Beispiel #1
0
        public Level(IntVec startPoint, Tile[,] tiles, GridBoundList <IEnvironmentObject> environment, GridBoundList <IInteractable> interact, GridBoundList <ILightSource> light, GridBoundList <GameCharacter> characterEntities, int dungeonLevel)
        {
            this.tiles                   = tiles;
            this.startPoint              = startPoint;
            this.Environment             = environment;
            this.InteractableEnvironment = interact;
            this.CharacterEntities       = characterEntities;
            this.LightSources            = light;
            this.DroppedItems            = new GridBoundList <Item>();
            this.DungeonLevel            = dungeonLevel;
            calculateTiles();
            needToCache = true;
            cachedSolid = new bool[tiles.GetLength(0), tiles.GetLength(1)];

            a       = GetStartPoint();
            b       = findRandomOpenPosition();
            path    = AStar.getPathBetween(this, a, b);
            moveset = AStar.getPossiblePositionsFrom(this, a, 15, false, false);

            for (int i = 0; i < 28; i++)
            {
                //Item item = Item.randomItem(10, 10);

                //Engine.Engine.Log(string.Format("Item Generated: {0}", item.Name));

                //DroppedItems.Add(item, findRandomOpenPosition());
            }
        }
 private static void populateLightSources(__FloorPlan.__Room room, GridBoundList <ILightSource> lights, Random rand)
 {
     if (room.type != __FloorPlan.__Room.__RoomType.DOORWAY)
     {
         foreach (var wall in room.GetWalls(true))
         {
             if (rand.NextDouble() > 0.94)
             {
                 lights.Add(new Tourch(wall.Item2, new Color(255, 155, 55)), wall.Item1);
             }
             //lights.Add(new ColorEnvironment(new Color(rand.Next(100,256), rand.Next(100,256), rand.Next(100,256)), false), position);
         }
     }
     //switch (room.type)
     //{
     //}
 }
        private static void populateSwitches(__FloorPlan floorPlan, GridBoundList <IInteractable> interactableEnvironment, Random rand, List <IInteractable> subscribedForSwitches)
        {
            while (subscribedForSwitches.Count > 0)
            {
                Brogue.Mapping.LevelGenerator.__FloorPlan.__Room room = floorPlan.rooms[rand.Next(floorPlan.rooms.Length)];

                if (room.type == __FloorPlan.__Room.__RoomType.NOTHING_SPECIAL)
                {
                    foreach (var wall in room.GetWalls(true))
                    {
                        if (subscribedForSwitches.Count > 0 && rand.NextDouble() > 0.99)
                        {
                            interactableEnvironment.Add(new Switch(subscribedForSwitches[0], wall.Item2), wall.Item1);
                            subscribedForSwitches.RemoveAt(0);
                        }
                    }
                }
            }
        }
        public static Level generate(int seed, int levels, int dungeonLevel = 1, int heroLevel = 1)
        {
            //seed = 1599313429;
            //levels = 2150;

            seedDebug  = seed;
            levelDebug = levels;

            Random rand = new Random(seed);

            __FloorPlan floorPlan = createFloorPlan(rand, levels);

            GridBoundList <IEnvironmentObject> environment             = new GridBoundList <IEnvironmentObject>();
            GridBoundList <IInteractable>      interactableEnvironment = new GridBoundList <IInteractable>();
            GridBoundList <ILightSource>       lightSources            = new GridBoundList <ILightSource>();
            GridBoundList <GameCharacter>      characters = new GridBoundList <GameCharacter>();

            IntVec startPoint = findEndPoints(floorPlan, interactableEnvironment, rand);

            Tuple <HiddenPassage, IntVec>[] previousPassage       = new Tuple <HiddenPassage, IntVec> [1];
            List <IInteractable>            subscribedForSwitches = new List <IInteractable>();


            foreach (var room in floorPlan.rooms)
            {
                populateEnvironmentObjects(room, environment, rand);
                populateInteractiveEnvironmentObjects(room, interactableEnvironment, rand, dungeonLevel, heroLevel, previousPassage, subscribedForSwitches);
                populateLightSources(room, lightSources, rand);
                populateGameCharacters(room, characters, rand, dungeonLevel, heroLevel);
            }

            populateSwitches(floorPlan, interactableEnvironment, rand, subscribedForSwitches);

            Level result = new Level(startPoint, floorPlan.tiles, environment, interactableEnvironment, lightSources, characters, dungeonLevel);

            //if (!result.isComplete())
            {
                //Engine.Engine.Log( "Level contains places which are impossible to reach from the starting position" );
            }

            return(result);
        }
        private static void populateGameCharacters(__FloorPlan.__Room room, GridBoundList <GameCharacter> chars, Random rand, int dungeonLevel, int heroLevel)
        {
            switch (room.type)
            {
            case __FloorPlan.__Room.__RoomType.BOSS_ROOM:
                if (room.isFree(room.GetCenter()))
                {
                    chars.Add(EnemyCreator.GetRandomBoss(dungeonLevel), room.GetCenter());
                }
                break;

            case __FloorPlan.__Room.__RoomType.NOTHING_SPECIAL:
                foreach (var pos in room.GetCells())
                {
                    if (rand.NextDouble() > 0.98 && room.isFree(pos))
                    {
                        chars.Add(EnemyCreator.GetRandomEnemy(1, dungeonLevel)[0], pos);
                    }
                    //lights.Add(new ColorEnvironment(new Color(rand.Next(100,256), rand.Next(100,256), rand.Next(100,256)), false), position);
                }
                break;

            case __FloorPlan.__Room.__RoomType.MOB_ROOM:
                Enemy[] enemies = EnemyCreator.GetRandomEnemy(rand.Next(2, 6), dungeonLevel);
                int     dropped = 1;
                chars.Add(enemies[0], room.GetCenter());
                foreach (var dir in Direction.Values)
                {
                    if (dropped < enemies.Length && (room.isFree(room.GetCenter() + dir)))
                    {
                        chars.Add(enemies[dropped], room.GetCenter() + dir);
                        dropped++;
                    }
                }
                break;
            }
        }
        private static IntVec findEndPoints(__FloorPlan floorPlan, GridBoundList <IInteractable> interactableEnvironment, Random rand)
        {
            int entryRoom = rand.Next(floorPlan.hallstart);

            while (floorPlan.rooms[entryRoom].type != __FloorPlan.__Room.__RoomType.FOYER && floorPlan.rooms[entryRoom].type != __FloorPlan.__Room.__RoomType.TREASURE_ROOM)
            {
                entryRoom = (entryRoom + 1) % floorPlan.hallstart;
            }
            __FloorPlan.__Room start      = floorPlan.rooms[entryRoom];
            IntVec             startPoint = start.GetCenter();

            Engine.Engine.Log(string.Format("Start point: <{0}, {1}>", startPoint.X, startPoint.Y));
            floorPlan.isFloor[startPoint.X, startPoint.Y] = false;
            floorPlan.rooms[entryRoom].type = __FloorPlan.__Room.__RoomType.EMPTY;

            int endRoom = (entryRoom + floorPlan.hallstart / 2) % floorPlan.hallstart;

            while (floorPlan.rooms[endRoom].type != __FloorPlan.__Room.__RoomType.FOYER && floorPlan.rooms[endRoom].type != __FloorPlan.__Room.__RoomType.TREASURE_ROOM)
            {
                endRoom = (endRoom + 1) % floorPlan.hallstart;
            }
            __FloorPlan.__Room end = floorPlan.rooms[endRoom];
            floorPlan.rooms[endRoom].type = __FloorPlan.__Room.__RoomType.EMPTY;
            Engine.Engine.Log(string.Format("End point: <{0}, {1}>", end.GetCenter().X, end.GetCenter().Y));
            floorPlan.isFloor[end.GetCenter().X, end.GetCenter().Y] = false;
            try
            {
                Stairs s = new Stairs();
            }
            catch (Exception e)
            {
                Console.WriteLine("");
            }
            interactableEnvironment.Add(new Stairs(), end.GetCenter());
            return(startPoint);
        }
        private static void populateInteractiveEnvironmentObjects(__FloorPlan.__Room room, GridBoundList <IInteractable> interact, Random rand, int dungeonLevel, int heroLevel, Tuple <HiddenPassage, IntVec>[] previousPassage, List <IInteractable> subscribedForSwitches)
        {
            switch (room.type)
            {
            case __FloorPlan.__Room.__RoomType.DOORWAY:
                if (room.setUnfree(room.dimensions.X, room.dimensions.Y))
                {
                    interact.Add(new Door((room.floorPlan[room.dimensions.X - 1, room.dimensions.Y]) ? Direction.RIGHT: Direction.UP), new IntVec(room.dimensions.X, room.dimensions.Y));
                }
                break;

            case __FloorPlan.__Room.__RoomType.SUPAH_TREASURE_ROOM:
                if (room.setUnfree(room.GetCenter()))
                {
                    Item[] items = new Item[rand.Next(2, 8)];
                    for (int i = 0; i < items.Length; i++)
                    {
                        items[i] = Item.randomLegendary(dungeonLevel, heroLevel);
                    }
                    interact.Add(new Chest(items), room.GetCenter());
                }

                foreach (var wall in room.GetWalls(false, false))
                {
                    room.setUnfree(wall.Item1);

                    interact.RemoveAtPosition(wall.Item1);
                    Gate door = new Gate(wall.Item2);
                    interact.Add(door, wall.Item1);
                    subscribedForSwitches.Add(door);
                }
                break;

            case __FloorPlan.__Room.__RoomType.TREASURE_ROOM:
                if (room.setUnfree(room.GetCenter()))
                {
                    Item[] items = new Item[rand.Next(2, 8)];
                    for (int i = 0; i < items.Length; i++)
                    {
                        items[i] = Item.randomItem(dungeonLevel, heroLevel);
                    }
                    interact.Add(new Chest(items), room.GetCenter());
                }
                break;

            case __FloorPlan.__Room.__RoomType.NOTHING_SPECIAL:
                foreach (var wall in room.GetWalls(false))
                {
                    if (rand.NextDouble() > 0.998)
                    {
                        if (previousPassage[0] == null)
                        {
                            previousPassage[0] = Tuple.Create <HiddenPassage, IntVec>(new HiddenPassage(wall.Item2), wall.Item1);
                        }
                        else
                        {
                            interact.Add(previousPassage[0].Item1, previousPassage[0].Item2);
                            interact.Add(new HiddenPassage(previousPassage[0].Item1, wall.Item2), wall.Item1);
                            previousPassage[0] = null;
                        }
                    }
                }
                break;
            }
        }
        private static void populateEnvironmentObjects(__FloorPlan.__Room room, GridBoundList <IEnvironmentObject> environ, Random rand)
        {
            Color col = Color.White;

            switch (room.type)
            {
            case __FloorPlan.__Room.__RoomType.BOSS_ROOM:
                col = Color.Red;
                break;

            case __FloorPlan.__Room.__RoomType.FOYER:
                col = Color.Blue;
                break;

            case __FloorPlan.__Room.__RoomType.TREASURE_ROOM:
                col = Color.Yellow;
                break;

            case __FloorPlan.__Room.__RoomType.NOTHING_SPECIAL:
                col = Color.Gray;
                break;

            case __FloorPlan.__Room.__RoomType.MOB_ROOM:
                col = Color.Green;
                break;
                //case __FloorPlan.__Room.__RoomType.DOORWAY:
                //    environ.Add(new ColorEnvironment(Color.Magenta, true), new IntVec(room.dimensions.X, room.dimensions.Y));
                //    break;
            }

            foreach (IntVec pos in room.GetCells())
            {
                //environ.Add(new ColorEnvironment(col, false), pos);
            }



            switch (room.type)
            {
            case __FloorPlan.__Room.__RoomType.BOSS_ROOM:
                Decoration[] scratches = { new Decoration(new Sprite(Engine.Engine.GetTexture("Enviroment/Scratches"), new IntVec(0, 0))),
                                           new Decoration(new Sprite(Engine.Engine.GetTexture("Enviroment/Scratches"), new IntVec(1, 0))) };
                foreach (IntVec pos in room.GetCells())
                {
                    //Scratches on the floor
                    if (rand.NextDouble() > 0.8)
                    {
                        environ.Add(ChooseOne(rand, scratches), pos);
                    }
                }
                goto case __FloorPlan.__Room.__RoomType.MOB_ROOM;

            case __FloorPlan.__Room.__RoomType.MOB_ROOM:
                Decoration[] bloods = { new Decoration(new Sprite(Engine.Engine.GetTexture("Enviroment/Blood"), new IntVec(0, 0))),
                                        new Decoration(new Sprite(Engine.Engine.GetTexture("Enviroment/Blood"), new IntVec(1, 0))) };
                foreach (IntVec pos in room.GetCells())
                {
                    //Blood on the floor
                    if (rand.NextDouble() > 0.8)
                    {
                        environ.Add(ChooseOne(rand, bloods), pos);
                    }
                }
                break;

            case __FloorPlan.__Room.__RoomType.NOTHING_SPECIAL:
                foreach (Tuple <IntVec, Direction> pos in room.GetWalls(true))
                {
                    if (rand.NextDouble() > 0.95)
                    {
                        environ.Add(new Plant(), pos.Item1);
                    }
                }

                Decoration[] floorStuff = { new Decoration(new Sprite(Engine.Engine.GetTexture("Enviroment/FloorStuff"), new IntVec(0, 0))),
                                            new Decoration(new Sprite(Engine.Engine.GetTexture("Enviroment/FloorStuff"), new IntVec(1, 0))),
                                            new Decoration(new Sprite(Engine.Engine.GetTexture("Enviroment/FloorStuff"), new IntVec(2, 0))) };
                foreach (IntVec pos in room.GetCells())
                {
                    //Random stuff on the floor
                    if (rand.NextDouble() > 0.95)
                    {
                        environ.Add(ChooseOne(rand, floorStuff), pos);
                    }
                }
                break;

            case __FloorPlan.__Room.__RoomType.FOYER:
                Decoration[] tableItems = { new Decoration(new Sprite(Engine.Engine.GetTexture("Enviroment/Plate"), new IntVec(0, 0))),
                                            new Decoration(new Sprite(Engine.Engine.GetTexture("Enviroment/Plate"), new IntVec(0, 0))),
                                            new Decoration(new Sprite(Engine.Engine.GetTexture("Enviroment/Plate"), new IntVec(1, 0))),
                                            new Decoration(new Sprite(Engine.Engine.GetTexture("Enviroment/Plate"), new IntVec(2, 0))),
                                            new Decoration(new Sprite(Engine.Engine.GetTexture("Enviroment/Plate"), new IntVec(3, 0))) };
                //Table
                for (int x = 2; x < room.dimensions.Width - 2; x++)
                {
                    for (int y = 2; y < room.dimensions.Height - 2; y++)
                    {
                        room.setUnfree(room.dimensions.X + x, room.dimensions.Y + y);
                        environ.Add(new Decoration(new Sprite(Engine.Engine.GetTexture("Enviroment/Table"), new IntVec(1 - ((x == 2) ? 1 : 0) + ((x == room.dimensions.Width - 3) ? 1 : 0), 1 - ((y == 2) ? 1 : 0) + ((y == room.dimensions.Height - 3) ? 1 : 0))), true), new IntVec(room.dimensions.X + x, room.dimensions.Y + y));
                        //environ.Add(new ColorEnvironment( Color.Aqua, true ) , new IntVec( room.dimensions.X + x, room.dimensions.Y + y ) );
                        if (rand.NextDouble() > 0.85)
                        {
                            //Something on the table
                            environ.Add(ChooseOne(rand, tableItems), new IntVec(room.dimensions.X + x, room.dimensions.Y + y));
                        }
                    }
                }
                //Chairs
                for (int x = 2; x < room.dimensions.Width - 2; x++)
                {
                    environ.Add(new Chair(Direction.DOWN), new IntVec(room.dimensions.X + x, room.dimensions.Y + 1));
                    environ.Add(new Chair(Direction.UP), new IntVec(room.dimensions.X + x, room.dimensions.Y + room.dimensions.Height - 2));
                }
                for (int y = 2; y < room.dimensions.Height - 2; y++)
                {
                    environ.Add(new Chair(Direction.RIGHT), new IntVec(room.dimensions.X + 1, room.dimensions.Y + y));
                    environ.Add(new Chair(Direction.LEFT), new IntVec(room.dimensions.X + room.dimensions.Width - 2, room.dimensions.Y + y));
                }
                //environ.Add( new Plant(), room.GetCenter() );
                break;
            }
        }