-
Notifications
You must be signed in to change notification settings - Fork 754
/
ToolStatsBuilder.java
118 lines (107 loc) · 4.54 KB
/
ToolStatsBuilder.java
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
package slimeknights.tconstruct.library.tools.stat;
import com.google.common.collect.ImmutableList;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import slimeknights.tconstruct.library.materials.MaterialRegistry;
import slimeknights.tconstruct.library.materials.definition.MaterialId;
import slimeknights.tconstruct.library.materials.stats.IMaterialStats;
import slimeknights.tconstruct.library.materials.stats.MaterialStatsId;
import slimeknights.tconstruct.library.tools.definition.module.material.ToolMaterialHook.WeightedStatType;
import slimeknights.tconstruct.library.tools.nbt.MaterialNBT;
import javax.annotation.Nullable;
import java.util.List;
import java.util.function.Function;
/**
* Extendable utilities for a stats builder.
* <p>
* It's encouraged to extend this for the base of your calculation. Using this class directly will give a no parts stat builder
*/
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class ToolStatsBuilder {
/**
* Called after bonuses are processed to set the unique stats for this builder.
* @param builder Stats builder
*/
public abstract void addStats(ModifierStatsBuilder builder);
/** Gets the given stat, returning a default if its missing instead of the stat's default */
@SuppressWarnings("SameParameterValue")
protected <T extends Number> T getStatOrDefault(IToolStat<T> stat, T defaultValue) {
return defaultValue;
}
/* Helpers */
/**
* Fetches the given stat from the material, getting the default stats if missing
* @param material Material type
* @param statsId Stat type
* @param <T> Stat type
* @return Stat, or default if the part type accepts it, null if the part type does not
*/
@Nullable
public static <T extends IMaterialStats> T fetchStatsOrDefault(MaterialId material, MaterialStatsId statsId) {
return MaterialRegistry.getInstance().<T>getMaterialStats(material, statsId)
.orElseGet(() -> MaterialRegistry.getInstance().getDefaultStats(statsId));
}
/**
* Gets a list of all stats for the given part type
* @param statsId Stat type
* @param materials Materials list
* @param statTypes List of required components, filters stat types
* @param <T> Type of stats
* @return List of stats
*/
public static <T extends IMaterialStats> List<T> listOfCompatibleWith(MaterialStatsId statsId, MaterialNBT materials, List<WeightedStatType> statTypes) {
ImmutableList.Builder<T> builder = ImmutableList.builder();
// iterating both lists at once, precondition that they have the same size
int size = statTypes.size();
for (int i = 0; i < size; i++) {
// ensure stat type is valid
WeightedStatType statType = statTypes.get(i);
if (statType.stat().equals(statsId)) {
T stats = fetchStatsOrDefault(materials.get(i).getId(), statType.stat());
if (stats != null) {
// add a copy of the stat once per weight, lazy way to do weighting
for (int w = 0; w < statType.weight(); w++) {
builder.add(stats);
}
}
}
}
return builder.build();
}
/**
* Gets the average value from a list of stat types
* @param stats Stat list
* @param statGetter Function to get the value
* @param <T> Material type
* @return Average value
*/
public static <T extends IMaterialStats> float getAverageValue(List<T> stats, Function<T, ? extends Number> statGetter) {
return getAverageValue(stats, statGetter, 0);
}
/**
* Gets the average value from a list of stat types
* @param stats Stat list
* @param statGetter Function to get the value
* @param missingValue Default value to use for missing stats
* @param <T> Material type
* @return Average value
*/
public static <T extends IMaterialStats, N extends Number> float getAverageValue(List<T> stats, Function<T, N> statGetter, double missingValue) {
return (float)stats.stream()
.mapToDouble(value -> statGetter.apply(value).doubleValue())
.average()
.orElse(missingValue);
}
/**
* Gets the average value from a list of stat types
* @param stats Stat list
* @param statGetter Function to get the value
* @param <T> Material type
* @return Average value
*/
public static <T extends IMaterialStats, N extends Number> float getTotalValue(List<T> stats, Function<T, N> statGetter) {
return (float)stats.stream()
.mapToDouble(value -> statGetter.apply(value).doubleValue())
.sum();
}
}