public BaseStatsDictionary AddPercent(IProtoEntity source, StatName statName, double percent) { if (percent == 0) { return(this); } var multiplier = percent / 100d; // simply sum multipliers (like values) if (multiplier == 0) { return(this); } StatsSources.RegisterPercent(ref this.sources, source, statName, percent); if (this.Multipliers.TryGetValue(statName, out var currentMultiplier)) { // simply sum with existing value multiplier += currentMultiplier; } else { // non-existing multiplier - add base multiplier (one) multiplier += 1; } this.ValidateIsNotReadOnly(); this.Multipliers[statName] = multiplier; return(this); }
public static void RegisterValue( ref StatsSources stats, IProtoEntity source, StatName statName, double value) { stats = stats.AddOrUpdate(source, statName, value, percent: 0); }
public static void RegisterPercent( ref StatsSources stats, IProtoEntity source, StatName statName, double percent) { stats = stats.AddOrUpdate(source, statName, value: 0, percent: percent); }
private FinalStatsCache( IDictionary <StatName, double> dictionaryFinalValues, IDictionary <StatName, double> dictionaryMultipliers, StatsSources sources, bool isClean) : this(dictionaryFinalValues, dictionaryMultipliers, sources) { this.isClean = isClean; }
public FinalStatsCache( IDictionary <StatName, double> dictionaryFinalValues, IDictionary <StatName, double> dictionaryMultipliers, StatsSources sources) { this.dictionaryFinalValues = dictionaryFinalValues; this.dictionaryMultipliers = dictionaryMultipliers; this.Sources = sources; this.isClean = true; }
public void Merge(IReadOnlyStatsDictionary otherStatsCache) { this.ValidateIsNotReadOnly(); this.Merge( this.Values, otherStatsCache.Values, isMultipliers: false); this.Merge( this.Multipliers, otherStatsCache.Multipliers, isMultipliers: true); StatsSources.Merge(ref this.sources, otherStatsCache.Sources); }
public static void Merge(ref StatsSources current, StatsSources other) { if (other.list is null) { return; } if (current.list is null) { current.list = other.List.ToList(); } else { current.list.AddRange(other.list); } }
public void AddValue(IProtoEntity source, StatName statName, double value) { if (value == 0d) { return; } StatsSources.RegisterValue(ref this.sources, source, statName, value); if (this.Values.TryGetValue(statName, out var currentValue)) { // simply sum with existing value value += currentValue; } this.ValidateIsNotReadOnly(); this.Values[statName] = value; }
public void Merge(IReadOnlyStatsDictionary otherStatsCache) { this.ValidateIsNotReadOnly(); // values are merged via sum this.Merge( this.Values, otherStatsCache.Values, isMultiplied: false); // multipliers are merged via multiplication this.Merge( this.Multipliers, otherStatsCache.Multipliers, isMultiplied: !this.IsMultipliersSummed); StatsSources.Merge(ref this.sources, otherStatsCache.Sources); }
public void AddPercent(IProtoEntity source, StatName statName, double percent) { if (percent == 0d) { return; } var multiplier = percent / 100d; if (this.IsMultipliersSummed) { // simply sum multipliers (like values) if (multiplier == 0) { return; } StatsSources.RegisterPercent(ref this.sources, source, statName, percent); if (this.Multipliers.TryGetValue(statName, out var currentMultiplier)) { // simply sum with existing value multiplier += currentMultiplier; } else { // non-existing multiplier - add base multiplier (one) multiplier += 1; } } else { if (multiplier <= -1) { // -100% or lower - wow! StatsSources.RegisterPercent(ref this.sources, source, statName, -100); this.Multipliers[statName] = 0; return; } StatsSources.RegisterPercent(ref this.sources, source, statName, percent); multiplier += 1; if (this.Multipliers.TryGetValue(statName, out var currentMultiplier)) { // Simply multiply multipliers. // We're doing this to avoid case when -50% + -50% = -100% // as it could broke the game in some cases (like movement speed). // But if percent is provided as -100%, then it will be converted to multiplier==0 // so we still can reset some stats to 0 by using percent effects. if (currentMultiplier == 0d) { // early return - the final multiplier also will be 0 and nothing changes return; } multiplier *= currentMultiplier; } } this.ValidateIsNotReadOnly(); this.Multipliers[statName] = multiplier; }