protected MobSpawn GetSeedChar(BaseMapGenContext map, SpawnList <MobSpawn> specialMobs) { //the contents of that theme can be selected randomly, MobSpawn seedSpawn = null; //or, to add some sensibility, make it seeded from a random spawn that can already be found in the map if (map.TeamSpawns.CanPick) { TeamSpawner spawn = map.TeamSpawns.Pick(map.Rand); if (spawn != null) { List <MobSpawn> exampleList = spawn.ChooseSpawns(map.Rand); if (exampleList.Count > 0) { seedSpawn = exampleList[map.Rand.Next(exampleList.Count)]; } } } //choose the spawn, then seed the theme with it //the theme will take the aspects of the seedspawn and then be ready to spit out a list if (seedSpawn == null && specialMobs.CanPick) { seedSpawn = specialMobs.Pick(map.Rand); } return(seedSpawn); }
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); } } }
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(T map) { int chosenAmount = Amount.Pick(map.Rand); if (chosenAmount > 0 && Spawns.Count > 0 && PatternSpawns.Count > 0) { List <int> openRooms = new List <int>(); //get all places that traps are eligible for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++) { if (BaseRoomFilter.PassesAllFilters(map.RoomPlan.GetRoomPlan(ii), this.Filters)) { openRooms.Add(ii); } } for (int ii = 0; ii < chosenAmount; ii++) { // add traps if (openRooms.Count > 0) { int randIndex = map.Rand.Next(openRooms.Count); TrapPattern pattern = PatternSpawns.Pick(map.Rand); } } } }
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 ApplyFeature(IMobSpawnMap map, Character newChar) { if (MapStartOnly && map.Begun) { return; } newChar.EquippedItem = Items.Pick(map.Rand); }
public void SpawnListEmptyChoose() { // choose when empty var spawnList = new SpawnList <string>(); Mock <IRandom> testRand = new Mock <IRandom>(MockBehavior.Strict); Assert.That(spawnList.CanPick, Is.EqualTo(false)); Assert.Throws <InvalidOperationException>(() => { spawnList.Pick(testRand.Object); }); }
public override List <MapItem> GenerateItems(BaseMapGenContext map, SpawnList <MapItem> specialItems) { int itemCount = Amount.Pick(map.Rand); List <MapItem> spawners = new List <MapItem>(); SpawnList <MapItem> subList = new SpawnList <MapItem>(); if (UseSpecialItems) { for (int ii = 0; ii < specialItems.Count; ii++) { MapItem spawn = specialItems.GetSpawn(ii); if (!spawn.IsMoney) { ItemEntrySummary itemEntry = DataManager.Instance.DataIndices[DataManager.DataType.Item].Entries[spawn.Value] as ItemEntrySummary; if (itemEntry.UsageType == UseType) { subList.Add(spawn, specialItems.GetSpawnRate(ii)); } } } } if (UseMapItems) { foreach (string key in map.ItemSpawns.Spawns.GetKeys()) { SpawnList <InvItem> spawns = map.ItemSpawns.Spawns.GetSpawn(key); for (int ii = 0; ii < spawns.Count; ii++) { //TODO: spawn rate is somewhat distorted here InvItem spawn = spawns.GetSpawn(ii); ItemEntrySummary itemEntry = DataManager.Instance.DataIndices[DataManager.DataType.Item].Entries[spawn.ID] as ItemEntrySummary; if (itemEntry.UsageType == UseType) { subList.Add(new MapItem(spawn), spawns.GetSpawnRate(ii)); } } } } if (subList.Count == 0) { return(spawners); } for (int ii = 0; ii < itemCount; ii++) { spawners.Add(subList.Pick(map.Rand)); } return(spawners); }
public override List <MapItem> GenerateItems(BaseMapGenContext map, SpawnList <MapItem> specialItems) { int itemCount = Amount.Pick(map.Rand); List <MapItem> spawners = new List <MapItem>(); SpawnList <MapItem> subList = new SpawnList <MapItem>(); if (UseSpecialItems) { for (int ii = 0; ii < specialItems.Count; ii++) { MapItem spawn = specialItems.GetSpawn(ii); if (!spawn.IsMoney) { if (Range.Min <= spawn.Value && spawn.Value < Range.Max) { subList.Add(spawn, specialItems.GetSpawnRate(ii)); } } } } if (UseMapItems) { foreach (string key in map.ItemSpawns.Spawns.GetKeys()) { SpawnList <InvItem> spawns = map.ItemSpawns.Spawns.GetSpawn(key); for (int ii = 0; ii < spawns.Count; ii++) { //TODO: spawn rate is somewhat distorted here InvItem spawn = spawns.GetSpawn(ii); //ItemData data = DataManager.Instance.GetItem(spawn.ID); if (Range.Min <= spawn.ID && spawn.ID < Range.Max) { subList.Add(new MapItem(spawn), spawns.GetSpawnRate(ii)); } } } } if (subList.Count == 0) { return(spawners); } for (int ii = 0; ii < itemCount; ii++) { spawners.Add(subList.Pick(map.Rand)); } return(spawners); }
public override void ApplyFeature(IMobSpawnMap map, Character newChar) { StatusEffect status = Statuses.Pick(map.Rand).Clone();//Clone Use Case; convert to Instantiate? status.LoadFromData(); StatusData entry = (StatusData)status.GetData(); if (!entry.Targeted)//no targeted statuses allowed { //need to also add the additional status states newChar.StatusEffects.Add(status.ID, status); } }
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 List <TSpawnable> GetSpawns(TGenContext map) { List <TSpawnable> spawns = new List <TSpawnable>(); foreach (TSpawnable element in SpecificSpawns) { spawns.Add(element); } for (int ii = 0; ii < SpawnAmount; ii++) { spawns.Add(RandomSpawns.Pick(map.Rand)); } return(spawns); }
public override List <MapItem> GenerateItems(BaseMapGenContext map, SpawnList <MapItem> specialItems) { int itemCount = Amount.Pick(map.Rand); List <MapItem> spawners = new List <MapItem>(); for (int ii = 0; ii < itemCount; ii++) { if (specialItems.Count > 0 && map.Rand.Next(100) < SpecialRatio) { spawners.Add(specialItems.Pick(map.Rand)); } else if (map.ItemSpawns.CanPick) { spawners.Add(new MapItem(map.ItemSpawns.Pick(map.Rand))); } } return(spawners); }
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 List <MobSpawn> GenerateMobs(BaseMapGenContext map, SpawnList <MobSpawn> specialMobs) { int mobCount = Amount.Pick(map.Rand); List <MobSpawn> spawners = new List <MobSpawn>(); IEnumerable <int> species = GetSpecies(map, specialMobs); SpawnList <MobSpawn> subList = new SpawnList <MobSpawn>(); for (int ii = 0; ii < specialMobs.Count; ii++) { MobSpawn spawn = specialMobs.GetSpawn(ii); if (CheckIfAllowed(map, spawn, species)) { subList.Add(spawn, specialMobs.GetSpawnRate(ii)); } } for (int ii = 0; ii < map.TeamSpawns.Count; ii++) { SpawnList <MobSpawn> memberSpawns = map.TeamSpawns.GetSpawn(ii).GetPossibleSpawns(); for (int jj = 0; ii < memberSpawns.Count; jj++) { MobSpawn spawn = memberSpawns.GetSpawn(jj); if (CheckIfAllowed(map, spawn, species)) { subList.Add(spawn, memberSpawns.GetSpawnRate(jj)); } } } if (subList.Count > 0) { for (int ii = 0; ii < mobCount; ii++) { spawners.Add(subList.Pick(map.Rand)); } } return(spawners); }
public override List <MobSpawn> GenerateMobs(BaseMapGenContext map, SpawnList <MobSpawn> specialMobs) { int mobCount = Amount.Pick(map.Rand); List <MobSpawn> spawners = new List <MobSpawn>(); for (int ii = 0; ii < mobCount; ii++) { if (specialMobs.Count > 0 && map.Rand.Next(100) < SpecialRatio) { spawners.Add(specialMobs.Pick(map.Rand)); } else if (map.TeamSpawns.CanPick) { List <MobSpawn> exampleList = map.TeamSpawns.Pick(map.Rand).ChooseSpawns(map.Rand); if (exampleList.Count > 0) { spawners.Add(exampleList[map.Rand.Next(exampleList.Count)]); } } } return(spawners); }
public List <Character> RespawnMob() { List <Character> respawns = new List <Character>(); if (TeamSpawns.Count > 0) { bool[][] traversedGrid = new bool[Width][]; for (int xx = 0; xx < Width; xx++) { traversedGrid[xx] = new bool[Height]; } List <Loc> freeTiles = new List <Loc>(); Grid.FloodFill(new Rect(new Loc(), new Loc(Width, Height)), (Loc testLoc) => { if (traversedGrid[testLoc.X][testLoc.Y]) { return(true); } return(TileBlocked(testLoc)); }, (Loc testLoc) => { if (traversedGrid[testLoc.X][testLoc.Y]) { return(true); } return(TileBlocked(testLoc, true)); }, (Loc testLoc) => { traversedGrid[testLoc.X][testLoc.Y] = true; //must be walkable, not have a nonwalkable on at least 3 cardinal directions, not be within eyesight of any of the player characters foreach (Character character in ActiveTeam.Players) { if (character.IsInSightBounds(testLoc)) { return; } } foreach (Team team in MapTeams) { foreach (Character character in team.Players) { if (!character.Dead && character.CharLoc == testLoc) { return; } } } freeTiles.Add(testLoc); }, EntryPoints[0].Loc); if (freeTiles.Count > 0) { for (int ii = 0; ii < 10; ii++) { Team newTeam = TeamSpawns.Pick(Rand).Spawn(this); if (newTeam == null) { continue; } Loc trialLoc = freeTiles[Rand.Next(freeTiles.Count)]; //find a way to place all members- needs to fit all of them in, or else fail the spawn Grid.LocTest checkOpen = (Loc testLoc) => { if (TileBlocked(testLoc)) { return(false); } Character locChar = GetCharAtLoc(testLoc); if (locChar != null) { return(false); } return(true); }; Grid.LocTest checkBlock = (Loc testLoc) => { return(TileBlocked(testLoc, true)); }; Grid.LocTest checkDiagBlock = (Loc testLoc) => { return(TileBlocked(testLoc, true, true)); }; List <Loc> resultLocs = new List <Loc>(); foreach (Loc loc in Grid.FindClosestConnectedTiles(new Loc(), new Loc(Width, Height), checkOpen, checkBlock, checkDiagBlock, trialLoc, newTeam.Players.Count)) { resultLocs.Add(loc); } if (resultLocs.Count >= newTeam.Players.Count) { for (int jj = 0; jj < newTeam.Players.Count; jj++) { newTeam.Players[jj].CharLoc = resultLocs[jj]; } MapTeams.Add(newTeam); foreach (Character member in newTeam.Players) { member.RefreshTraits(); respawns.Add(member); } break; } } } } return(respawns); }
protected LocRay4?PlaceRoom(T map, List <LocRay4> rays, EffectTile sealingTile, List <Loc> freeTiles) { Grid.LocTest checkBlockForPlace = (Loc testLoc) => { if (!Collision.InBounds(map.Width, map.Height, testLoc)) { return(false); } return(!map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) && !map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.UnbreakableTerrain)); }; //try X times to dig a passage for (int ii = 0; ii < 500 && rays.Count > 0; ii++) { int rayIndex = map.Rand.Next(rays.Count); LocRay4 ray = rays[rayIndex]; rays.RemoveAt(rayIndex); Loc rayDirLoc = ray.Dir.GetLoc(); Axis4 axis = ray.Dir.ToAxis(); Axis4 orth = axis == Axis4.Horiz ? Axis4.Vert : Axis4.Horiz; int minLength = Math.Max(1, HallLength.Min); Rect hallBound = new Rect(ray.Loc + DirExt.AddAngles(ray.Dir, Dir4.Left).GetLoc(), new Loc(1)); hallBound = Rect.IncludeLoc(hallBound, ray.Loc + rayDirLoc * (minLength - 1) + DirExt.AddAngles(ray.Dir, Dir4.Right).GetLoc()); //make sure the MIN hall can tunnel unimpeded if (!CanPlaceRect(map, hallBound, checkBlockForPlace)) { continue; } for (int jj = 0; jj < 100; jj++) { //plan the room RoomGen <T> plan = GenericRooms.Pick(map.Rand).Copy(); Loc size = plan.ProposeSize(map.Rand); plan.PrepareSize(map.Rand, size); //attempt to place the bounds somewhere, anywhere, within the limitations that the room itself provides List <int> candidateOpenings = new List <int>(); int planLength = plan.GetBorderLength(ray.Dir.Reverse()); for (int kk = 0; kk < planLength; kk++) { if (plan.GetFulfillableBorder(ray.Dir.Reverse(), kk)) { candidateOpenings.Add(kk); } } //as well as continue extending the hall until we hit a walkable. int tunnelLen = Math.Max(1, HallLength.Pick(map.Rand)); Loc roomLoc = ray.Loc + rayDirLoc * tunnelLen; int perpOffset = candidateOpenings[map.Rand.Next(candidateOpenings.Count)]; roomLoc += orth.CreateLoc(-perpOffset, 0); if (rayDirLoc.GetScalar(axis) < 0)//move back the top-left of the entrance { roomLoc += rayDirLoc * (size.GetScalar(axis) - 1); } Rect roomTestBound = new Rect(roomLoc, size); roomTestBound.Inflate(1, 1); //make a rect for the rest of the hall Rect hallExtBound = new Rect(ray.Loc + rayDirLoc * minLength + DirExt.AddAngles(ray.Dir, Dir4.Left).GetLoc(), new Loc(1)); hallExtBound = Rect.IncludeLoc(hallBound, ray.Loc + rayDirLoc * (tunnelLen - 1) + DirExt.AddAngles(ray.Dir, Dir4.Right).GetLoc()); //now that we've chosen our position, let's test it if (!CanPlaceRect(map, roomTestBound, checkBlockForPlace) || !CanPlaceRect(map, hallExtBound, checkBlockForPlace)) // also test that the CHOSEN hallway can be properly sealed { continue; //invalid location, try another place } else { plan.SetLoc(roomLoc); plan.ReceiveBorderRange(new IntRange(perpOffset, perpOffset + 1) + roomLoc.GetScalar(orth), ray.Dir.Reverse()); //draw the room plan.DrawOnMap(map); //surround the room with bounds for (int xx = roomTestBound.X; xx < roomTestBound.Right; xx++) { map.Tiles[xx][roomTestBound.Y] = (Tile)map.UnbreakableTerrain.Copy(); map.Tiles[xx][roomTestBound.End.Y - 1] = (Tile)map.UnbreakableTerrain.Copy(); } for (int yy = roomTestBound.Y + 1; yy < roomTestBound.Bottom - 1; yy++) { map.Tiles[roomTestBound.X][yy] = (Tile)map.UnbreakableTerrain.Copy(); map.Tiles[roomTestBound.End.X - 1][yy] = (Tile)map.UnbreakableTerrain.Copy(); } //spawn tiles, items, foes List <Loc> addedTiles = ((IPlaceableGenContext <MapItem>)map).GetFreeTiles(plan.Draw); freeTiles.AddRange(addedTiles); //tunnel to the room Loc loc = ray.Loc; for (int tt = 0; tt < tunnelLen; tt++) { //make walkable map.Tiles[loc.X][loc.Y] = (Tile)map.RoomTerrain.Copy(); //make left side unbreakable Loc lLoc = loc + DirExt.AddAngles(ray.Dir, Dir4.Left).GetLoc(); map.Tiles[lLoc.X][lLoc.Y] = (Tile)map.UnbreakableTerrain.Copy(); //make right side unbreakable Loc rLoc = loc + DirExt.AddAngles(ray.Dir, Dir4.Right).GetLoc(); map.Tiles[rLoc.X][rLoc.Y] = (Tile)map.UnbreakableTerrain.Copy(); loc += rayDirLoc; } //finally, seal with a locked door map.Tiles[ray.Loc.X][ray.Loc.Y] = (Tile)map.UnbreakableTerrain.Copy(); EffectTile newEffect = new EffectTile(sealingTile, ray.Loc); ((IPlaceableGenContext <EffectTile>)map).PlaceItem(ray.Loc, newEffect); return(ray); } } } //DiagManager.Instance.LogInfo("Couldn't place sealed detour!"); return(null); }
public override void DrawOnMap(T map) { Loc isleSize = new Loc(1); while (isleSize.X * isleSize.Y < ItemAmount) { if (isleSize.X > isleSize.Y) { isleSize.Y++; } else { isleSize.X++; } } //require at least a rectangle that can contain a ring of land around the ring of water if (isleSize.X + 4 > Draw.Size.X || isleSize.Y + 4 > Draw.Size.Y) { DrawMapDefault(map); return; } Loc ringSize = isleSize + new Loc(2); //size of room should be between size of cave + 2 and max for (int x = 0; x < Draw.Size.X; x++) { for (int y = 0; y < Draw.Size.Y; y++) { map.SetTile(new Loc(Draw.X + x, Draw.Y + y), map.RoomTerrain.Copy()); } } List <Loc> freeTiles = new List <Loc>(); Loc blockStart = new Loc(Draw.X + 1 + map.Rand.Next(Draw.Size.X - ringSize.X - 1), Draw.Y + 1 + map.Rand.Next(Draw.Size.Y - ringSize.Y - 1)); for (int x = 0; x < ringSize.X; x++) { for (int y = 0; y < ringSize.Y; y++) { if (x == 0 || x == ringSize.X - 1 || y == 0 || y == ringSize.Y - 1) { map.SetTile(new Loc(blockStart.X + x, blockStart.Y + y), WaterTerrain.Copy()); } else { freeTiles.Add(new Loc(blockStart.X + x, blockStart.Y + y)); } } } if (Treasures.Count > 0) { for (int ii = 0; ii < ItemAmount; ii++) { MapItem item = new MapItem(Treasures.Pick(map.Rand)); int randIndex = map.Rand.Next(freeTiles.Count); map.PlaceItem(freeTiles[randIndex], item); freeTiles.RemoveAt(randIndex); } } //hall restrictions SetRoomBorders(map); }
public override List <MobSpawn> ChooseSpawns(IRandom rand) { List <MobSpawn> chosenSpawns = new List <MobSpawn>(); int teamSize = TeamSizes.Pick(rand); bool selectedLeader = false; bool selectedSupport = false; //pick first team member List <SpawnList <MobSpawn> > eligibleSpawns = new List <SpawnList <MobSpawn> > { NormalSpawns, LeaderSpawns, }; if (teamSize > 1) { eligibleSpawns.Add(SupportSpawns); } else { eligibleSpawns.Add(LonerSpawns); } SpawnList <MobSpawn> chosenList = chooseSpawnList(eligibleSpawns, rand); if (chosenList == LeaderSpawns) { selectedLeader = true; } else if (chosenList == SupportSpawns) { selectedSupport = true; } chosenSpawns.Add(chosenList.Pick(rand)); //pick remaining team members for (int ii = 1; ii < teamSize; ii++) { eligibleSpawns = new List <SpawnList <MobSpawn> >(); eligibleSpawns.Add(NormalSpawns); if (!selectedLeader) { eligibleSpawns.Add(LeaderSpawns); } if (!selectedSupport) { eligibleSpawns.Add(SupportSpawns); } chosenList = chooseSpawnList(eligibleSpawns, rand); if (chosenList == LeaderSpawns) { selectedLeader = true; } else if (chosenList == SupportSpawns) { selectedSupport = true; } chosenSpawns.Add(chosenList.Pick(rand)); } return(chosenSpawns); }
public override void ApplyToPath(IRandom rand, GridPlan floorPlan) { for (int xx = 0; xx < floorPlan.GridWidth - 1; xx++) { for (int yy = 0; yy < floorPlan.GridHeight - 1; yy++) { //check for room presence in all rooms (must be SINGLE and immutable) if (!roomViable(floorPlan, xx, yy)) { continue; } if (!roomViable(floorPlan, xx, yy + 1)) { continue; } if (!roomViable(floorPlan, xx + 1, yy)) { continue; } if (!roomViable(floorPlan, xx + 1, yy + 1)) { continue; } //check for hall connectivity in all constituent halls if (floorPlan.GetHall(new LocRay4(xx, yy, Dir4.Down)) == null) { continue; } if (floorPlan.GetHall(new LocRay4(xx, yy, Dir4.Right)) == null) { continue; } if (floorPlan.GetHall(new LocRay4(xx + 1, yy, Dir4.Down)) == null) { continue; } if (floorPlan.GetHall(new LocRay4(xx, yy + 1, Dir4.Right)) == null) { continue; } if (rand.Next(100) < CombineChance) { //erase the constituent rooms floorPlan.EraseRoom(new Loc(xx, yy)); floorPlan.EraseRoom(new Loc(xx + 1, yy)); floorPlan.EraseRoom(new Loc(xx, yy + 1)); floorPlan.EraseRoom(new Loc(xx + 1, yy + 1)); //erase the constituent halls floorPlan.SetHall(new LocRay4(xx, yy, Dir4.Down), null, new ComponentCollection()); floorPlan.SetHall(new LocRay4(xx, yy, Dir4.Right), null, new ComponentCollection()); floorPlan.SetHall(new LocRay4(xx + 1, yy, Dir4.Down), null, new ComponentCollection()); floorPlan.SetHall(new LocRay4(xx, yy + 1, Dir4.Right), null, new ComponentCollection()); //place the room RoomGen <T> gen = GiantRooms.Pick(rand); floorPlan.AddRoom(new Rect(xx, yy, 2, 2), gen.Copy(), this.RoomComponents.Clone(), false); } } } }
public override void Apply(T map) { if (Spawns.Count > 0) { List <Loc> freeTiles = new List <Loc>(); //get all places that traps are eligible for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++) { IRoomGen room = map.RoomPlan.GetRoom(ii); List <Loc> tiles = ((IPlaceableGenContext <EffectTile>)map).GetFreeTiles(room.Draw); freeTiles.AddRange(tiles); } // add tile if (freeTiles.Count > 0) { int randIndex = ((IGenContext)map).Rand.Next(freeTiles.Count); Loc loc = freeTiles[randIndex]; EffectTile spawnedTrap = Spawns.Pick(((IGenContext)map).Rand); map.PlaceItem(loc, spawnedTrap); freeTiles.RemoveAt(randIndex); if (GuardSpawns.Count > 0) { for (int ii = 0; ii < 10; ii++) { Team newTeam = GuardSpawns.Pick(((IGenContext)map).Rand).Spawn(map); if (newTeam == null) { continue; } //spawn guards Grid.LocTest checkSpawnOpen = (Loc testLoc) => { return(((IGroupPlaceableGenContext <Team>)map).CanPlaceItem(testLoc)); }; Grid.LocTest checkSpawnBlock = (Loc testLoc) => { return(map.TileBlocked(testLoc)); }; Grid.LocTest checkDiagSpawnBlock = (Loc testLoc) => { return(map.TileBlocked(testLoc, true)); }; List <Loc> resultLocs = new List <Loc>(); foreach (Loc resultLoc in Grid.FindClosestConnectedTiles(new Loc(), new Loc(map.Width, map.Height), checkSpawnOpen, checkSpawnBlock, checkDiagSpawnBlock, loc, newTeam.MemberGuestCount)) { resultLocs.Add(resultLoc); } if (resultLocs.Count >= newTeam.MemberGuestCount) { Loc[] locs = new Loc[newTeam.MemberGuestCount]; for (int jj = 0; jj < locs.Length; jj++) { locs[jj] = resultLocs[jj]; } map.PlaceItems(newTeam, locs); break; } } } } } }
public override void ApplyToPath(IRandom rand, GridPlan floorPlan) { int chosenBigRooms = RoomAmount.Pick(rand); for (int ii = 0; ii < chosenBigRooms; ii++) { for (int jj = 0; jj < 20; jj++) { LargeRoom <T> chosenRoom = GiantRooms.Pick(rand); Rect destRect = new Rect(new Loc(rand.Next(floorPlan.GridWidth - chosenRoom.Size.X), rand.Next(floorPlan.GridHeight - chosenRoom.Size.Y)), chosenRoom.Size); if (spaceViable(floorPlan, destRect)) { List <LocRay4> raysOut = new List <LocRay4>(); for (int xx = destRect.Start.X; xx < destRect.End.X; xx++) { LocRay4 locUp = new LocRay4(xx, destRect.Start.Y, Dir4.Up); if (destRect.Start.Y > 0 && floorPlan.GetHall(locUp) != null) { raysOut.Add(locUp); } LocRay4 locDown = new LocRay4(xx, destRect.Start.Y + chosenRoom.Size.Y - 1, Dir4.Down); if (destRect.Start.Y < floorPlan.GridHeight - 1 && floorPlan.GetHall(locDown) != null) { raysOut.Add(locDown); } } for (int yy = destRect.Start.Y; yy < destRect.End.Y; yy++) { LocRay4 locLeft = new LocRay4(destRect.Start.X, yy, Dir4.Left); if (destRect.Start.X > 0 && floorPlan.GetHall(locLeft) != null) { raysOut.Add(locLeft); } LocRay4 locRight = new LocRay4(destRect.Start.X + chosenRoom.Size.X - 1, yy, Dir4.Right); if (destRect.Start.X < floorPlan.GridWidth - 1 && floorPlan.GetHall(locRight) != null) { raysOut.Add(locRight); } } List <List <LocRay4> > exitSets = findHallSets(floorPlan, destRect, raysOut); //exits: no more than allowed if (exitSets.Count > chosenRoom.AllowedEntrances) { continue; } //this block tallies all sets that can be joined to the big room //it also chooses which ones to keep by randomly removing them from the raysOut list int setsTaken = 0; foreach (List <LocRay4> set in exitSets) { List <LocRay4> possibleRays = new List <LocRay4>(); foreach (LocRay4 ray in set) { int scalar = (ray.Loc - destRect.Start).GetScalar(ray.Dir.ToAxis().Orth()); if (chosenRoom.OpenBorders[(int)ray.Dir][scalar]) { possibleRays.Add(ray); } } if (possibleRays.Count > 0) { LocRay4 locRay = possibleRays[rand.Next(possibleRays.Count)]; raysOut.Remove(locRay); setsTaken++; } else { break; } } if (setsTaken == exitSets.Count) { for (int xx = 0; xx < chosenRoom.Size.X; xx++) { for (int yy = 0; yy < chosenRoom.Size.Y; yy++) { //erase rooms in vicinity Loc loc = new Loc(xx + destRect.Start.X, yy + destRect.Start.Y); //erase halls in vicinity floorPlan.EraseRoom(loc); if (xx > 0) { floorPlan.SetHall(new LocRay4(loc, Dir4.Left), null, new ComponentCollection()); } if (yy > 0) { floorPlan.SetHall(new LocRay4(loc, Dir4.Up), null, new ComponentCollection()); } } } //remove all halls still in the list foreach (LocRay4 rayOut in raysOut) { floorPlan.SetHall(rayOut, null, new ComponentCollection()); } //add room floorPlan.AddRoom(destRect, chosenRoom.Gen, new ComponentCollection()); break; } } } } }
public override List <MobSpawn> ChooseSpawns(IRandom rand) { List <MobSpawn> chosenSpawns = new List <MobSpawn>(); if (!TeamSizes.CanPick) { return(chosenSpawns); } int teamSize = TeamSizes.Pick(rand); bool selectedLeader = false; bool selectedNonSupport = false; //pick first team member SpawnList <TeamMemberSpawn> eligibleSpawns = new SpawnList <TeamMemberSpawn>(); for (int ii = 0; ii < Spawns.Count; ii++) { TeamMemberSpawn spawn = Spawns.GetSpawn(ii); bool add = false; switch (spawn.Role) { case TeamMemberSpawn.MemberRole.Normal: case TeamMemberSpawn.MemberRole.Leader: add = true; break; case TeamMemberSpawn.MemberRole.Support: add = (teamSize > 1); break; case TeamMemberSpawn.MemberRole.Loner: add = (teamSize == 1); break; } if (add) { eligibleSpawns.Add(spawn, Spawns.GetSpawnRate(ii)); } } if (!eligibleSpawns.CanPick) { return(chosenSpawns); } TeamMemberSpawn chosenSpawn = eligibleSpawns.Pick(rand); if (chosenSpawn.Role == TeamMemberSpawn.MemberRole.Leader) { selectedLeader = true; } if (chosenSpawn.Role != TeamMemberSpawn.MemberRole.Support) { selectedNonSupport = true; } chosenSpawns.Add(chosenSpawn.Spawn); //pick remaining team members for (int jj = 1; jj < teamSize; jj++) { eligibleSpawns.Clear(); for (int ii = 0; ii < Spawns.Count; ii++) { TeamMemberSpawn spawn = Spawns.GetSpawn(ii); bool add = false; switch (spawn.Role) { case TeamMemberSpawn.MemberRole.Normal: add = true; break; case TeamMemberSpawn.MemberRole.Leader: add = !selectedLeader; break; case TeamMemberSpawn.MemberRole.Support: add = selectedNonSupport; break; } if (add) { eligibleSpawns.Add(spawn, Spawns.GetSpawnRate(ii)); } } if (!eligibleSpawns.CanPick) { return(chosenSpawns); } chosenSpawn = eligibleSpawns.Pick(rand); if (chosenSpawn.Role == TeamMemberSpawn.MemberRole.Leader) { selectedLeader = true; } if (chosenSpawn.Role != TeamMemberSpawn.MemberRole.Support) { selectedNonSupport = true; } chosenSpawns.Add(chosenSpawn.Spawn); } return(chosenSpawns); }
public override void DrawOnMap(T map) { Loc caveSize = ProposeSize(((IGenContext)map).Rand); if (caveSize.X != Draw.Width || caveSize.Y != Draw.Height) { DrawMapDefault(map); return; } //place room in a space that fits List <Loc> freeTiles = new List <Loc>(); Loc caveStart = Draw.Start + new Loc(2, 1); for (int x = 0; x < caveSize.X - 4; x++) { for (int y = 0; y < caveSize.Y - 4; y++) { map.SetTile(new Loc(caveStart.X + x, caveStart.Y + y), map.RoomTerrain.Copy()); freeTiles.Add(new Loc(caveStart.X + x, caveStart.Y + y)); } } //place tile treasures List <EffectTile> tileTreasures = TileTreasures.GetSpawns(map); for (int ii = 0; ii < tileTreasures.Count; ii++) { int randIndex = ((IGenContext)map).Rand.Next(freeTiles.Count); EffectTile tile = new EffectTile(tileTreasures[ii]); map.PlaceItem(freeTiles[randIndex], tile); freeTiles.RemoveAt(randIndex); } //place item treasures List <MapItem> treasures = Treasures.GetSpawns(map); for (int ii = 0; ii < treasures.Count; ii++) { int randIndex = ((IGenContext)map).Rand.Next(freeTiles.Count); MapItem item = treasures[ii]; map.PlaceItem(freeTiles[randIndex], item); freeTiles.RemoveAt(randIndex); } //open the passage to the treasure room Loc tunnel = new Loc(caveStart.X + (caveSize.X - 4) / 2, caveStart.Y + caveSize.Y - 4); map.SetTile(tunnel, map.RoomTerrain.Copy()); //dig the room into the treasure room for (int xx = 0; xx < 3; xx++) { for (int yy = 0; yy < 2; yy++) { map.SetTile(new Loc(tunnel.X - 1 + xx, tunnel.Y + 1 + yy), map.RoomTerrain.Copy()); } } //place monsters and items MonsterTeam team = new MonsterTeam(); Character newChar = GuardTypes.Pick(((IGenContext)map).Rand).Spawn(team, map); map.PlaceItems(new TeamSpawn(team, false), new Loc[1] { tunnel }); //dig tunnels within this room to hook up to the incoming demands foreach (Dir4 dir in DirExt.VALID_DIR4) { if (dir == Dir4.Up) {//if approached from the top, it must be either left or right. Dig to that side and then dig up. List <IntRange> upReq = RoomSideReqs[dir]; bool left = false; bool right = false; for (int ii = 0; ii < upReq.Count; ii++) { bool hasLeft = upReq[ii].Contains(Draw.Start.X) && BorderToFulfill[Dir4.Up][0]; bool hasRight = upReq[ii].Contains(Draw.End.X - 1) && BorderToFulfill[Dir4.Up][Draw.Width - 1]; if (hasLeft && hasRight) { if (((IGenContext)map).Rand.Next(2) == 0) { left = true; } else { right = true; } } else { left |= hasLeft; right |= hasRight; } } if (left) { DigAtBorder(map, Dir4.Left, Draw.End.Y - 1); DigAtBorder(map, Dir4.Up, Draw.Start.X); } if (right) { DigAtBorder(map, Dir4.Right, Draw.End.Y - 1); DigAtBorder(map, Dir4.Up, Draw.End.X - 1); } } else if (dir == Dir4.Down) {//if approached from bottom, do nothing; we already fulfill every possibility } else {//if approached from the sides, dig at the bottommost Y of the room, because that was the only tile allowed. if (RoomSideReqs[dir].Count > 0) { DigAtBorder(map, dir, Draw.End.Y - 1); } } } for (int x = 0; x < Draw.Width; x++) { for (int y = 0; y < Draw.Height - 1; y++) { Loc checkLoc = new Loc(Draw.X + x, Draw.Y + y); if (!map.GetTile(checkLoc).TileEquivalent(map.RoomTerrain)) { map.SetTile(checkLoc, map.UnbreakableTerrain.Copy()); } } } SetRoomBorders(map); }
public override void ApplyToPath(IRandom rand, GridPlan floorPlan) { int gapLength = Vertical ? floorPlan.GridHeight : floorPlan.GridWidth; int sideLength = Vertical ? floorPlan.GridWidth : floorPlan.GridHeight; if (gapLength < 3 || sideLength < 2) { CreateErrorPath(rand, floorPlan); return; } //add the body int chosenTier = FromCorners ? (rand.Next(2) * gapLength - 1) : rand.Next(1, gapLength - 1); RoomGen <T> roomGen = GiantHallGen.Pick(rand); if (roomGen == null) { roomGen = GenericRooms.Pick(rand); } floorPlan.AddRoom(new Rect(Vertical ? 0 : chosenTier, Vertical ? chosenTier : 0, Vertical ? sideLength : 1, Vertical ? 1 : sideLength), roomGen, this.LargeRoomComponents.Clone()); GenContextDebug.DebugProgress("Center Room"); //add the legs for (int ii = 0; ii < sideLength; ii++) { if (chosenTier > 0) { if (rand.Next(100) < LegPercent) { int roomTier = rand.Next(0, chosenTier); floorPlan.AddRoom(new Loc(Vertical ? ii : roomTier, Vertical ? roomTier : ii), GenericRooms.Pick(rand), this.RoomComponents.Clone()); for (int jj = roomTier; jj < chosenTier; jj++) { SafeAddHall(new LocRay4(new Loc(Vertical ? ii : jj, Vertical ? jj : ii), Vertical ? Dir4.Down : Dir4.Right), floorPlan, GenericHalls.Pick(rand), GetDefaultGen(), this.RoomComponents, this.HallComponents, true); } GenContextDebug.DebugProgress("Add Leg"); int hasRoom = -1; for (int jj = ii - 1; jj >= 0; jj--) { if (floorPlan.GetRoomPlan(new Loc(Vertical ? jj : roomTier, Vertical ? roomTier : jj)) != null) { hasRoom = jj; break; } } if (ii > 0 && hasRoom > -1) { if (rand.Next(100) < ConnectPercent) { for (int jj = ii; jj > hasRoom; jj--) { SafeAddHall(new LocRay4(new Loc(Vertical ? jj : roomTier, Vertical ? roomTier : jj), Vertical ? Dir4.Left : Dir4.Up), floorPlan, GenericHalls.Pick(rand), GetDefaultGen(), this.RoomComponents, this.HallComponents, true); GenContextDebug.DebugProgress("Connect Leg"); } } } } } if (chosenTier < gapLength - 1) { if (rand.Next(100) < LegPercent) { int roomTier = rand.Next(chosenTier + 1, gapLength); floorPlan.AddRoom(new Loc(Vertical ? ii : roomTier, Vertical ? roomTier : ii), GenericRooms.Pick(rand), this.RoomComponents.Clone()); for (int jj = chosenTier; jj < roomTier; jj++) { SafeAddHall(new LocRay4(new Loc(Vertical ? ii : jj, Vertical ? jj : ii), Vertical ? Dir4.Down : Dir4.Right), floorPlan, GenericHalls.Pick(rand), GetDefaultGen(), this.RoomComponents, this.HallComponents, true); } GenContextDebug.DebugProgress("Add Leg"); int hasRoom = -1; for (int jj = ii - 1; jj >= 0; jj--) { if (floorPlan.GetRoomPlan(new Loc(Vertical ? jj : roomTier, Vertical ? roomTier : jj)) != null) { hasRoom = jj; break; } } if (ii > 0 && hasRoom > -1) { if (rand.Next(100) < ConnectPercent) { for (int jj = ii; jj > hasRoom; jj--) { SafeAddHall(new LocRay4(new Loc(Vertical ? jj : roomTier, Vertical ? roomTier : jj), Vertical ? Dir4.Left : Dir4.Up), floorPlan, GenericHalls.Pick(rand), GetDefaultGen(), this.RoomComponents, this.HallComponents, true); GenContextDebug.DebugProgress("Connect Leg"); } } } } } } }