Esempio n. 1
0
        private bool AddMonsterLinearPatrol(MapInfo mapInfo, MonsterFightAndRunAI monster, Dictionary <int, List <int> > terminalBranchNodes, int level)
        {
            var roomsOnLevel = mapInfo.FilterOutCorridors(mapInfo.GetRoomIndicesForLevel(level));

            var roomsWithNeigbours = terminalBranchNodes.Where(tb => tb.Key > 1).SelectMany(tb => tb.Value).Intersect(roomsOnLevel);

            var sourceRooms = roomsWithNeigbours.Shuffle();

            //May be expensive
            Point        startPoint = null;
            List <Point> waypoints  = new List <Point>();

            foreach (var room in sourceRooms)
            {
                var distanceToOtherRooms = mapInfo.Model.GetDistanceOfVerticesFromParticularVertexInFullMap(room, roomsWithNeigbours);

                var sisterRooms = distanceToOtherRooms.Where(kv => kv.Value == 2).Select(kv => kv.Key);

                if (!sisterRooms.Any())
                {
                    continue;
                }

                var candidatePointsInRoom = mapInfo.GetAllPointsInRoomOfTerrain(room, RoomTemplateTerrain.Floor).Shuffle();

                bool success = false;
                foreach (var p in candidatePointsInRoom)
                {
                    success = Game.Dungeon.AddMonster(monster, level, p);

                    if (success)
                    {
                        startPoint = p;
                        break;
                    }
                }

                if (!success)
                {
                    //Failure
                    continue;
                }

                foreach (var sisterRoom in sisterRooms)
                {
                    var candidatePointInSisterRoom = mapInfo.GetAllPointsInRoomOfTerrain(sisterRoom, RoomTemplateTerrain.Floor).RandomElement();
                    waypoints.Add(candidatePointInSisterRoom);
                }

                monster.Waypoints = waypoints;
                break;
            }

            if (startPoint == null)
            {
                return(false);
            }

            return(true);
        }
Esempio n. 2
0
        public void CreateMonstersForLevels(MapInfo mapInfo, int level, int levelDifficulty)
        {
            SetupMonsterWeightings();

            var monsterSetsUsed = new List <MonsterSet>();

            var roomVertices      = mapInfo.FilterOutCorridors(mapInfo.GetRoomIndicesForLevel(level));
            var floorAreaForLevel = roomVertices.Sum(v => mapInfo.GetAllPointsInRoomOfTerrain(v, RoomTemplateTerrain.Floor).Count() + mapInfo.GetAllPointsInRoomOfTerrain(v, RoomTemplateTerrain.Wall).Count());

            LogFile.Log.LogEntryDebug("Floor area for level: " + level + ": " + floorAreaForLevel, LogDebugLevel.Medium);

            //0.05 is a bit high
            double areaScaling      = 0.03;
            var    monstersForLevel = (int)Math.Floor(floorAreaForLevel * areaScaling);

            var monsterSetsForLevel = monsterSets.Where(s => s.difficulty == levelDifficulty);

            if (!monsterSetsForLevel.Any())
            {
                monsterSetsForLevel = monsterSets.Where(s => s.difficulty <= levelDifficulty);
            }

            var newSets    = monsterSetsForLevel.Except(monsterSetsUsed);
            var setsToPick = newSets;

            if (!newSets.Any())
            {
                setsToPick = monsterSetsForLevel;
            }

            var setToUse = setsToPick.RandomElement();

            LogFile.Log.LogEntryDebug("Use set of difficulty " + setToUse.difficulty + " for level " + Game.Dungeon.DungeonInfo.LevelNaming[level], LogDebugLevel.Medium);

            monsterSetsUsed.Add(setToUse);

            AddMonstersToLevelGaussianDistribution(mapInfo, level, setToUse.monsterSet, monstersForLevel);

            //Not working for the time being - maybe check tomorrow morning

            /*
             * //var heurestics = new MapHeuristics(mapInfo.Model.GraphNoCycles, 0);
             *
             * for (int i = 0; i < 10; i++)
             * {
             *  AddMonsterLinearPatrol(mapInfo, new RogueBasin.Creatures.PatrolBot(), terminalBranchNodes, level);
             * }*/
        }
Esempio n. 3
0
        public void RoomsInALevelCanBeReturned()
        {
            var mapInfo = new MapInfo(GetStandardMapInfoBuilder());

            var level1Nodes = mapInfo.GetRoomIndicesForLevel(1);

            CollectionAssert.AreEquivalent(new List<int>(new int[] { 5, 6, 7 }), level1Nodes.ToList());
        }
Esempio n. 4
0
        /** Build a map using templated rooms */
        public MapInfo GenerateDungeonWithStory()
        {
            //Load standard room types
            RoomTemplate room1     = RoomTemplateLoader.LoadTemplateFromFile("RogueBasin.bin.Debug.vaults.vault1.room", StandardTemplateMapping.terrainMapping);
            RoomTemplate corridor1 = RoomTemplateLoader.LoadTemplateFromFile("RogueBasin.bin.Debug.vaults.corridortemplate3x1.room", StandardTemplateMapping.terrainMapping);

            RoomTemplate replacementVault = RoomTemplateLoader.LoadTemplateFromFile("RogueBasin.bin.Debug.vaults.replacevault1.room", StandardTemplateMapping.terrainMapping);
            RoomTemplate placeHolderVault = RoomTemplateLoader.LoadTemplateFromFile("RogueBasin.bin.Debug.vaults.placeholdervault1.room", StandardTemplateMapping.terrainMapping);

            bool    dungeonCreationSuccessful = false;
            MapInfo mapInfo;

            do
            {
                //Build cargo bay level

                var cargoMapBuilder        = new TemplatedMapBuilder(100, 100);
                var cargoTemplateGenerator = new TemplatedMapGenerator(cargoMapBuilder);

                PlaceOriginRoom(cargoTemplateGenerator, room1);
                PlaceRandomConnectedRooms(cargoTemplateGenerator, 4, room1, corridor1, 5, 10);

                //Add mass transit connection
                var cargoTransitConnection = AddRoomToRandomOpenDoor(cargoTemplateGenerator, replacementVault, corridor1, 3);

                //Add escape pods
                var escapePodsConnection = AddRoomToRandomOpenDoor(cargoTemplateGenerator, placeHolderVault, corridor1, 3);

                //Add a small number of place holder holder rooms for vaults
                var cargoPlaceholders      = new List <Connection>();
                int maxPlaceHolders        = 2;
                int cargoTotalPlaceHolders = 0;

                do
                {
                    var placeHolderRoom = AddRoomToRandomOpenDoor(cargoTemplateGenerator, placeHolderVault, corridor1, 3);
                    if (placeHolderRoom != null)
                    {
                        cargoPlaceholders.Add(placeHolderRoom);
                        cargoTotalPlaceHolders++;
                    }
                    else
                    {
                        break;
                    }
                } while (cargoTotalPlaceHolders < maxPlaceHolders);

                cargoTemplateGenerator.ReplaceUnconnectedDoorsWithTerrain(RoomTemplateTerrain.Wall);

                //Build bridge

                var bridgeMapBuilder        = new TemplatedMapBuilder(100, 100);
                var bridgeTemplateGenerator = new TemplatedMapGenerator(bridgeMapBuilder, 100);

                PlaceOriginRoom(bridgeTemplateGenerator, room1);
                PlaceRandomConnectedRooms(bridgeTemplateGenerator, 4, room1, corridor1, 5, 10);

                //Add mass transit connection
                var bridgeTransitConnection = AddRoomToRandomOpenDoor(bridgeTemplateGenerator, replacementVault, corridor1, 3);

                //Add main bridge
                var bridgeMainBridgeConnection = AddRoomToRandomOpenDoor(bridgeTemplateGenerator, placeHolderVault, corridor1, 3);

                //Replace spare doors with walls
                bridgeTemplateGenerator.ReplaceUnconnectedDoorsWithTerrain(RoomTemplateTerrain.Wall);

                //Build the graph containing all the levels

                //Build and add the cargo map

                var mapInfoBuilder = new MapInfoBuilder();
                var startRoom      = 0;
                mapInfoBuilder.AddConstructedLevel(0, cargoTemplateGenerator.ConnectivityMap, cargoTemplateGenerator.GetRoomTemplatesInWorldCoords(), cargoTemplateGenerator.GetDoorsInMapCoords(), startRoom);

                //Build and add the bridge map, with a connection to the cargo map

                mapInfoBuilder.AddConstructedLevel(1, bridgeTemplateGenerator.ConnectivityMap, bridgeTemplateGenerator.GetRoomTemplatesInWorldCoords(), bridgeTemplateGenerator.GetDoorsInMapCoords(),
                                                   new Connection(cargoTransitConnection.Target, bridgeTransitConnection.Target));

                mapInfo = new MapInfo(mapInfoBuilder);
                var mapHeuristics = new MapHeuristics(mapInfo.Model.GraphNoCycles, startRoom);

                //LOCKS

                //MAIN QUEST

                //Escape pod door
                //  - bridge self-destruct

                mapInfo.Model.DoorAndClueManager.PlaceDoorAndClue(new DoorRequirements(escapePodsConnection, "escape"), bridgeMainBridgeConnection.Target);

                //MAIN QUEST SUPPORT

                //Level-local lock on bridge level on critical path to main bridge. Place clue a reasonable distance away, not on critical path (if possible)

                var bridgeCriticalPath       = mapInfo.Model.GetPathBetweenVerticesInReducedMap(bridgeTransitConnection.Target, bridgeMainBridgeConnection.Target);
                var bridgeCriticalConnection = bridgeCriticalPath.ElementAt(bridgeCriticalPath.Count() / 2);

                var allRoomsForCriticalClue = mapInfo.Model.DoorAndClueManager.GetValidRoomsToPlaceClueForDoor(bridgeCriticalConnection);
                var bridgeRooms             = mapInfo.GetRoomIndicesForLevel(1);
                var bridgeCriticalPathRooms = bridgeCriticalPath.Select(c => c.Source).Union(bridgeCriticalPath.Select(c => c.Target));

                var allowedBridgeRoomsNotOnCriticalPath = allRoomsForCriticalClue.Intersect(bridgeRooms).Except(bridgeCriticalPathRooms);

                int roomForCriticalBridgeClue;
                if (allowedBridgeRoomsNotOnCriticalPath.Count() > 0)
                {
                    var distancesBetweenClueAndDoor = mapInfo.Model.GetDistanceOfVerticesFromParticularVertexInReducedMap(bridgeCriticalConnection.Source, allowedBridgeRoomsNotOnCriticalPath);

                    //Get room that is half maximum distance from door
                    var verticesByDistance = distancesBetweenClueAndDoor.OrderByDescending(kv => kv.Value).Select(kv => kv.Key);
                    roomForCriticalBridgeClue = verticesByDistance.ElementAt(verticesByDistance.Count() / 2);

                    //Or as far away as possible
                    roomForCriticalBridgeClue = MaxEntry(distancesBetweenClueAndDoor).Key;
                }
                else
                {
                    roomForCriticalBridgeClue = allRoomsForCriticalClue.RandomElement();
                }

                mapInfo.Model.DoorAndClueManager.PlaceDoorAndClue(new DoorRequirements(bridgeCriticalConnection, "green"), roomForCriticalBridgeClue);

                LogFile.Log.LogEntryDebug("L0 Critical Path, candidates: " + allowedBridgeRoomsNotOnCriticalPath.Count() + " lock at: " + bridgeCriticalConnection + " clue at " + roomForCriticalBridgeClue, LogDebugLevel.High);

                //Add maps to the dungeon

                Map masterMap = cargoMapBuilder.MergeTemplatesIntoMap(terrainMapping);

                //Set player's start location (must be done before adding items)

                var firstRoom = mapInfo.GetRoom(0);
                masterMap.PCStartLocation = new Point(firstRoom.X + firstRoom.Room.Width / 2, firstRoom.Y + firstRoom.Room.Height / 2);

                //Add terrain and randomize walls

                Dictionary <MapTerrain, List <MapTerrain> > brickTerrainMapping = new Dictionary <MapTerrain, List <MapTerrain> > {
                    { MapTerrain.Wall, new List <MapTerrain> {
                          MapTerrain.BrickWall1, MapTerrain.BrickWall1, MapTerrain.BrickWall1, MapTerrain.BrickWall2, MapTerrain.BrickWall3, MapTerrain.BrickWall4, MapTerrain.BrickWall5
                      } }
                };

                Map randomizedMapL1 = MapTerrainRandomizer.RandomizeTerrainInMap(masterMap, brickTerrainMapping);
                Game.Dungeon.AddMap(randomizedMapL1);

                Map masterMapL2 = bridgeMapBuilder.MergeTemplatesIntoMap(terrainMapping);
                Dictionary <MapTerrain, List <MapTerrain> > panelTerrainMapping = new Dictionary <MapTerrain, List <MapTerrain> > {
                    { MapTerrain.Wall, new List <MapTerrain> {
                          MapTerrain.PanelWall1, MapTerrain.PanelWall1, MapTerrain.PanelWall1, MapTerrain.PanelWall2, MapTerrain.PanelWall3, MapTerrain.PanelWall4, MapTerrain.PanelWall5
                      } }
                };
                Map randomizedMapL2 = MapTerrainRandomizer.RandomizeTerrainInMap(masterMapL2, panelTerrainMapping);
                Game.Dungeon.AddMap(randomizedMapL2);

                //Recalculate walkable to allow placing objects
                Game.Dungeon.RefreshAllLevelPathingAndFOV();

                //Add elevator features to link the maps

                //L1 -> L2
                var elevator1Loc = mapInfo.GetRandomPointInRoomOfTerrain(cargoTransitConnection.Target, RoomTemplateTerrain.Floor);
                var elevator2Loc = mapInfo.GetRandomPointInRoomOfTerrain(bridgeTransitConnection.Target, RoomTemplateTerrain.Floor);

                Game.Dungeon.AddFeature(new Features.Elevator(1, elevator2Loc), 0, elevator1Loc);
                Game.Dungeon.AddFeature(new Features.Elevator(0, elevator1Loc), 1, elevator2Loc);

                //Add non-interactable features
                var bridgeRoomOnMap = mapInfo.GetRoom(bridgeMainBridgeConnection.Target);
                AddStandardDecorativeFeaturesToRoom(1, bridgeRoomOnMap, 50, DecorationFeatureDetails.decorationFeatures[DecorationFeatureDetails.DecorationFeatures.Machine]);
                var escapePodsRoom = mapInfo.GetRoom(escapePodsConnection.Target);
                AddStandardDecorativeFeaturesToRoom(0, escapePodsRoom, 50, DecorationFeatureDetails.decorationFeatures[DecorationFeatureDetails.DecorationFeatures.Machine]);

                //Add clues

                //Find a random room corresponding to a vertex with a clue and place a clue there
                foreach (var cluesAtVertex in mapInfo.Model.DoorAndClueManager.ClueMap)
                {
                    foreach (var clue in cluesAtVertex.Value)
                    {
                        var possibleRooms = clue.PossibleClueRoomsInFullMap;
                        var randomRoom    = possibleRooms[Game.Random.Next(possibleRooms.Count)];

                        bool placedItem = false;
                        do
                        {
                            var pointInRoom = mapInfo.GetRandomPointInRoomOfTerrain(randomRoom, RoomTemplateTerrain.Floor);

                            placedItem = Game.Dungeon.AddItem(new Items.Clue(clue), mapInfo.GetLevelForRoomIndex(randomRoom), pointInRoom);
                        } while (!placedItem);
                    }
                }

                //Add locks to dungeon as simple doors

                foreach (var door in mapInfo.Model.DoorAndClueManager.DoorMap.Values)
                {
                    var lockedDoor = new Locks.SimpleLockedDoor(door);
                    var doorInfo   = mapInfo.GetDoorForConnection(door.DoorConnectionFullMap);
                    lockedDoor.LocationLevel = doorInfo.LevelNo;
                    lockedDoor.LocationMap   = doorInfo.MapLocation;

                    LogFile.Log.LogEntryDebug("Lock door level " + lockedDoor.LocationLevel + " loc: " + doorInfo.MapLocation, LogDebugLevel.High);

                    Game.Dungeon.AddLock(lockedDoor);
                }

                dungeonCreationSuccessful = true;
            } while (!dungeonCreationSuccessful);

            //Set map for visualisation
            return(mapInfo);
        }
Esempio n. 5
0
        /** Build a map using templated rooms */
        public MapInfo GenerateDungeonWithReplacedVaults()
        {
            //Load standard room types
            RoomTemplate room1     = RoomTemplateLoader.LoadTemplateFromFile("RogueBasin.bin.Debug.vaults.vault1.room", StandardTemplateMapping.terrainMapping);
            RoomTemplate corridor1 = RoomTemplateLoader.LoadTemplateFromFile("RogueBasin.bin.Debug.vaults.corridortemplate3x1.room", StandardTemplateMapping.terrainMapping);

            RoomTemplate replacementVault = RoomTemplateLoader.LoadTemplateFromFile("RogueBasin.bin.Debug.vaults.replacevault1.room", StandardTemplateMapping.terrainMapping);
            RoomTemplate placeHolderVault = RoomTemplateLoader.LoadTemplateFromFile("RogueBasin.bin.Debug.vaults.placeholdervault1.room", StandardTemplateMapping.terrainMapping);

            //Build level 1

            var l1mapBuilder        = new TemplatedMapBuilder(100, 100);
            var l1templateGenerator = new TemplatedMapGenerator(l1mapBuilder);

            PlaceOriginRoom(l1templateGenerator, room1);
            PlaceRandomConnectedRooms(l1templateGenerator, 5, room1, corridor1, 5, 10);

            //Add a place holder room for the elevator
            var l1elevatorConnection = AddRoomToRandomOpenDoor(l1templateGenerator, placeHolderVault, corridor1, 3);
            var l1elevatorIndex      = l1elevatorConnection.Target;

            LogFile.Log.LogEntryDebug("Level 1 elevator at index " + l1elevatorIndex, LogDebugLevel.High);

            //Build level 2

            var l2mapBuilder        = new TemplatedMapBuilder(100, 100);
            var l2templateGenerator = new TemplatedMapGenerator(l2mapBuilder, 100);

            PlaceOriginRoom(l2templateGenerator, room1);
            PlaceRandomConnectedRooms(l2templateGenerator, 5, room1, corridor1, 5, 10);

            //Add a place holder room for the elevator
            var l2elevatorConnection = AddRoomToRandomOpenDoor(l2templateGenerator, placeHolderVault, corridor1, 3);
            var l2elevatorIndex      = l2elevatorConnection.Target;

            LogFile.Log.LogEntryDebug("Level 2 elevator at index " + l2elevatorIndex, LogDebugLevel.High);

            //Replace the placeholder vaults with the actual elevator rooms
            l1templateGenerator.ReplaceRoomTemplate(l1elevatorIndex, l1elevatorConnection, replacementVault, 0);
            l2templateGenerator.ReplaceRoomTemplate(l2elevatorIndex, l2elevatorConnection, replacementVault, 0);

            //Replace spare doors with walls
            l1templateGenerator.ReplaceUnconnectedDoorsWithTerrain(RoomTemplateTerrain.Wall);
            l2templateGenerator.ReplaceUnconnectedDoorsWithTerrain(RoomTemplateTerrain.Wall);

            //Build the graph containing all the levels

            //Build and add the l1 map

            var mapInfoBuilder = new MapInfoBuilder();
            var startRoom      = 0;

            mapInfoBuilder.AddConstructedLevel(0, l1templateGenerator.ConnectivityMap, l1templateGenerator.GetRoomTemplatesInWorldCoords(), l1templateGenerator.GetDoorsInMapCoords(), startRoom);

            //Build and add the l2 map

            mapInfoBuilder.AddConstructedLevel(1, l2templateGenerator.ConnectivityMap, l2templateGenerator.GetRoomTemplatesInWorldCoords(), l2templateGenerator.GetDoorsInMapCoords(),
                                               new Connection(l1elevatorIndex, l2elevatorIndex));

            MapInfo mapInfo       = new MapInfo(mapInfoBuilder);
            var     mapHeuristics = new MapHeuristics(mapInfo.Model.GraphNoCycles, startRoom);

            //LOCKS

            //Add a locked door on a dead end, localised to level 0
            var level0Indices       = mapInfo.GetRoomIndicesForLevel(0);
            var roomConnectivityMap = mapHeuristics.GetTerminalBranchConnections();

            var deadEnds         = roomConnectivityMap[0];
            var deadEndsInLevel0 = deadEnds.Where(c => level0Indices.Contains(c.Source) && level0Indices.Contains(c.Target)).ToList();

            var randomDeadEndToLock = deadEndsInLevel0.RandomElement();

            var allRoomsForClue0    = mapInfo.Model.DoorAndClueManager.GetValidRoomsToPlaceClueForDoor(randomDeadEndToLock);
            var roomsForClue0Level0 = allRoomsForClue0.Intersect(level0Indices);
            var roomForClue0        = roomsForClue0Level0.RandomElement();

            LogFile.Log.LogEntryDebug("Lock door " + randomDeadEndToLock + " clue at " + roomForClue0, LogDebugLevel.High);

            mapInfo.Model.DoorAndClueManager.PlaceDoorAndClue(new DoorRequirements(randomDeadEndToLock, "yellow"), roomForClue0);

            //Add a locked door halfway along the critical path between the l0 and l1 elevators
            var l0CriticalPath       = mapInfo.Model.GetPathBetweenVerticesInReducedMap(startRoom, l1elevatorIndex);
            var l0CriticalConnection = l0CriticalPath.ElementAt(l0CriticalPath.Count() / 2);

            var allRoomsForCriticalL0Clue = mapInfo.Model.DoorAndClueManager.GetValidRoomsToPlaceClueForDoor(l0CriticalConnection);
            var roomForCriticalL0Clue     = allRoomsForCriticalL0Clue.RandomElement();

            mapInfo.Model.DoorAndClueManager.PlaceDoorAndClue(new DoorRequirements(l0CriticalConnection, "green"), roomForCriticalL0Clue);

            LogFile.Log.LogEntryDebug("L0 Critical Path, candidates: " + l0CriticalPath.Count() + " lock at: " + l0CriticalConnection + " clue at " + roomForCriticalL0Clue, LogDebugLevel.High);

            //Add a multi-level clue
            var level1Indices = mapInfo.GetRoomIndicesForLevel(1);

            var deadEndsInLevel1 = deadEnds.Where(c => level1Indices.Contains(c.Source) && level1Indices.Contains(c.Target)).ToList();

            var randomDeadEndToLockL1 = deadEndsInLevel1.RandomElement();

            var allRoomsForClue1    = mapInfo.Model.DoorAndClueManager.GetValidRoomsToPlaceClueForDoor(randomDeadEndToLockL1);
            var roomsForClue1Level0 = allRoomsForClue1.Intersect(level0Indices);
            var roomForClue1        = roomsForClue0Level0.RandomElement();

            LogFile.Log.LogEntryDebug("Lock door " + randomDeadEndToLock + " clue at " + roomForClue0, LogDebugLevel.High);

            mapInfo.Model.DoorAndClueManager.PlaceDoorAndClue(new DoorRequirements(randomDeadEndToLockL1, "red"), roomForClue1);

            //Add a locked door to a dead end, localised to level 1 and place the clue as far away as possible on that level

            var randomDeadEndToLockL1FarClue = deadEndsInLevel1.RandomElement();

            var allRoomsForFarClue          = mapInfo.Model.DoorAndClueManager.GetValidRoomsToPlaceClueForDoor(randomDeadEndToLockL1FarClue);
            var roomsForFarClueLevel1       = allRoomsForFarClue.Intersect(level1Indices);
            var distancesBetweenClueAndDoor = mapInfo.Model.GetDistanceOfVerticesFromParticularVertexInReducedMap(randomDeadEndToLockL1.Source, roomsForFarClueLevel1);
            var roomForFarClue = MaxEntry(distancesBetweenClueAndDoor).Key;

            LogFile.Log.LogEntryDebug("Lock door " + randomDeadEndToLockL1FarClue + " clue at " + roomForFarClue, LogDebugLevel.High);

            mapInfo.Model.DoorAndClueManager.PlaceDoorAndClue(new DoorRequirements(randomDeadEndToLockL1FarClue, "magenta"), roomForFarClue);

            //Add maps to the dungeon

            Map masterMap = l1mapBuilder.MergeTemplatesIntoMap(terrainMapping);

            //Set player's start location (must be done before adding items)

            var firstRoom = mapInfo.GetRoom(0);

            masterMap.PCStartLocation = new Point(firstRoom.X + firstRoom.Room.Width / 2, firstRoom.Y + firstRoom.Room.Height / 2);

            //Add terrain and randomize walls

            Dictionary <MapTerrain, List <MapTerrain> > brickTerrainMapping = new Dictionary <MapTerrain, List <MapTerrain> > {
                { MapTerrain.Wall, new List <MapTerrain> {
                      MapTerrain.BrickWall1, MapTerrain.BrickWall1, MapTerrain.BrickWall1, MapTerrain.BrickWall2, MapTerrain.BrickWall3, MapTerrain.BrickWall4, MapTerrain.BrickWall5
                  } }
            };

            Map randomizedMapL1 = MapTerrainRandomizer.RandomizeTerrainInMap(masterMap, brickTerrainMapping);

            Game.Dungeon.AddMap(randomizedMapL1);

            Map masterMapL2 = l2mapBuilder.MergeTemplatesIntoMap(terrainMapping);
            Dictionary <MapTerrain, List <MapTerrain> > panelTerrainMapping = new Dictionary <MapTerrain, List <MapTerrain> > {
                { MapTerrain.Wall, new List <MapTerrain> {
                      MapTerrain.PanelWall1, MapTerrain.PanelWall1, MapTerrain.PanelWall1, MapTerrain.PanelWall2, MapTerrain.PanelWall3, MapTerrain.PanelWall4, MapTerrain.PanelWall5
                  } }
            };
            Map randomizedMapL2 = MapTerrainRandomizer.RandomizeTerrainInMap(masterMapL2, panelTerrainMapping);

            Game.Dungeon.AddMap(randomizedMapL2);

            //Recalculate walkable to allow placing objects
            Game.Dungeon.RefreshAllLevelPathingAndFOV();

            //Add elevator features to link the maps

            //L1 -> L2
            var elevator1Loc = mapInfo.GetRandomPointInRoomOfTerrain(l1elevatorIndex, RoomTemplateTerrain.Floor);
            var elevator2Loc = mapInfo.GetRandomPointInRoomOfTerrain(l2elevatorIndex, RoomTemplateTerrain.Floor);

            Game.Dungeon.AddFeature(new Features.Elevator(1, elevator2Loc), 0, elevator1Loc);
            Game.Dungeon.AddFeature(new Features.Elevator(0, elevator1Loc), 1, elevator2Loc);


            //Add clues

            //Find a random room corresponding to a vertex with a clue and place a clue there
            foreach (var cluesAtVertex in mapInfo.Model.DoorAndClueManager.ClueMap)
            {
                foreach (var clue in cluesAtVertex.Value)
                {
                    var possibleRooms = clue.PossibleClueRoomsInFullMap;
                    var randomRoom    = possibleRooms[Game.Random.Next(possibleRooms.Count)];

                    var pointInRoom = mapInfo.GetRandomPointInRoomOfTerrain(randomRoom, RoomTemplateTerrain.Floor);

                    Game.Dungeon.AddItem(new Items.Clue(clue), mapInfo.GetLevelForRoomIndex(randomRoom), pointInRoom);
                }
            }

            //Add locks to dungeon as simple doors

            foreach (var door in mapInfo.Model.DoorAndClueManager.DoorMap.Values)
            {
                var lockedDoor = new Locks.SimpleLockedDoor(door);
                var doorInfo   = mapInfo.GetDoorForConnection(door.DoorConnectionFullMap);
                lockedDoor.LocationLevel = doorInfo.LevelNo;
                lockedDoor.LocationMap   = doorInfo.MapLocation;

                LogFile.Log.LogEntryDebug("Lock door level " + lockedDoor.LocationLevel + " loc: " + doorInfo.MapLocation, LogDebugLevel.High);

                Game.Dungeon.AddLock(lockedDoor);
            }

            //Set map for visualisation
            return(mapInfo);
        }
Esempio n. 6
0
        public void CreateMonstersForLevels(MapInfo mapInfo, IEnumerable <int> levelsToProcess, Dictionary <int, int> levelDifficulty)
        {
            SetupMonsterWeightings();

            var monsterSetsUsed = new List <MonsterSet>();

            foreach (var level in levelsToProcess)
            {
                var roomVertices      = mapInfo.FilterOutCorridors(mapInfo.GetRoomIndicesForLevel(level));
                var floorAreaForLevel = roomVertices.Sum(v => mapInfo.GetAllPointsInRoomOfTerrain(v, RoomTemplateTerrain.Floor).Count() + mapInfo.GetAllPointsInRoomOfTerrain(v, RoomTemplateTerrain.Wall).Count());
                LogFile.Log.LogEntryDebug("Floor area for level: " + level + ": " + floorAreaForLevel, LogDebugLevel.Medium);

                //0.05 is a bit high
                double areaScaling      = 0.03;
                var    monstersForLevel = (int)Math.Floor(floorAreaForLevel * areaScaling);

                var monsterSetsForLevel = monsterSets.Where(s => s.difficulty == levelDifficulty[level]);

                if (!monsterSetsForLevel.Any())
                {
                    monsterSetsForLevel = monsterSets.Where(s => s.difficulty <= levelDifficulty[level]);
                }

                var newSets    = monsterSetsForLevel.Except(monsterSetsUsed);
                var setsToPick = newSets;
                if (!newSets.Any())
                {
                    setsToPick = monsterSetsForLevel;
                }

                var setToUse = setsToPick.RandomElement();

                monstersForLevel = (int)Math.Ceiling(monstersForLevel * setToUse.scaling);

                if (Game.Dungeon.Difficulty == GameDifficulty.Easy)
                {
                    monstersForLevel = (int)Math.Ceiling(monstersForLevel * 0.5);
                }
                else if (Game.Dungeon.Difficulty == GameDifficulty.Medium)
                {
                    monstersForLevel = (int)Math.Ceiling(monstersForLevel * 1.0);
                }
                else if (Game.Dungeon.Difficulty == GameDifficulty.Hard)
                {
                    monstersForLevel = (int)Math.Ceiling(monstersForLevel * 1.2);
                }

                LogFile.Log.LogEntryDebug("Use set of difficulty " + setToUse.difficulty + " for level " + Game.Dungeon.DungeonInfo.LevelNaming[level], LogDebugLevel.Medium);

                monsterSetsUsed.Add(setToUse);

                Game.Dungeon.MonsterPlacement.AddMonstersToLevelGaussianDistribution(mapInfo, level, setToUse.monsterSet, monstersForLevel);

                var monsterSetContainsBarrels = setToUse.monsterSet.Where(t => t.Item2.GetType() == typeof(RogueBasin.Creatures.ExplosiveBarrel));

                if (monsterSetContainsBarrels.Any())
                {
                    AddMonstersToLevelGaussianDistribution(mapInfo, level, new List <Tuple <int, Monster> > {
                        new Tuple <int, Monster>(1, new RogueBasin.Creatures.ExplosiveBarrel())
                    }, monstersForLevel / 3);
                }

                //Not working for the time being - maybe check tomorrow morning

                /*
                 * //var heurestics = new MapHeuristics(mapInfo.Model.GraphNoCycles, 0);
                 *
                 * for (int i = 0; i < 10; i++)
                 * {
                 *  AddMonsterLinearPatrol(mapInfo, new RogueBasin.Creatures.PatrolBot(), terminalBranchNodes, level);
                 * }*/
            }
        }
Esempio n. 7
0
        private void AddMonstersToRoomsOnLevelGaussianDistribution(MapInfo mapInfo, int level, IEnumerable <Monster> monster)
        {
            //Get the number of rooms
            var allRoomsAndCorridors = mapInfo.GetRoomIndicesForLevel(level).Except(new List <int> {
                mapInfo.StartRoom
            });
            var rooms = mapInfo.FilterOutCorridors(allRoomsAndCorridors).ToList();
            var candidatePointsInRooms = rooms.Select(room => mapInfo.GetAllPointsInRoomOfTerrain(room, RoomTemplateTerrain.Floor));
            var roomsAndPointsInRooms  = rooms.Zip(candidatePointsInRooms, Tuple.Create);

            var monstersToPlaceRandomized = monster.Shuffle().ToList();

            int noMonsters = monstersToPlaceRandomized.Count;
            int noRooms    = rooms.Count();

            LogFile.Log.LogEntryDebug("No rooms: " + noRooms + " Total monsters to place (level: " + level + "): " + noMonsters, LogDebugLevel.Medium);

            //Distribution amongst rooms, mostly evenly, scaled by room size

            var roomMonsterRatio = roomsAndPointsInRooms.Select(rp => Math.Max(0, Gaussian.BoxMuller(5, 3)) * rp.Item2.Count());

            double totalMonsterRatio = roomMonsterRatio.Sum();

            double ratioToTotalMonsterBudget = noMonsters / totalMonsterRatio;

            int[]  monstersPerRoom = new int[noRooms];
            double remainder       = 0.0;

            for (int i = 0; i < noRooms; i++)
            {
                double monsterBudget = roomMonsterRatio.ElementAt(i) * ratioToTotalMonsterBudget + remainder;

                double actualMonstersToPlace = Math.Floor(monsterBudget);

                double levelBudgetSpent    = actualMonstersToPlace;
                double levelBudgetLeftOver = monsterBudget - levelBudgetSpent;

                monstersPerRoom[i] = (int)actualMonstersToPlace;
                remainder          = levelBudgetLeftOver;

                //Any left over monster ratio gets added to the next level up
            }

            //Calculate actual number of monster levels placed

            int totalMonsters = monstersPerRoom.Sum();

            LogFile.Log.LogEntryDebug("Total monsters actually placed (level: " + level + "): " + noMonsters, LogDebugLevel.Medium);

            //Place monsters in rooms

            Dungeon dungeon = Game.Dungeon;

            int monsterPos = 0;

            for (int r = 0; r < noRooms; r++)
            {
                int monstersToPlaceInRoom = monstersPerRoom[r];

                var candidatePointsInRoom = roomsAndPointsInRooms.ElementAt(r).Item2.Shuffle();
                int monstersPlacedInRoom  = 0;

                foreach (var p in candidatePointsInRoom)
                {
                    if (monsterPos >= monstersToPlaceRandomized.Count)
                    {
                        LogFile.Log.LogEntryDebug("Trying to place too many monsters", LogDebugLevel.High);
                        monsterPos++;
                        break;
                    }

                    Monster mon = monstersToPlaceRandomized[monsterPos];
                    GiveMonsterStandardItems(mon);

                    bool placedSuccessfully = Game.Dungeon.AddMonster(mon, level, p);
                    if (placedSuccessfully)
                    {
                        monsterPos++;
                        monstersPlacedInRoom++;
                    }

                    if (monstersPlacedInRoom >= monstersToPlaceInRoom)
                    {
                        break;
                    }
                }
            }
        }