Exemple #1
0
        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);
                    }
                }
            }
        }
Exemple #2
0
        public override void Apply(T map)
        {
            //Iterate every room/hall and coat the ones filtered
            List <RoomHallIndex>       spawningRooms = new List <RoomHallIndex>();
            Dictionary <Loc, SealType> sealList      = new Dictionary <Loc, SealType>();

            for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
            {
                if (!BaseRoomFilter.PassesAllFilters(map.RoomPlan.GetRoomPlan(ii), this.Filters))
                {
                    continue;
                }
                spawningRooms.Add(new RoomHallIndex(ii, false));
            }

            for (int ii = 0; ii < map.RoomPlan.HallCount; ii++)
            {
                if (!BaseRoomFilter.PassesAllFilters(map.RoomPlan.GetHallPlan(ii), this.Filters))
                {
                    continue;
                }
                spawningRooms.Add(new RoomHallIndex(ii, true));
            }

            if (spawningRooms.Count == 0)
            {
                return;
            }

            for (int ii = 0; ii < spawningRooms.Count; ii++)
            {
                IFloorRoomPlan plan = map.RoomPlan.GetRoomHall(spawningRooms[ii]);

                //seal the sides and note edge cases
                for (int xx = plan.RoomGen.Draw.X + 1; xx < plan.RoomGen.Draw.End.X - 1; xx++)
                {
                    sealBorderRay(map, sealList, plan, new LocRay8(xx, plan.RoomGen.Draw.Y, Dir8.Up), Dir8.Left, Dir8.Right);
                    sealBorderRay(map, sealList, plan, new LocRay8(xx, plan.RoomGen.Draw.End.Y - 1, Dir8.Down), Dir8.Left, Dir8.Right);
                }

                for (int yy = plan.RoomGen.Draw.Y + 1; yy < plan.RoomGen.Draw.End.Y - 1; yy++)
                {
                    sealBorderRay(map, sealList, plan, new LocRay8(plan.RoomGen.Draw.X, yy, Dir8.Left), Dir8.Up, Dir8.Down);
                    sealBorderRay(map, sealList, plan, new LocRay8(plan.RoomGen.Draw.End.X - 1, yy, Dir8.Right), Dir8.Up, Dir8.Down);
                }

                //seal edge cases
                sealCornerRay(map, sealList, plan, new LocRay8(plan.RoomGen.Draw.X, plan.RoomGen.Draw.Y, Dir8.UpLeft));
                sealCornerRay(map, sealList, plan, new LocRay8(plan.RoomGen.Draw.End.X - 1, plan.RoomGen.Draw.Y, Dir8.UpRight));
                sealCornerRay(map, sealList, plan, new LocRay8(plan.RoomGen.Draw.X, plan.RoomGen.Draw.End.Y - 1, Dir8.DownLeft));
                sealCornerRay(map, sealList, plan, new LocRay8(plan.RoomGen.Draw.End.X - 1, plan.RoomGen.Draw.End.Y - 1, Dir8.DownRight));
            }

            PlaceBorders(map, sealList);
        }
Exemple #3
0
 public override void ApplyToPath(IRandom rand, GridPlan floorPlan)
 {
     for (int ii = 0; ii < floorPlan.RoomCount; ii++)
     {
         GridRoomPlan plan = floorPlan.GetRoomPlan(ii);
         if (!BaseRoomFilter.PassesAllFilters(plan, this.Filters))
         {
             continue;
         }
         if (plan.RoomGen is IPermissiveRoomGen)
         {
             plan.PreferHall = true;
         }
     }
 }
        private bool roomViable(GridPlan floorPlan, int xx, int yy)
        {
            //must be PRESENT, SINGLE and immutable
            GridRoomPlan plan = floorPlan.GetRoomPlan(new Loc(xx, yy));

            if (plan == null)
            {
                return(false);
            }
            if (plan.Bounds.Area > 1)
            {
                return(false);
            }
            if (!BaseRoomFilter.PassesAllFilters(plan, this.Filters))
            {
                return(false);
            }

            return(true);
        }
Exemple #5
0
 private bool spaceViable(GridPlan floorPlan, Rect rect)
 {
     //all tiles must be ABSENT, or SINGLE AND not immutable
     for (int xx = rect.Start.X; xx < rect.End.X; xx++)
     {
         for (int yy = rect.Start.Y; yy < rect.End.Y; yy++)
         {
             GridRoomPlan plan = floorPlan.GetRoomPlan(new Loc(xx, yy));
             if (plan == null)
             {
                 continue;
             }
             if (plan.Bounds.Area > 1)
             {
                 return(false);
             }
             if (!BaseRoomFilter.PassesAllFilters(plan, this.Filters))
             {
                 return(false);
             }
         }
     }
     return(true);
 }
Exemple #6
0
        public virtual FloorPathBranch <T> .ListPathBranchExpansion?ChooseRoomExpansion(IRandom rand, FloorPlan floorPlan)
        {
            List <RoomHallIndex> availableExpansions = new List <RoomHallIndex>();

            for (int ii = 0; ii < floorPlan.RoomCount; ii++)
            {
                if (!BaseRoomFilter.PassesAllFilters(floorPlan.GetRoomPlan(ii), this.Filters))
                {
                    continue;
                }
                availableExpansions.Add(new RoomHallIndex(ii, false));
            }

            for (int ii = 0; ii < floorPlan.HallCount; ii++)
            {
                if (!BaseRoomFilter.PassesAllFilters(floorPlan.GetHallPlan(ii), this.Filters))
                {
                    continue;
                }
                availableExpansions.Add(new RoomHallIndex(ii, true));
            }

            return(FloorPathBranch <T> .ChooseRoomExpansion(this.PrepareBossRoom, 100, rand, floorPlan, availableExpansions));
        }
Exemple #7
0
        public override void Apply(T map)
        {
            int chosenAmount = Amount.Pick(map.Rand);

            if (chosenAmount > 0)
            {
                SpawnList <int> spawningRooms = new SpawnList <int>();

                //get all places that spawnings are eligible
                for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
                {
                    IRoomGen room = map.RoomPlan.GetRoom(ii);

                    if (!BaseRoomFilter.PassesAllFilters(map.RoomPlan.GetRoomPlan(ii), this.Filters))
                    {
                        continue;
                    }

                    spawningRooms.Add(ii, 10000);
                }

                int trials = 10 * chosenAmount;
                for (int ii = 0; ii < trials && chosenAmount > 0; ii++)
                {
                    if (spawningRooms.SpawnTotal == 0)//check to make sure there's still spawn choices left
                    {
                        break;
                    }
                    int  spawnIndex = spawningRooms.PickIndex(map.Rand);
                    int  roomNum    = spawningRooms.GetSpawn(spawnIndex);
                    Team newTeam    = Spawn.GetSpawn(map);
                    if (newTeam == null)
                    {
                        continue;
                    }

                    List <Loc> freeTiles = Grid.FindTilesInBox(map.RoomPlan.GetRoom(roomNum).Draw.Start, map.RoomPlan.GetRoom(roomNum).Draw.Size,
                                                               (Loc testLoc) =>
                    {
                        return(((IGroupPlaceableGenContext <Team>)map).CanPlaceItem(testLoc));
                    });

                    //this actually places the members of the team in random scattered locations, leaving them to group together via wandering
                    if (freeTiles.Count >= newTeam.Players.Count)
                    {
                        Loc[] locs = new Loc[newTeam.Players.Count];
                        for (int jj = 0; jj < newTeam.Players.Count; jj++)
                        {
                            int randIndex = map.Rand.Next(freeTiles.Count);
                            locs[jj] = freeTiles[randIndex];
                            freeTiles.RemoveAt(randIndex);
                        }
                        ((IGroupPlaceableGenContext <Team>)map).PlaceItems(newTeam, locs);
                        chosenAmount--;
                    }

                    if (freeTiles.Count == 0)//if spawningRooms is now impossible there, remove the room entirely
                    {
                        spawningRooms.RemoveAt(spawnIndex);
                    }
                    else //otherwise decrease spawn rate for room
                    {
                        spawningRooms.SetSpawnRate(spawnIndex, Math.Max(spawningRooms.GetSpawnRate(spawnIndex) * ClumpFactor / 100, 1));
                    }
                }
            }
        }
Exemple #8
0
        /// <summary>
        /// chooses and caegorizes the tile to be sealed
        /// </summary>
        /// <param name="map"></param>
        /// <param name="sealList"></param>
        /// <param name="plan"></param>
        /// <param name="loc"></param>
        /// <param name="dir"></param>
        /// <returns>Whether it affected the tile outwards or not</returns>
        private bool sealBorderRay(T map, Dictionary <Loc, SealType> sealList, IFloorRoomPlan plan, LocRay8 locRay, Dir8 side1, Dir8 side2)
        {
            Loc forthLoc = locRay.Loc + locRay.Dir.GetLoc();

            bool hasAdjacent  = false;
            bool hasCondition = false;

            for (int ii = 0; ii < plan.Adjacents.Count; ii++)
            {
                IFloorRoomPlan adjacentPlan = map.RoomPlan.GetRoomHall(plan.Adjacents[ii]);
                if (Collision.InBounds(adjacentPlan.RoomGen.Draw, forthLoc))
                {
                    hasAdjacent = true;
                    if (BaseRoomFilter.PassesAllFilters(adjacentPlan, this.Filters))
                    {
                        hasCondition = true;
                        break;
                    }
                }
            }

            if (!hasAdjacent)
            {
                //in the case where the extending tile is within no adjacents
                //  all normal walls shall be turned into impassables
                //  everything else is saved into the lock list
                sealBorderTile(map, sealList, SealType.Locked, forthLoc);

                return(true);
            }
            else if (!hasCondition)
            {
                //in the case where the extending tile is within an adjacent and that adjacent DOESNT pass filter
                //  all normal walls for the INWARD border shall be turned into impassables
                //  everything else for the INWARD border shall be saved into a key list

                if (map.Tiles[forthLoc.X][forthLoc.Y].TileEquivalent(map.RoomTerrain))
                {
                    sealBorderTile(map, sealList, SealType.Key, locRay.Loc);
                }
                else
                {
                    sealBorderTile(map, sealList, SealType.Locked, locRay.Loc);
                }

                //when transitioning between inward and outward
                //-when transitioning from outward to inward, the previous outward tile needs an inward check
                //-when transitioning from inward to outward, the current outward tile needs a inward check

                //in the interest of trading redundancy for simplicity, an inward block will just block the tiles to the sides
                //regardless of if they've already been blocked
                //redundancy will be handled by hashsets
                if (side1 != Dir8.None)
                {
                    Loc sideLoc = locRay.Loc + side1.GetLoc();
                    sealBorderTile(map, sealList, SealType.Locked, sideLoc);
                }
                if (side2 != Dir8.None)
                {
                    Loc sideLoc = locRay.Loc + side2.GetLoc();
                    sealBorderTile(map, sealList, SealType.Locked, sideLoc);
                }
                return(false);
            }
            else
            {
                //in the case where the extending tile is within an adjacent and that adjacent passes filter
                //  do nothing and skip these tiles
                return(true);
            }
        }
Exemple #9
0
        public override void Apply(T map)
        {
            Grid.LocTest checkBlock = (Loc testLoc) =>
            {
                return(!map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) || map.HasTileEffect(testLoc));
            };

            //choose a room to put the chest in
            //do not choose a room that would cause disconnection of the floor
            List <int> possibleRooms = new List <int>();

            for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
            {
                FloorRoomPlan testPlan = map.RoomPlan.GetRoomPlan(ii);
                //if (map.RoomPlan.IsChokePoint(new RoomHallIndex(ii, false)))
                //    continue;
                if (!BaseRoomFilter.PassesAllFilters(testPlan, this.Filters))
                {
                    continue;
                }

                //also do not choose a room that contains the end stairs
                IViewPlaceableGenContext <MapGenExit> exitMap = (IViewPlaceableGenContext <MapGenExit>)map;
                if (Collision.InBounds(testPlan.RoomGen.Draw, exitMap.GetLoc(0)))
                {
                    continue;
                }

                possibleRooms.Add(ii);
            }

            if (possibleRooms.Count == 0)
            {
                return;
            }

            List <Loc> freeTiles = new List <Loc>();
            IRoomGen   room      = null;

            while (possibleRooms.Count > 0)
            {
                int chosenRoom = map.Rand.Next(possibleRooms.Count);
                room = map.RoomPlan.GetRoom(possibleRooms[chosenRoom]);

                //get all places that the chest is eligible
                freeTiles = Grid.FindTilesInBox(room.Draw.Start, room.Draw.Size, (Loc testLoc) =>
                {
                    if (map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(testLoc) &&
                        map.Tiles[testLoc.X][testLoc.Y + 1].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(new Loc(testLoc.X, testLoc.Y + 1)) &&
                        !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Panel] &&
                        !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Item])
                    {
                        if (Grid.GetForkDirs(testLoc, checkBlock, checkBlock).Count < 2)
                        {
                            foreach (MapItem item in map.Items)
                            {
                                if (item.TileLoc == testLoc)
                                {
                                    return(false);
                                }
                            }
                            foreach (Team team in map.AllyTeams)
                            {
                                foreach (Character testChar in team.EnumerateChars())
                                {
                                    if (testChar.CharLoc == testLoc)
                                    {
                                        return(false);
                                    }
                                }
                            }
                            foreach (Team team in map.MapTeams)
                            {
                                foreach (Character testChar in team.EnumerateChars())
                                {
                                    if (testChar.CharLoc == testLoc)
                                    {
                                        return(false);
                                    }
                                }
                            }
                            return(true);
                        }
                    }
                    return(false);
                });
                if (freeTiles.Count > 0)
                {
                    break;
                }
                possibleRooms.RemoveAt(chosenRoom);
            }

            //can't find any free tile in any room, return
            if (freeTiles.Count == 0)
            {
                return;
            }

            if (!ItemThemes.CanPick)
            {
                return;
            }
            //choose which item theme to work with
            ItemTheme chosenItemTheme = ItemThemes.Pick(map.Rand);

            //the item spawn list in this class dictates the items available for spawning
            //it will be queried for items that match the theme selected
            List <MapItem> chosenItems = chosenItemTheme.GenerateItems(map, Items);

            if (chosenItems.Count == 0)
            {
                return;
            }

            int randIndex = map.Rand.Next(freeTiles.Count);
            Loc loc       = freeTiles[randIndex];


            EffectTile spawnedChest = new EffectTile(37, true);

            if (Ambush && MobThemes.CanPick)
            {
                spawnedChest.Danger = true;
                //the mob theme will be selected randomly
                MobTheme chosenMobTheme = MobThemes.Pick(map.Rand);

                //the mobs in this class are the ones that would be available when the game wants to spawn things outside of the floor's spawn list
                //it will be queried for monsters that match the theme provided
                List <MobSpawn> chosenMobs = chosenMobTheme.GenerateMobs(map, Mobs);


                MobSpawnState mobSpawn = new MobSpawnState();
                foreach (MobSpawn mob in chosenMobs)
                {
                    MobSpawn copyMob = mob.Copy();
                    if (map.Rand.Next(ALT_COLOR_ODDS) == 0)
                    {
                        copyMob.BaseForm.Skin = 1;
                    }
                    mobSpawn.Spawns.Add(copyMob);
                }
                spawnedChest.TileStates.Set(mobSpawn);
            }

            ItemSpawnState itemSpawn = new ItemSpawnState();

            itemSpawn.Spawns = chosenItems;
            spawnedChest.TileStates.Set(itemSpawn);

            Rect wallBounds = new Rect(room.Draw.X - 1, room.Draw.Y - 1, room.Draw.Size.X + 2, room.Draw.Size.Y + 2);

            spawnedChest.TileStates.Set(new BoundsState(wallBounds));

            ((IPlaceableGenContext <EffectTile>)map).PlaceItem(loc, spawnedChest);
            map.PostProcGrid[loc.X][loc.Y].Status[(int)PostProcType.Panel] = true;
            map.PostProcGrid[loc.X][loc.Y].Status[(int)PostProcType.Item]  = true;

            GenContextDebug.DebugProgress("Placed Chest");
        }
Exemple #10
0
        public override void Apply(T map)
        {
            if (!ItemThemes.CanPick)
            {
                return;
            }

            if (!MobThemes.CanPick)
            {
                return;
            }


            //choose a room to cram all the items in
            List <int> possibleRooms = new List <int>();

            for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
            {
                if (!BaseRoomFilter.PassesAllFilters(map.RoomPlan.GetRoomPlan(ii), this.Filters))
                {
                    continue;
                }
                possibleRooms.Add(ii);
            }

            if (possibleRooms.Count == 0)
            {
                return;
            }

            IRoomGen room = map.RoomPlan.GetRoom(possibleRooms[map.Rand.Next(possibleRooms.Count)]);

            //determine the number of free tiles to put items on; trim the maximum item spawn accordingly (maximum <= 1/2 of free tiles)
            //determine the number of free tiles to put mobs on; trim the maximum mob spawn accordingly (maximum <= 1/2 of free tiles)
            List <Loc> itemTiles = new List <Loc>();
            int        mobSpace  = 0;

            for (int x = room.Draw.X; x < room.Draw.X + room.Draw.Size.X; x++)
            {
                for (int y = room.Draw.Y; y < room.Draw.Y + room.Draw.Size.Y; y++)
                {
                    Loc testLoc = new Loc(x, y);
                    if (!map.TileBlocked(testLoc))
                    {
                        if (!map.HasTileEffect(new Loc(x, y)) && !map.PostProcGrid[x][y].Status[(int)PostProcType.Panel] && !map.PostProcGrid[x][y].Status[(int)PostProcType.Item])
                        {
                            bool hasItem = false;
                            foreach (MapItem item in map.Items)
                            {
                                if (item.TileLoc == testLoc)
                                {
                                    hasItem = true;
                                    break;
                                }
                            }
                            if (!hasItem)
                            {
                                itemTiles.Add(testLoc);
                            }
                        }
                        bool hasMob = false;
                        foreach (Team team in map.AllyTeams)
                        {
                            foreach (Character testChar in team.EnumerateChars())
                            {
                                if (testChar.CharLoc == testLoc)
                                {
                                    hasMob = true;
                                    break;
                                }
                            }
                        }
                        foreach (Team team in map.MapTeams)
                        {
                            foreach (Character testChar in team.EnumerateChars())
                            {
                                if (testChar.CharLoc == testLoc)
                                {
                                    hasMob = true;
                                    break;
                                }
                            }
                        }
                        if (!hasMob)
                        {
                            mobSpace++;
                        }
                    }
                }
            }

            //choose which item theme to work with
            ItemTheme chosenItemTheme = ItemThemes.Pick(map.Rand);

            //the item spawn list in this class dictates the items available for spawning
            //it will be queried for items that match the theme selected
            List <MapItem> chosenItems = chosenItemTheme.GenerateItems(map, Items);

            //place the items
            for (int ii = 0; ii < chosenItems.Count; ii++)
            {
                if (itemTiles.Count > 0)
                {
                    MapItem item      = new MapItem(chosenItems[ii]);
                    int     randIndex = map.Rand.Next(itemTiles.Count);
                    ((IPlaceableGenContext <MapItem>)map).PlaceItem(itemTiles[randIndex], item);
                    itemTiles.RemoveAt(randIndex);
                }
            }



            //the mob theme will be selected randomly
            MobTheme chosenMobTheme = MobThemes.Pick(map.Rand);

            //the mobs in this class are the ones that would be available when the game wants to spawn things outside of the floor's spawn list
            //it will be queried for monsters that match the theme provided
            List <MobSpawn> chosenMobs = chosenMobTheme.GenerateMobs(map, Mobs);

            //cover the room in a check that holds all of the monsters, and covers the room's bounds
            CheckIntrudeBoundsEvent check = new CheckIntrudeBoundsEvent();

            check.Bounds = room.Draw;
            {
                MonsterHouseMapEvent house = new MonsterHouseMapEvent();
                house.Bounds = room.Draw;
                foreach (MobSpawn mob in chosenMobs)
                {
                    MobSpawn copyMob = mob.Copy();
                    if (map.Rand.Next(ALT_COLOR_ODDS) == 0)
                    {
                        copyMob.BaseForm.Skin = 1;
                    }
                    house.Mobs.Add(copyMob);
                }
                check.Effects.Add(house);
            }

            AddIntrudeStep(map, check);
        }
Exemple #11
0
        protected override void PlaceBorders(T map, Dictionary <Loc, SealType> sealList)
        {
            Rect?bossRect = null;

            for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
            {
                FloorRoomPlan plan = map.RoomPlan.GetRoomPlan(ii);
                if (!BaseRoomFilter.PassesAllFilters(plan, this.BossFilters))
                {
                    continue;
                }
                bossRect = plan.RoomGen.Draw;
                break;
            }

            //if there's no way to open the door, there cannot be a door; give the player the treasure unguarded
            if (bossRect == null)
            {
                return;
            }

            EffectTile bossEffect = null;

            for (int xx = bossRect.Value.Start.X; xx < bossRect.Value.End.X; xx++)
            {
                for (int yy = bossRect.Value.Start.Y; yy < bossRect.Value.End.Y; yy++)
                {
                    if (map.Tiles[xx][yy].Effect.ID == BossTile)
                    {
                        bossEffect = map.Tiles[xx][yy].Effect;
                        break;
                    }
                }
                if (bossEffect != null)
                {
                    break;
                }
            }

            if (bossEffect == null)
            {
                return;
            }


            List <Loc> lockList = new List <Loc>();

            foreach (Loc loc in sealList.Keys)
            {
                switch (sealList[loc])
                {
                case SealType.Blocked:
                    map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy();
                    break;

                default:
                    lockList.Add(loc);
                    break;
                }
            }

            foreach (Loc loc in lockList)
            {
                map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy();
                EffectTile newEffect = new EffectTile(SealedTile, true, loc);
                ((IPlaceableGenContext <EffectTile>)map).PlaceItem(loc, newEffect);
            }

            ResultEventState resultEvent = new ResultEventState();

            resultEvent.ResultEvents.Add(new OpenVaultEvent(lockList));

            bossEffect.TileStates.Set(resultEvent);
        }
Exemple #12
0
        public override void Apply(T map)
        {
            //choose a room to cram all the items in
            List <int> possibleRooms = new List <int>();

            for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
            {
                FloorRoomPlan testPlan = map.RoomPlan.GetRoomPlan(ii);
                if (!BaseRoomFilter.PassesAllFilters(testPlan, this.Filters))
                {
                    continue;
                }

                //also do not choose a room that contains the start or end
                IViewPlaceableGenContext <MapGenEntrance> entranceMap = map;
                if (Collision.InBounds(testPlan.RoomGen.Draw, entranceMap.GetLoc(0)))
                {
                    continue;
                }
                IViewPlaceableGenContext <MapGenExit> exitMap = map;
                if (Collision.InBounds(testPlan.RoomGen.Draw, exitMap.GetLoc(0)))
                {
                    continue;
                }

                possibleRooms.Add(ii);
            }

            FloorRoomPlan roomPlan  = null;
            Rect          limitRect = Rect.Empty;

            while (possibleRooms.Count > 0)
            {
                int chosenRoom = map.Rand.Next(possibleRooms.Count);
                roomPlan = map.RoomPlan.GetRoomPlan(possibleRooms[chosenRoom]);

                bool[][] eligibilityGrid = new bool[roomPlan.RoomGen.Draw.Width][];
                for (int xx = 0; xx < roomPlan.RoomGen.Draw.Width; xx++)
                {
                    eligibilityGrid[xx] = new bool[roomPlan.RoomGen.Draw.Height];
                    for (int yy = 0; yy < roomPlan.RoomGen.Draw.Height; yy++)
                    {
                        bool eligible = true;
                        Loc  testLoc  = roomPlan.RoomGen.Draw.Start + new Loc(xx, yy);
                        if (map.Tiles[testLoc.X][testLoc.Y].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(testLoc) &&
                            map.Tiles[testLoc.X][testLoc.Y + 1].TileEquivalent(map.RoomTerrain) && !map.HasTileEffect(new Loc(testLoc.X, testLoc.Y + 1)) &&
                            !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Panel] &&
                            !map.PostProcGrid[testLoc.X][testLoc.Y].Status[(int)PostProcType.Item])
                        {
                            foreach (MapItem item in map.Items)
                            {
                                if (item.TileLoc == testLoc)
                                {
                                    eligible = false;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            eligible = false;
                        }
                        eligibilityGrid[xx][yy] = eligible;
                    }
                }

                List <Rect> candRects = Detection.DetectNLargestRects(eligibilityGrid, 1);
                if (candRects.Count > 0)
                {
                    limitRect = new Rect(roomPlan.RoomGen.Draw.Start + candRects[0].Start, candRects[0].Size);
                    if (limitRect.Size.X >= MIN_SHOP_SIZE && limitRect.Size.Y >= MIN_SHOP_SIZE)
                    {
                        break;
                    }
                }
                possibleRooms.RemoveAt(chosenRoom);
            }

            if (limitRect.Size.X < MIN_SHOP_SIZE || limitRect.Size.Y < MIN_SHOP_SIZE)
            {
                return;
            }

            //randomly roll an actual rectangle within the saferect bounds: between 3x3 and the limit
            Loc  rectSize  = new Loc(map.Rand.Next(MIN_SHOP_SIZE, limitRect.Width + 1), map.Rand.Next(MIN_SHOP_SIZE, limitRect.Height + 1));
            Loc  rectStart = new Loc(limitRect.X + map.Rand.Next(limitRect.Width - rectSize.X + 1), limitRect.Y + map.Rand.Next(limitRect.Height - rectSize.Y + 1));
            Rect safeRect  = new Rect(rectStart, rectSize);

            // place the mat of the shop
            List <Loc> itemTiles = new List <Loc>();

            for (int xx = safeRect.X; xx < safeRect.End.X; xx++)
            {
                for (int yy = safeRect.Y; yy < safeRect.End.Y; yy++)
                {
                    Loc matLoc = new Loc(xx, yy);
                    itemTiles.Add(matLoc);
                    EffectTile effect = new EffectTile(45, true, matLoc);
                    ((IPlaceableGenContext <EffectTile>)map).PlaceItem(matLoc, effect);
                    map.PostProcGrid[matLoc.X][matLoc.Y].Status[(int)PostProcType.Panel] = true;
                    map.PostProcGrid[matLoc.X][matLoc.Y].Status[(int)PostProcType.Item]  = true;
                }
            }

            // place the map status for checking shop items and spawning security guards
            {
                MapStatus status = new MapStatus(SecurityStatus);
                status.LoadFromData();
                ShopSecurityState securityState = new ShopSecurityState();
                for (int ii = 0; ii < Mobs.Count; ii++)
                {
                    securityState.Security.Add(Mobs.GetSpawn(ii).Copy(), Mobs.GetSpawnRate(ii));
                }
                status.StatusStates.Set(securityState);
                status.StatusStates.Set(new MapIndexState(Personality));
                map.Map.Status.Add(SecurityStatus, status);
            }

            // place the mob running the shop
            {
                ExplorerTeam newTeam = new ExplorerTeam();
                newTeam.SetRank(1);
                Character shopkeeper = StartMob.Spawn(newTeam, map);
                Loc       randLoc    = itemTiles[map.Rand.Next(itemTiles.Count)];
                ((IGroupPlaceableGenContext <TeamSpawn>)map).PlaceItems(new TeamSpawn(newTeam, true), new Loc[] { randLoc });
            }

            //choose which item theme to work with
            ItemTheme chosenItemTheme = ItemThemes.Pick(map.Rand);

            //the item spawn list in this class dictates the items available for spawning
            //it will be queried for items that match the theme selected
            List <MapItem> chosenItems = chosenItemTheme.GenerateItems(map, Items);

            //place the items
            for (int ii = 0; ii < chosenItems.Count; ii++)
            {
                if (itemTiles.Count > 0)
                {
                    MapItem item      = new MapItem(chosenItems[ii]);
                    int     randIndex = map.Rand.Next(itemTiles.Count);
                    ((IPlaceableGenContext <MapItem>)map).PlaceItem(itemTiles[randIndex], item);
                    itemTiles.RemoveAt(randIndex);
                }
            }

            //prevent the room from being chosen for anything else
            roomPlan.Components.Set(new NoEventRoom());
        }
Exemple #13
0
        protected override void PlaceBorders(T map, Dictionary <Loc, SealType> sealList)
        {
            List <Loc> freeSwitchTiles = new List <Loc>();

            for (int ii = 0; ii < map.RoomPlan.RoomCount; ii++)
            {
                FloorRoomPlan plan = map.RoomPlan.GetRoomPlan(ii);
                if (!BaseRoomFilter.PassesAllFilters(plan, this.SwitchFilters))
                {
                    continue;
                }
                freeSwitchTiles.AddRange(((IPlaceableGenContext <EffectTile>)map).GetFreeTiles(plan.RoomGen.Draw));
            }
            for (int ii = 0; ii < map.RoomPlan.HallCount; ii++)
            {
                FloorHallPlan plan = map.RoomPlan.GetHallPlan(ii);
                if (!BaseRoomFilter.PassesAllFilters(plan, this.SwitchFilters))
                {
                    continue;
                }
                freeSwitchTiles.AddRange(((IPlaceableGenContext <EffectTile>)map).GetFreeTiles(plan.RoomGen.Draw));
            }

            //if there's no way to open the door, there cannot be a door; give the player the treasure unguarded
            if (freeSwitchTiles.Count == 0)
            {
                return;
            }

            List <Loc> lockList = new List <Loc>();

            foreach (Loc loc in sealList.Keys)
            {
                switch (sealList[loc])
                {
                case SealType.Blocked:
                    map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy();
                    break;

                default:
                    lockList.Add(loc);
                    break;
                }
            }

            foreach (Loc loc in lockList)
            {
                map.Tiles[loc.X][loc.Y] = (Tile)map.UnbreakableTerrain.Copy();
                EffectTile newEffect = new EffectTile(SealedTile, true, loc);
                ((IPlaceableGenContext <EffectTile>)map).PlaceItem(loc, newEffect);
            }


            EffectTile switchTile = new EffectTile(SwitchTile, true);

            if (TimeLimit)
            {
                switchTile.Danger = true;
            }

            TileListState state = new TileListState();

            state.Tiles = lockList;
            switchTile.TileStates.Set(state);

            int randIndex = map.Rand.Next(freeSwitchTiles.Count);

            ((IPlaceableGenContext <EffectTile>)map).PlaceItem(freeSwitchTiles[randIndex], switchTile);
        }