Example #1
0
        protected override long EvaluateInternal(RollData data, DiceAST root, int depth)
        {
            long rolls = Expression.Evaluate(data, root, depth + 1);

            rolls += Critical?.Evaluate(data, root, depth + 1) ?? 0;
            rolls += Fumble?.Evaluate(data, root, depth + 1) ?? 0;
            MarkCrits();

            return(rolls);
        }
Example #2
0
        internal void AddFumble(ComparisonNode comp)
        {
            if (comp == null)
            {
                return;
            }

            if (Fumble == null)
            {
                Fumble = comp;
            }
            else
            {
                Fumble.Add(comp);
            }
        }
Example #3
0
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder(Expression?.ToString() ?? String.Empty);

            if (Critical != null)
            {
                sb.AppendFormat(".critical({0})", Critical.ToString());
            }

            if (Fumble != null)
            {
                sb.AppendFormat(".fumble({0})", Fumble.ToString());
            }

            return(sb.ToString());
        }
Example #4
0
        private void MarkCrits()
        {
            Value     = Expression.Value;
            ValueType = Expression.ValueType;
            _values.Clear();
            DieFlags mask = 0;

            if (Critical != null)
            {
                mask |= DieFlags.Critical;
            }

            if (Fumble != null)
            {
                mask |= DieFlags.Fumble;
            }

            foreach (var die in Expression.Values)
            {
                DieFlags flags = 0;

                if (die.DieType == DieType.Special || die.DieType == DieType.Group)
                {
                    // we don't skip over dropped dice here since we DO still want to
                    // mark them as criticals/fumbles as needed.
                    _values.Add(die);
                    continue;
                }

                if (Critical?.Compare(die.Value) == true)
                {
                    flags |= DieFlags.Critical;

                    // if tracking successes; a critical success is worth 2 successes
                    if (ValueType == ResultType.Successes)
                    {
                        // just in case the die wasn't already marked as a success
                        if ((die.Flags & DieFlags.Success) == 0)
                        {
                            flags |= DieFlags.Success;
                            Value++;
                        }

                        Value++;
                    }
                }

                if (Fumble?.Compare(die.Value) == true)
                {
                    flags |= DieFlags.Fumble;

                    // if tracking failures; a critical failure is worth -2 successes
                    if (ValueType == ResultType.Successes)
                    {
                        // just in case the die wasn't already marked as a failure
                        if ((die.Flags & DieFlags.Failure) == 0)
                        {
                            flags |= DieFlags.Failure;
                            Value--;
                        }

                        Value--;
                    }
                }

                _values.Add(new DieResult()
                {
                    DieType  = die.DieType,
                    NumSides = die.NumSides,
                    Value    = die.Value,
                    // strip any existing crit/fumble flag off and use ours,
                    // assuming a comparison was defined for it.
                    // (we may have an existing flag if the die rolled min or max value)
                    Flags = (die.Flags & ~mask) | flags
                });
            }
        }