示例#1
0
 public static float DistanceSqr(Vector2i a, Vector2i b)
 {
     return(Vector2i.DistanceSqr(a, b));
 }
示例#2
0
        /// <summary>
        /// Runs the generator and returns the spaces in the generated entrance.
        /// </summary>
        /// <param name="rooms">
        /// The rooms that were generated. Used to choose a place to place an entrance.
        /// </param>
        /// <param name="theMap">
        /// The map that new units are being generated into.
        /// </param>
        /// <param name="unitsToKeep">
        /// The units to keep alive in the map, indexed by their ID's.
        /// Pass "null" if new units should be generated from scratch.
        /// </param>
        public List <Vector2i> Generate(Map theMap, EtMGame.WorldSettings genSettings,
                                        List <Room> rooms, int nThreads, int seed,
                                        UlongSet unitsToKeep = null)
        {
            //Choose a room and place the level's "entrance" into the middle of it.
            List <Vector2i> entranceSpaces = new List <Vector2i>();

            {
                PRNG     roomPlacer = new PRNG(unchecked (seed * 8957));
                Vector2i entrance   = rooms[roomPlacer.NextInt() % rooms.Count].OriginalBounds.Center;
                entrance = new Vector2i(Mathf.Clamp(entrance.x, 1, genSettings.Size - 2),
                                        Mathf.Clamp(entrance.y, 1, genSettings.Size - 2));

                //Carve a small circle out of the map for the entrance.
                const float entranceRadius    = 1.75f,
                            entranceRadiusSqr = entranceRadius * entranceRadius;
                int      entranceRadiusCeil   = Mathf.CeilToInt(entranceRadius);
                Vector2i entranceRegionMin    = entrance - new Vector2i(entranceRadiusCeil,
                                                                        entranceRadiusCeil),
                         entranceRegionMax = entrance + new Vector2i(entranceRadiusCeil,
                                                                     entranceRadiusCeil);
                entranceRegionMin = new Vector2i(Mathf.Clamp(entranceRegionMin.x,
                                                             0, genSettings.Size - 1),
                                                 Mathf.Clamp(entranceRegionMin.y,
                                                             0, genSettings.Size - 1));
                entranceRegionMax = new Vector2i(Mathf.Clamp(entranceRegionMax.x,
                                                             0, genSettings.Size - 1),
                                                 Mathf.Clamp(entranceRegionMax.y,
                                                             0, genSettings.Size - 1));
                foreach (Vector2i entranceSpace in new Vector2i.Iterator(entranceRegionMin,
                                                                         entranceRegionMax + 1))
                {
                    if (entrance.DistanceSqr(entranceSpace) < entranceRadiusSqr)
                    {
                        entranceSpaces.Add(entranceSpace);
                        theMap.Tiles[entranceSpace] = GameLogic.TileTypes.Empty;
                    }
                }
            }


            //If we weren't given any units to place, generate some.
            if (unitsToKeep == null)
            {
                unitsToKeep = new UlongSet();

                //Find or create the PlayerGroup.
                var playerGroup = GameLogic.Groups.PlayerGroup.Get(theMap);

                //Generate a certain number of player units.
                PRNG prng = new PRNG(seed);
                for (int i = 0; i < NStartingChars; ++i)
                {
                    //PlayerChar's have 3 stats to randomize.
                    //Distribute "points" among them randomly.
                    //Prefer energy, then food, then strength.

                    float totalPoints = StartingStatAbilities;

                    float p      = prng.NextFloat() * Math.Min(1.0f, totalPoints);
                    float energy = p;
                    totalPoints -= p;

                    p = prng.NextFloat() * Math.Min(1.0f, totalPoints);
                    float food = p;
                    totalPoints -= p;

                    float strength = totalPoints;

                    energy = Mathf.Lerp(PlayerConsts.MinStart_Energy,
                                        PlayerConsts.MaxStart_Energy,
                                        energy);
                    food = Mathf.Lerp(PlayerConsts.MinStart_Food,
                                      PlayerConsts.MaxStart_Food,
                                      food);
                    strength = Mathf.Lerp(PlayerConsts.MinStart_Strength,
                                          PlayerConsts.MaxStart_Strength,
                                          strength);

                    var gender = (i % 2 == 0) ?
                                 GameLogic.Units.Player_Char.Personality.Genders.Male :
                                 GameLogic.Units.Player_Char.Personality.Genders.Female;

                    PlayerChar chr = new PlayerChar(
                        theMap, playerGroup.ID, food, energy, strength, 1.0f,
                        GameLogic.Units.Player_Char.Personality.GenerateName(gender, prng.NextInt()),
                        gender);
                    theMap.AddUnit(chr);
                    unitsToKeep.Add(chr.ID);
                }
            }

            //Position the units.
            UnityEngine.Assertions.Assert.IsTrue(entranceSpaces.Count > 0);
            int unitsPerSpace = unitsToKeep.Count / entranceSpaces.Count;
            int unitI         = 0,
                posI          = 0;

            foreach (Unit unit in unitsToKeep.Select(id => theMap.GetUnit(id)))
            {
                unit.Pos.Value = entranceSpaces[posI];

                unitI += 1;
                if (unitI >= unitsPerSpace)
                {
                    unitI = 0;
                    posI  = (posI + 1) % entranceSpaces.Count;
                }
            }

            return(entranceSpaces);
        }