-
Notifications
You must be signed in to change notification settings - Fork 13
/
FactorMultiplier.cs
126 lines (106 loc) · 4.24 KB
/
FactorMultiplier.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
using KSP.Localization;
using System;
namespace KerbalHealth
{
public class FactorMultiplier : IConfigNode
{
internal const string ConfigNodeName = "FACTOR_MULTIPLIER";
double freeMultiplier = 1;
public string FactorName
{
get => Factor?.Name ?? "All";
set => Factor = Core.GetHealthFactor(value);
}
public HealthFactor Factor { get; set; }
public double BonusSum { get; set; } = 0;
public double FreeMultiplier
{
get => freeMultiplier;
set
{
freeMultiplier = value;
if (MinMultiplier > value)
MinMultiplier = value;
else if (MaxMultiplier < value)
MaxMultiplier = value;
}
}
public double MinMultiplier { get; set; } = 1;
public double MaxMultiplier { get; set; } = 1;
/// <summary>
/// Final multiplier for this factor
/// </summary>
public double Multiplier => UtilMath.Clamp(FreeMultiplier * (1 - BonusSum), MinMultiplier, MaxMultiplier);
public bool IsTrivial =>
BonusSum == 0
&& FreeMultiplier == 1
&& MinMultiplier >= 1
&& MaxMultiplier <= 1;
public void Save(ConfigNode node)
{
if (Factor != null)
node.AddValue("multiplyFactor", FactorName);
if (BonusSum != 0)
node.AddValue("bonusSum", BonusSum);
if (FreeMultiplier != 1)
node.AddValue("multiplier", FreeMultiplier);
if (MinMultiplier < 1)
node.AddValue("minMultiplier", MinMultiplier);
if (MaxMultiplier > 1)
node.AddValue("maxMultiplier", MaxMultiplier);
}
public void Load(ConfigNode node)
{
FactorName = node.GetString("multiplyFactor");
BonusSum = node.GetDouble("bonusSum");
MinMultiplier = node.GetDouble("minMultiplier", 1);
MaxMultiplier = node.GetDouble("maxMultiplier", 1);
FreeMultiplier = node.GetDouble("multiplier", 1);
}
public FactorMultiplier(HealthFactor factor = null) => Factor = factor;
public FactorMultiplier(ConfigNode configNode) => Load(configNode);
/// <summary>
/// Combines two factor multipliers into one, adding bonus sums and multiplying their multipliers
/// </summary>
/// <param name="fm2"></param>
/// <returns></returns>
public static FactorMultiplier Combine(FactorMultiplier fm1, FactorMultiplier fm2) => new FactorMultiplier(fm1.Factor).CombineWith(fm2);
/// <summary>
/// Adds a free (i.e. not restricted by crew cap) multiplier
/// </summary>
/// <param name="multiplier"></param>
public void AddMultiplier(double multiplier)
{
FreeMultiplier *= multiplier;
if (multiplier < MinMultiplier)
MinMultiplier = multiplier;
else if (multiplier > MaxMultiplier)
MaxMultiplier = multiplier;
}
public void AddMultiplier(double multiplier, int crewCap, int crew)
{
BonusSum += Math.Abs(1 - multiplier) * crewCap / crew;
if (multiplier < MinMultiplier)
MinMultiplier = multiplier;
if (multiplier > MaxMultiplier)
MaxMultiplier = multiplier;
}
public FactorMultiplier CombineWith(FactorMultiplier fm)
{
if (Factor != fm.Factor)
{
Core.Log($"Could not combine {FactorName} and {fm.FactorName} multipliers.", LogLevel.Error);
return this;
}
BonusSum += fm.BonusSum;
MinMultiplier = Math.Min(MinMultiplier, fm.MinMultiplier);
MaxMultiplier = Math.Max(MaxMultiplier, fm.MaxMultiplier);
FreeMultiplier *= fm.FreeMultiplier;
return this;
}
public override string ToString() =>
IsTrivial
? string.Empty
: Localizer.Format("#KH_FactorMultiplier_desc", Factor?.Name ?? Localizer.Format("#KH_FactorMultiplier_All"), Multiplier.ToString("P0"));
}
}