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; } } }