/// <summary> /// Add a monster with a random patrol. Needs the mapgenerator of the level in question /// </summary> /// <param name="monster"></param> /// <param name="mapGen"></param> private void AddMonsterSquarePatrol(MonsterFightAndRunAI monster, int level, MapGenerator mapGen) { Dungeon dungeon = Game.Dungeon; Point startLocation; int loops = 0; int maxLoops = 50; do { CreaturePatrol patrol = mapGen.CreatureStartPosAndWaypoints(monster.GetPatrolRotationClockwise()); monster.Waypoints = patrol.Waypoints; startLocation = patrol.StartPos; loops++; } while (!Game.Dungeon.AddMonster(monster, level, startLocation) && loops < maxLoops); if (loops == maxLoops) { LogFile.Log.LogEntryDebug("Failed to place patrolling monster: " + monster.Representation, LogDebugLevel.High); } }
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); } } } }
/// <summary> /// Add a monster with a random patrol. Needs the mapgenerator of the level in question /// </summary> /// <param name="monster"></param> /// <param name="mapGen"></param> private bool AddMonsterFarFromLocation(Monster monster, Point location, int level, MapGenerator mapGen) { //Offset location int maxLoops = 50; int loops = 0; Point toPlaceLoc = new Point(location); int distance = 40; do { toPlaceLoc = new Point(location.x + (int)Gaussian.BoxMuller(distance, 5), location.y + (int)Gaussian.BoxMuller(distance, 5)); loops++; distance--; } while (!Game.Dungeon.AddMonster(monster, level, toPlaceLoc) && loops < maxLoops); if (loops == maxLoops) { LogFile.Log.LogEntryDebug("Failed to place: " + monster.Representation + " far from to: " + location + " reverting to random placement", LogDebugLevel.Medium); loops = 0; do { toPlaceLoc = Game.Dungeon.RandomWalkablePointInLevel(level); loops++; } while (!Game.Dungeon.AddMonster(monster, level, toPlaceLoc) && loops < maxLoops); LogFile.Log.LogEntryDebug("Failed to place: " + monster.Representation + " giving up", LogDebugLevel.High); return false; } LogFile.Log.LogEntryDebug("Item " + monster.Representation + " placed at: " + location.ToString(), LogDebugLevel.High); return true; }
/// <summary> /// Add a monster with a random patrol. Needs the mapgenerator of the level in question /// </summary> /// <param name="monster"></param> /// <param name="mapGen"></param> private void AddMonsterLinearPatrol(MonsterFightAndRunAI monster, int level, MapGenerator mapGen) { Dungeon dungeon = Game.Dungeon; Point startLocation; int loops = 0; int maxLoops = 50; bool success = false; do { CreaturePatrol patrol = mapGen.CreatureStartPosAndWaypointsSisterRooms(monster.GetPatrolRotationClockwise(), 3); monster.Waypoints = patrol.Waypoints; startLocation = patrol.StartPos; loops++; success = Game.Dungeon.AddMonster(monster, level, startLocation); //Linear patrols start from the centre of rooms so monsters often overlap in small number of room levels //Try with a random point if(!success) success = Game.Dungeon.AddMonster(monster, level, patrol.StartRoom.RandomPointInRoom()); } while (!success && loops < maxLoops); if (loops == maxLoops) { LogFile.Log.LogEntryDebug("Failed to place patrolling monster: " + monster.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); } } } }