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); }
public int AddMonstersToRoom(MapInfo mapInfo, int level, int roomId, IEnumerable <Monster> monsters) { var candidatePointsInRoom = mapInfo.GetAllPointsInRoomOfTerrain(roomId, RoomTemplateTerrain.Floor).Shuffle(); int monstersPlaced = 0; Monster mon = monsters.ElementAt(monstersPlaced); foreach (Point p in candidatePointsInRoom) { bool placedSuccessfully = Game.Dungeon.AddMonster(mon, level, p); if (placedSuccessfully) { GiveMonsterStandardItems(mon); monstersPlaced++; if (monstersPlaced == monsters.Count()) { break; } mon = monsters.ElementAt(monstersPlaced); } } return(monstersPlaced); }
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); * }*/ }
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); * }*/ } }
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; } } } }