Esempio n. 1
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;
                    }
                }
            }
        }
Esempio n. 2
0
        private IEnumerable <Monster> CreateGaussianDistributionOfMonsterTypes(List <Tuple <int, Monster> > typesToPlace, int totalMonsters)
        {
            int weightAverage = 10;
            int weightStdDev  = 30;

            var monstersAndWeights = typesToPlace.Select(f => new Tuple <int, Monster>((int)Math.Abs(Gaussian.BoxMuller(weightAverage, weightStdDev)) * f.Item1, f.Item2));

            var monsterTypesDistributionExpanded = Enumerable.Range(0, totalMonsters).Select(i => ChooseItemFromWeights <Monster>(monstersAndWeights));

            return(monsterTypesDistributionExpanded.Select(m => m.NewCreatureOfThisType()));
        }