private void AddMonstersEqualDistribution(List<Monster> monster, int level, MapGenerator mapGen) { //Get the number of rooms List<RoomCoords> rooms = mapGen.GetAllRooms(); int noMonsters = monster.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 double[] roomMonsterRatio = new double[noRooms]; for (int i = 0; i < noRooms; i++) { roomMonsterRatio[i] = Math.Max(0, Gaussian.BoxMuller(5, 1)); } double totalMonsterRatio = 0.0; for (int i = 0; i < noRooms; i++) { totalMonsterRatio += roomMonsterRatio[i]; } double ratioToTotalMonsterBudget = noMonsters / totalMonsterRatio; int[] monstersPerRoom = new int[noRooms]; double remainder = 0.0; for (int i = 0; i < noRooms; i++) { double monsterBudget = roomMonsterRatio[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 = 0; for (int i = 0; i < noRooms; i++) { totalMonsters += monstersPerRoom[i]; } LogFile.Log.LogEntryDebug("Total monsters actually placed (level: " + level + "): " + noMonsters, LogDebugLevel.Medium); //Place monsters in rooms Dungeon dungeon = Game.Dungeon; int monsterPos = 0; int maxLoops = 10; for (int r = 0; r < noRooms; r++) { int monstersToPlaceInRoom = monstersPerRoom[r]; int loops = 0; for (int m = 0; m < monstersToPlaceInRoom; m++) { if(monsterPos >= monster.Count) { LogFile.Log.LogEntryDebug("Trying to place too many monsters", LogDebugLevel.High); monsterPos++; continue; } Monster mon = monster[monsterPos]; Point location; do { location = rooms[r].RandomPointInRoom(); loops++; } while (!Game.Dungeon.AddMonster(mon, level, location) && loops < maxLoops); monsterPos++; if (loops == maxLoops) { LogFile.Log.LogEntryDebug("Failed to place: " + mon.Representation, LogDebugLevel.High); } } } }
//Copy of monster one private void AddItemsEqualDistribution(List<Item> monster, int level, MapGenerator mapGen) { //Get the number of rooms List<RoomCoords> rooms = mapGen.GetAllRooms(); int noMonsters = monster.Count; int noRooms = rooms.Count; LogFile.Log.LogEntryDebug("No rooms: " + noRooms + " Total items to place (level: " + level + "): " + noMonsters, LogDebugLevel.Medium); //Distribution amongst rooms, mostly evenly //(better to use a norm dist here) double[] roomMonsterRatio = new double[noRooms]; for (int i = 0; i < noRooms; i++) { roomMonsterRatio[i] = Math.Max(0, Gaussian.BoxMuller(5, 1)); } double totalMonsterRatio = 0.0; for (int i = 0; i < noRooms; i++) { totalMonsterRatio += roomMonsterRatio[i]; } double ratioToTotalMonsterBudget = noMonsters / totalMonsterRatio; int[] monstersPerRoom = new int[noRooms]; double remainder = 0.0; for (int i = 0; i < noRooms; i++) { //In monster levels. A level 3 monster will cost 3 of these. double monsterBudget = roomMonsterRatio[i] * ratioToTotalMonsterBudget + remainder; double actualMonstersToPlace = Math.Floor(monsterBudget); //This is a historic bug - should be actualMonstersToPlace not monstersOfThisLevel. Still, the game is now balanced to this so I can't change it! 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 = 0; for (int i = 0; i < noRooms; i++) { totalMonsters += monstersPerRoom[i]; } LogFile.Log.LogEntryDebug("Total items actually placed (level: " + level + "): " + totalMonsters, LogDebugLevel.Medium); if (totalMonsters < noMonsters) { //find room with no items int i = 0; for (; i < noRooms; i++) { if (monstersPerRoom[i] == 0) break; } if(i == noRooms) monstersPerRoom[0] += noMonsters - totalMonsters; else monstersPerRoom[i] += noMonsters - totalMonsters; LogFile.Log.LogEntryDebug("Compensating (level: " + level + "): " + (noMonsters - totalMonsters) + " extra items", LogDebugLevel.Medium); } //Place monsters in rooms Dungeon dungeon = Game.Dungeon; int monsterPos = 0; int maxLoops = 10; for (int r = 0; r < noRooms; r++) { int monstersToPlaceInRoom = monstersPerRoom[r]; int loops = 0; for (int m = 0; m < monstersToPlaceInRoom; m++) { if (monsterPos >= monster.Count) { LogFile.Log.LogEntryDebug("Trying to place too many items", LogDebugLevel.High); monsterPos++; continue; } Item mon = monster[monsterPos]; Point location; do { location = rooms[r].RandomPointInRoom(); LogFile.Log.LogEntryDebug("Item " + mon.Representation + " at: " + location.ToString(), LogDebugLevel.Medium); loops++; } while (!Game.Dungeon.AddItem(mon, level, location) && loops < maxLoops); monsterPos++; if (loops == maxLoops) { LogFile.Log.LogEntryDebug("Failed to place: " + mon.Representation, LogDebugLevel.High); } } } }