Beispiel #1
0
        /// <summary> Applies a single stat to the result. </summary>
        /// <param name="state"> Current state object </param>
        /// <param name="stat"> Stat to apply </param>
        /// <param name="statValue"> Value to apply to stat </param>
        /// <param name="randomizer"> Function to use to generate random values </param>
        /// <param name="scaler"> Function to use to scale appleied values </param>
        /// <param name="rollGroup"> History of rolls to use, or record to. </param>
        private void ApplyStat(State state, string stat, JsonValue statValue, StatTableEntry entry, JsonObject rollGroup)
        {
            if (rollGroup.Has(stat))
            {
                // Roll already exists? Replay calculation only.

                if (statValue.isNumber)
                {
                    state.result[stat] = entry.applier(state.result.Get <double>(stat), entry.scaler(state, statValue * rollGroup.Get <double>(stat)));
                }
                else if (statValue.isArray)
                {
                    var a = statValue[0].doubleVal;
                    var b = statValue[1].doubleVal;
                    state.result[stat] = entry.applier(state.result.Get <double>(stat), entry.scaler(state, a + (b - a) * rollGroup.Get <double>(stat)));
                }
            }
            else
            {
                // Roll does not exist? Roll and calculate.
                var roll = entry.randomizer(state);
                if (statValue.isNumber)
                {
                    state.result[stat] = entry.applier(state.result.Get <double>(stat), entry.scaler(state, statValue * roll));
                }
                else if (statValue.isArray)
                {
                    var a = statValue[0].doubleVal;
                    var b = statValue[1].doubleVal;
                    state.result[stat] = entry.applier(state.result.Get <double>(stat), entry.scaler(state, a + (b - a) * roll));
                }

                rollGroup[stat] = roll;
            }
        }
Beispiel #2
0
        /// <summary> Apply a stat group to the result </summary>
        /// <param name="state"> Current generator state </param>
        /// <param name="rule"> Rule object </param>
        /// <param name="group"> Name of stat group to apply </param>
        /// <param name="rolls"> History of rolls to use, or record to. </param>
        private void ApplyStatGroup(State state, JsonObject rule, string group, JsonObject rolls)
        {
            StatTableEntry entry = statGroupTable[group];
            JsonObject     stats = rule.Get <JsonObject>(group);

            if (stats != null)
            {
                if (!rolls.Has(group))
                {
                    rolls[group] = new JsonObject();
                }
                var rollGroup = rolls.Get <JsonObject>(group);

                foreach (var pair in stats)
                {
                    string key = pair.Key;
                    var    val = pair.Value;

                    var setCheck = FindRule(key);
                    if (setCheck != null && setCheck.isObject)
                    {
                        foreach (var pair2 in setCheck)
                        {
                            var stat = pair2.Key;
                            ApplyStat(state, stat, val, entry, rollGroup);
                        }
                    }
                    else
                    {
                        ApplyStat(state, key, val, entry, rollGroup);
                    }
                }
            }
        }
Beispiel #3
0
 public StatTableEntry(StatTableEntry other)
 {
     this.randomizer = other.randomizer;
     this.scaler     = other.scaler;
     this.applier    = other.applier;
 }
Beispiel #4
0
        /// <summary> Function that bakes stat group table </summary>
        /// <returns> Baked stat group table </returns>
        private static Dictionary <string, StatTableEntry> BuildStatTable()
        {
            Dictionary <string, StatTableEntry> table = new Dictionary <string, StatTableEntry>();

            // Randomizers
            // stat (1.0 always)
            double stat(State state)
            {
                return(1.0);
            }

            // rand [0, 1)
            double rand(State state)
            {
                return(state.NextRand());
            }

            // normal (approximate) in [0, 1), with .5 avg
            double norm(State state)
            {
                return(state.NextNorm());
            }

            // Scalers
            // normal scaling (v*scale)
            double mscale(State state, double v)
            {
                return(v * state.scale);
            }

            // divisor scaling (v/scale)
            double dscale(State state, double v)
            {
                return(v / state.scale);
            }

            // power scaling (v^scale)
            double pscale(State state, double v)
            {
                return(Math.Pow(v, state.scale));
            }

            // fixed scaling (v)
            double f(State state, double v)
            {
                return(v);
            }

            // fixed sqrt scaling (sqrt(v))
            double sqrt(State state, double v)
            {
                return(Math.Sqrt(v));
            }

            // Add
            double add(double x, double y)
            {
                return(x + y);
            }

            // Subtract
            double sub(double x, double y)
            {
                return(x - y);
            }

            // Multiply
            double mult(double x, double y)
            {
                return(x * y);
            }

            // Divide
            double div(double x, double y)
            {
                return(x / y);
            }

            // power
            double pow(double x, double y)
            {
                return(Math.Pow(x, y));
            }

            // combine Ratios (eg, (.5,.5) => .75, (.6, .5) => .8
            double ratio(double x, double y)
            {
                return(OM(OM(x) * OM(y)));
            }

            double Clamp01(double v)
            {
                return(v < 0 ? 0 : v > 1 ? 1 : v);
            }

            double OM(double v)
            {
                return(1.0 - Clamp01(v));
            }                                                            // One Minus

            StatTableEntry baseEntry = new StatTableEntry(stat, mscale, add);

            table[nameof(stat)] = new StatTableEntry(baseEntry);
            table[nameof(rand)] = new StatTableEntry(baseEntry); table[nameof(rand)].randomizer = rand;
            table[nameof(norm)] = new StatTableEntry(baseEntry); table[nameof(norm)].randomizer = norm;

            Func <State, double, double>[] scalers = new Func <State, double, double>[] { mscale, dscale, pscale, f, sqrt };
            string[] scalerNs = new string[] { nameof(mscale), nameof(dscale), nameof(pscale), nameof(f), nameof(sqrt), };

            Func <double, double, double>[] appliers = new Func <double, double, double>[] { add, sub, mult, div, ratio, pow };
            string[] applierNs = new string[] { nameof(add), nameof(sub), nameof(mult), nameof(div), nameof(ratio), nameof(pow) };

            var keys = new List <string>();

            keys.Clear(); keys.AddRange(table.Keys);
            foreach (var key in keys)
            {
                var entry = table[key];
                for (int i = 0; i < scalers.Length; i++)
                {
                    string dkey = scalerNs[i] + key;
                    var    copy = new StatTableEntry(entry);
                    copy.scaler = scalers[i];
                    table[dkey] = copy;
                }
            }

            keys.Clear(); keys.AddRange(table.Keys);
            foreach (var key in keys)
            {
                var entry = table[key];
                for (int i = 0; i < appliers.Length; i++)
                {
                    string dkey = applierNs[i] + key;
                    var    copy = new StatTableEntry(entry);
                    copy.applier = appliers[i];
                    table[dkey]  = copy;
                }
            }

            return(table);
        }