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 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; }