Exemplo n.º 1
0
        /// </inheritdoc>
        public double?RollStatistic(Statistic stat, Character character, bool useEffects = false)
        {
            StatisticValue sv = character?.GetStatistic(stat, useEffects);

            if (character == null || sv == null)
            {
                return(null);
            }

            int    rng = GameRandom.Between(1, 100);
            double maxSuccessRoll;

            int statNum = sv.Value;

            if (statNum <= 0)
            {
                return(-999);
            }

            if (stat is Attribute)
            {
                maxSuccessRoll = Math.Round(32.2 * Math.Sqrt(statNum) - 7);
            }
            else
            {
                maxSuccessRoll = Math.Round(10 * Math.Sqrt(statNum) - 0.225 * statNum - 1);
            }

            Attribute luckStat       = character.Statistics.Select(x => x.Statistic).OfType <Attribute>().FirstOrDefault(x => x.Aliases.ContainsIgnoreCase("luck"));
            double    luckInfluence  = 1.0;
            int       luckDifference = 0;

            if (luckStat != null)
            {
                // each point of LCK above/below 5 prolly shoulda been +/-1% flat chance max
                // Do that, but ALSO make each point in luck a +/-0.1% chance for  mega crit

                int luckValue = character.GetStatistic(luckStat, useEffects).Value;
                luckDifference = luckValue - 5;

                luckInfluence  += luckDifference * 0.01;
                maxSuccessRoll *= luckInfluence;
            }

            maxSuccessRoll = Math.Min(maxSuccessRoll, HIGHEST_MAX_SUCCESS_ROLL);

            double resultPercent = (maxSuccessRoll - rng) / maxSuccessRoll;

            int critRng = GameRandom.Between(1, 1000);

            // Success
            if (resultPercent >= 0)
            {
                double maxCritSuccessRoll = 1 + (1 * luckDifference);

                // Minimum 1, maximum 10
                maxCritSuccessRoll = Math.Max(1, Math.Min(maxCritSuccessRoll, 10));

                if (critRng <= maxCritSuccessRoll)
                {
                    return(999);
                }
            }
            // Failure
            else
            {
                double maxCritFailRoll = 6 - (1 * luckDifference);
                maxCritFailRoll = Math.Min(maxCritFailRoll, 10);

                if (critRng <= maxCritFailRoll)
                {
                    return(-999);
                }
            }

            return(Math.Round(resultPercent * 100.0, 1));
        }