Exemple #1
0
        public NoZeroLevelUpStats(
            int[] growthRates, int[] statGains, bool[] cappedStats)
            : base(growthRates, statGains, cappedStats)
        {
            // On an empty level, gain a point in whatever stat had the best roll
            if (EmptyLevel)
            {
                // Get a random stat order, for tie breaking
                List <int> stats           = Enumerable.Range(0, growthRates.Length).ToList();
                List <int> randomStatOrder = new List <int>();
                while (stats.Count > 0)
                {
                    int index = Global.game_system.get_rng() % stats.Count;
                    if (growthRates[index] != 0)
                    {
                        randomStatOrder.Add(stats[index]);
                    }
                    stats.RemoveAt(index);
                }

                if (randomStatOrder.Any())
                {
                    // Take the roll for each growth rate and get the difference
                    var rolls = new List <Tuple <int, int> >();
                    foreach (int j in randomStatOrder)
                    {
                        int roll = Rolls[j] - Math.Abs(growthRates[j]);
                        // Halve the chance of getting hp,
                        // since hp is worth half as much
                        rolls.Add(Tuple.Create(j,
                                               roll * Game_Actor.GetStatRatio(j)));
                    }
                    // Sort by how close to the growth the roll was
                    rolls.Sort(delegate(Tuple <int, int> a, Tuple <int, int> b)
                    {
                        int sortValue = a.Item2 - b.Item2;
                        if (sortValue == 0)
                        {
                            return(randomStatOrder.IndexOf(b.Item1));
                        }
                        return(sortValue);
                    });

                    int freeStat = rolls[0].Item1;
                    StatGains[freeStat] += growthRates[freeStat] > 0 ? 1 : -1;
                }
            }
        }
        public override string ToString()
        {
            string result = string.Format(
                "LevelUpStats: {0} point change", Enumerable
                .Range(0, StatGains.Length)
                .Sum(i => StatGains[i] / (float)Game_Actor.GetStatRatio(i)));

            if (PerfectLevel)
            {
                result += "; Perfect level";
            }
            else if (EmptyLevel)
            {
                result += "; Empty level";
            }

            return(result);
        }
        private void GetGrowthOverflow(
            int[] gainedStats, int[] currentLevelStats, int[] growths)
        {
            int unusedGrowth  = 0;
            int uncappedStats = growths.Length;

            // Apply guaranteed growths and get the remainder
            for (int i = 0; i < growths.Length; i++)
            {
                for (; ;)
                {
                    bool guaranteedGain = growths[i] >= 100;
                    bool guaranteedLoss = growths[i] <= -100;
                    bool statCapped     = Actor.get_capped(
                        i, gainedStats[i] + currentLevelStats[i]);

                    // If the growth is below -100, add 100 to the growth and subtract 1 from the stat
                    if (guaranteedLoss)
                    {
                        currentLevelStats[i]--;
                        growths[i] += 100;
                    }
                    // If the stat is already capped, add it to the excess growth pool and zero it out
                    else if (statCapped && growths[i] > 0)
                    {
                        unusedGrowth += growths[i] / Game_Actor.GetStatRatio(i);
                        uncappedStats--;
                        growths[i] = 0;
                    }
                    // If the growth is above 100, add 1 to the stat and subtract 100 from the growth
                    else if (guaranteedGain)
                    {
                        currentLevelStats[i]++;
                        growths[i] -= 100;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            ProcessUnusedGrowths(gainedStats, currentLevelStats, growths, unusedGrowth, uncappedStats);
        }
        protected virtual void ProcessUnusedGrowths(
            int[] gainedStats, int[] currentLevelStats, int[] growths,
            int unusedGrowth, int uncappedStats)
        {
            int maxBonus = MaxOverflowBonus();

            // Divide leftover growths among remaining stats
            if (unusedGrowth > 0 && uncappedStats > 0)
            {
                for (int i = 0; i < growths.Length; i++)
                {
                    bool statCapped = Actor.get_capped(
                        i, gainedStats[i] + currentLevelStats[i]);

                    if (!statCapped)
                    {
                        int bonus = Math.Min(maxBonus, (unusedGrowth / uncappedStats));
                        growths[i] += bonus * Game_Actor.GetStatRatio(i);
                    }
                }
            }
        }
        private void RollSemifixedGrowths(
            int[] growthRates,
            IEnumerable <int> stats,
            List <int> randomStatOrder,
            int multiplier)
        {
            // Skip if no stats to process
            if (!stats.Any())
            {
                return;
            }

            // Get totals
            float growthTotal = multiplier * stats
                                .Select(x => growthRates[x] / (float)Game_Actor.GetStatRatio(x))
                                .Sum();

            // Take the roll for each growth rate and get the difference
            var rolls = new List <Tuple <int, int> >();

            foreach (int j in stats)
            {
                rolls.Add(Tuple.Create(j,
                                       Rolls[j] - (multiplier * growthRates[j])));
            }
            // Sort by how far under the growth the roll was
            rolls.Sort(delegate(Tuple <int, int> a, Tuple <int, int> b)
            {
                int sortValue = a.Item2 - b.Item2;
                if (sortValue == 0)
                {
                    return(randomStatOrder.IndexOf(b.Item1));
                }
                return(sortValue);
            });

            // Go through stats in the order they beat the rng by
            while (growthTotal > 0 && rolls.Any())
            {
                int stat = rolls[0].Item1;
                rolls.RemoveAt(0);
                float value     = 1 / (float)Game_Actor.GetStatRatio(stat);
                float statWorth = value * 100;

                // IF the remaining points to gain are worth more than the current stat,
                // automatically grant the point
                if (growthTotal >= statWorth)
                {
                    StatGains[stat] += multiplier;
                    growthTotal     -= statWorth;
                }
                // Else roll for this stat, with the probability being the percentage
                // of a point remaining
                else
                {
                    if (Global.game_system.get_rng() < growthTotal / value)
                    {
                        StatGains[stat] += multiplier;
                    }
                    growthTotal = 0;
                }
            }
        }