private IReadOnlyCollection <PathDefinition> GetPaths(IValueCalculationContext context, IStat stat)
        {
            if (!_target.Equals(stat))
            {
                return(context.GetPaths(stat));
            }

            var originalPaths   = context.GetPaths(_target);
            var conversionPaths = context.GetPaths(_source)
                                  .Select(p => new PathDefinition(p.ModifierSource, p.ConversionStats.Prepend(_source).ToArray()));
            var paths = new HashSet <PathDefinition>(originalPaths);

            paths.UnionWith(conversionPaths);
            return(paths);
        }
示例#2
0
        public NodeValue?Calculate(IValueCalculationContext context)
        {
            if (context.GetValue(_stat, NodeType.BaseOverride, _path) is NodeValue baseOverride)
            {
                return(baseOverride);
            }

            if (context.GetValue(_stat, NodeType.BaseSet, _path) is NodeValue baseSet)
            {
                var baseAdd = context.GetValue(_stat, NodeType.BaseAdd, _path) ?? new NodeValue(0);
                return(baseSet + baseAdd);
            }

            return(context.GetValue(_stat, NodeType.BaseAdd, _path));
        }
        private NodeValue?Calculate(IValueCalculationContext context, NodeValue value)
        {
            if (Stat.Minimum != null)
            {
                var minimum = context.GetValue(Stat.Minimum) ?? new NodeValue(double.MinValue);
                value = NodeValue.Combine(value, minimum, Math.Max);
            }

            if (Stat.Maximum != null)
            {
                var maximum = context.GetValue(Stat.Maximum) ?? new NodeValue(double.MaxValue);
                value = NodeValue.Combine(value, maximum, Math.Min);
            }

            return(value);
        }
        private IReadOnlyCollection <PathDefinition> GetPaths(IValueCalculationContext context, IStat stat)
        {
            var originalPaths = context.GetPaths(stat);

            if (!_ailmentDamage.Equals(stat))
            {
                return(originalPaths);
            }

            var skillPaths = context.GetPaths(_skillDamage)
                             .Select(p => new PathDefinition(p.ModifierSource));
            var paths = new HashSet <PathDefinition>(originalPaths);

            paths.UnionWith(skillPaths);
            return(paths);
        }
        private NodeValue?GetValues(
            IValueCalculationContext context, IStat stat, NodeType nodeType, PathDefinition path)
        {
            var originalValue = context.GetValue(stat, nodeType, path);

            if (nodeType != NodeType.BaseAdd && nodeType != NodeType.BaseSet)
            {
                return(originalValue);
            }
            if (!stat.Equals(_transformedStat))
            {
                return(originalValue);
            }

            var effectivenessStat =
                nodeType == NodeType.BaseSet ? _baseSetEffectivenessStat : _baseAddEffectivenessStat;
            var effectiveness = context.GetValue(effectivenessStat) ?? new NodeValue(1);

            return(originalValue * effectiveness);
        }
        GetValue(IValueCalculationContext context, IStat stat, NodeType nodeType, PathDefinition path)
        {
            var value = context.GetValue(stat, nodeType, path);

            if (value is null || !_convertTo.Equals(stat) || nodeType != NodeType.PathTotal)
            {
                return(value);
            }

            var sourceConversion = context.GetValue(_conversion) ?? new NodeValue(0);

            if (sourceConversion <= 100)
            {
                // Conversions don't exceed 100%, No scaling required
                return(value);
            }

            var isSkillPath           = path.ModifierSource is ModifierSource.Local.Skill;
            var sourceSkillConversion = context.GetValue(_skillConversion) ?? new NodeValue(0);

            if (sourceSkillConversion >= 100)
            {
                // Conversions from skills are or exceed 100%
                // Non-skill conversions don't apply
                if (!isSkillPath)
                {
                    return(new NodeValue(0));
                }
                // Skill conversions are scaled to sum to 100%
                return(value / sourceSkillConversion * 100);
            }

            // Conversions exceed 100%
            // Skill conversions don't scale (they themselves don't exceed 100%)
            if (isSkillPath)
            {
                return(value);
            }
            // Non-skill conversions are scaled to sum to 100% - skill conversions
            return(value * (100 - sourceSkillConversion) / (sourceConversion - sourceSkillConversion));
        }
示例#7
0
        public NodeValue?Calculate(IValueCalculationContext context)
        {
            var uncapped = context.GetValue(_stat, NodeType.UncappedSubtotal);

            if (uncapped is null)
            {
                return(null);
            }

            var uncappedV = uncapped.Value;

            if (uncappedV == 0)
            {
                return(new NodeValue(0));
            }

            var min = _stat.Minimum is null ? null : context.GetValue(_stat.Minimum);
            var max = _stat.Maximum is null ? null : context.GetValue(_stat.Maximum);

            return(Min(Max(uncappedV, min), max));
        }
示例#8
0
 public NodeValue?Calculate(IValueCalculationContext valueCalculationContext) =>
 _multiplier * (valueCalculationContext.GetValue(_stat) / _divisor).Select(Math.Ceiling);
示例#9
0
 public static void AssertCorrectModifiers(
     IValueCalculationContext context,
     (string stat, Form form, NodeValue? value, ModifierSource source)[] expectedModifiers,
 public static NodeValue?GetValue(
     this IValueCalculationContext context, IStat stat, NodeType nodeType = NodeType.Total)
 => context.GetValue(stat, nodeType, PathDefinition.MainPath);
示例#11
0
 GetValues(IValueCalculationContext context, Form form, IEnumerable <(IStat stat, PathDefinition path)> paths)
 public NodeValue?Calculate(IValueCalculationContext context)
 => throw new AssertionException("Expected value not to be calculated");
示例#13
0
 public ModifiedContext(IStat barSkillConversion, IValueCalculationContext originalContext)
 {
     _barSkillConversion = barSkillConversion;
     _originalContext    = originalContext;
 }
示例#14
0
        public NodeValue?Calculate(IValueCalculationContext context)
        {
            var modifiedContext = new ModifiedContext(_barSkillConversion, context);

            return(_transformedValue.Calculate(modifiedContext));
        }
示例#15
0
 public ModifiedContext(IStat foo, IStat bar, IValueCalculationContext originalContext)
 {
     _foo             = foo;
     _bar             = bar;
     _originalContext = originalContext;
 }
示例#16
0
        public NodeValue?Calculate(IValueCalculationContext context)
        {
            var value = _transformedValue.Calculate(context);

            return(value.Select(d => Math.Round(d, _decimals)));
        }
 public static List <NodeValue?> GetValues(
     this IValueCalculationContext context, Form form, IStat stat, PathDefinition path)
 => context.GetValues(form, new[] { (stat, path) });
 public static List <NodeValue?> GetValues(
     this IValueCalculationContext context, Form form, IStat stat)
 => context.GetValues(form, stat, PathDefinition.MainPath);
示例#19
0
 public override NodeValue?Calculate(IValueCalculationContext context) =>
 _values.Select(v => v.Calculate(context))
 .Select(v => new NodeValue(v.IsTrue() ? 1 : 0))
 .DefaultIfEmpty()
 .Aggregate((l, r) => l + r);
示例#20
0
 public NodeValue?Calculate(IValueCalculationContext valueCalculationContext)
 {
     throw new NotImplementedException();
 }
 public NodeValue?Calculate(IValueCalculationContext context) =>
 context.GetValue(_stat, NodeType.TotalOverride) ?? context.GetValue(_stat, NodeType.Subtotal);
 public NodeValue?Calculate(IValueCalculationContext valueCalculationContext) =>
 _value.Calculate(valueCalculationContext);
示例#23
0
 /// <summary>
 /// Returns the values of the nodes of all paths of the given type in the given stat's subgraph.
 /// </summary>
 public static IEnumerable <NodeValue?> GetValues(
     this IValueCalculationContext context, IStat stat, NodeType nodeType) =>
 context.GetPaths(stat).Select(p => context.GetValue(stat, nodeType, p));
        public NodeValue?Calculate(IValueCalculationContext context)
        {
            var modifiedContext = new ModifiedValueCalculationContext(context, getValue: GetValues);

            return(_transformedValue.Calculate(modifiedContext));
        }
示例#25
0
        public NodeValue?Calculate(IValueCalculationContext valueCalculationContext)
        {
            var path = new PathDefinition(_path.ModifierSource, _path.ConversionStats.Skip(1).ToArray());

            return(valueCalculationContext.GetValue(_path.ConversionStats[0], NodeType.Base, path));
        }
示例#26
0
 public static IEnumerable <NodeValue?> Calculate(
     this IEnumerable <IValue> @this, IValueCalculationContext context)
 => @this.Select(v => v.Calculate(context));
 public NodeValue?Calculate(IValueCalculationContext valueCalculationContext) =>
 _aggregator(valueCalculationContext.GetValues(_form, _stat, _path));