-
Notifications
You must be signed in to change notification settings - Fork 754
/
PartStatsModule.java
118 lines (98 loc) · 4.22 KB
/
PartStatsModule.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.definition.module.material;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import slimeknights.mantle.data.loadable.primitive.IntLoadable;
import slimeknights.mantle.data.loadable.record.RecordLoadable;
import slimeknights.tconstruct.library.json.TinkerLoadables;
import slimeknights.tconstruct.library.module.ModuleHook;
import slimeknights.tconstruct.library.module.HookProvider;
import slimeknights.tconstruct.library.tools.definition.ToolDefinition;
import slimeknights.tconstruct.library.tools.definition.module.ToolHooks;
import slimeknights.tconstruct.library.tools.part.IToolPart;
import slimeknights.tconstruct.library.tools.stat.MaterialStatProvider;
import slimeknights.tconstruct.library.tools.stat.MaterialStatProviders;
import java.util.List;
import java.util.function.Supplier;
/** Tool using tool parts for its material stats, allows part swapping and tool building */
public class PartStatsModule extends MaterialStatsModule implements ToolPartsHook {
private static final List<ModuleHook<?>> DEFAULT_HOOKS = HookProvider.<PartStatsModule>defaultHooks(ToolHooks.TOOL_STATS, ToolHooks.TOOL_TRAITS, ToolHooks.TOOL_MATERIALS, ToolHooks.TOOL_PARTS, ToolHooks.MATERIAL_REPAIR);
public static final RecordLoadable<PartStatsModule> LOADER = RecordLoadable.create(
STAT_PROVIDER_FIELD,
WeightedPart.LOADABLE.list(1).requiredField("parts", m -> m.parts),
PartStatsModule::new).validate((module, error) -> {
module.validate(error);
return module;
});
/** Parts for serializing */
@VisibleForTesting
@Getter
private final List<WeightedPart> parts;
/*** Flattened parts for the hook */
private final List<IToolPart> flatParts;
public PartStatsModule(MaterialStatProvider statProvider, List<WeightedPart> parts) {
super(statProvider, parts.stream().map(part -> new WeightedStatType(part.part.getStatType(), part.weight)).toList());
this.parts = parts;
this.flatParts = parts.stream().map(WeightedPart::part).toList();
}
@Override
public RecordLoadable<PartStatsModule> getLoader() {
return LOADER;
}
@Override
public List<ModuleHook<?>> getDefaultHooks() {
return DEFAULT_HOOKS;
}
@Override
public List<IToolPart> getParts(ToolDefinition definition) {
return flatParts;
}
/** Stat with weights */
@VisibleForTesting
public record WeightedPart(IToolPart part, int weight) {
public static final RecordLoadable<WeightedPart> LOADABLE = RecordLoadable.create(
TinkerLoadables.TOOL_PART_ITEM.requiredField("item", WeightedPart::part),
IntLoadable.FROM_ONE.defaultField("weight", 1, WeightedPart::weight),
WeightedPart::new).compact(TinkerLoadables.TOOL_PART_ITEM.flatXmap(item -> new WeightedPart(item, 1), WeightedPart::part), s -> s.weight == 1);
}
/* Builder */
public static Builder parts(MaterialStatProvider statProvider) {
return new Builder(statProvider);
}
/** Starts a builder for melee harvest stats */
public static Builder meleeHarvest() {
return parts(MaterialStatProviders.MELEE_HARVEST);
}
/** Starts a builder for ranged stats */
public static Builder ranged() {
return parts(MaterialStatProviders.RANGED);
}
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public static class Builder {
private final ImmutableList.Builder<WeightedPart> parts = ImmutableList.builder();
private final MaterialStatProvider statProvider;
/** Adds a part to the builder */
public Builder part(IToolPart part, int weight) {
parts.add(new WeightedPart(part, weight));
return this;
}
/** Adds a part to the builder */
public Builder part(Supplier<? extends IToolPart> part, int weight) {
return part(part.get(), weight);
}
/** Adds a part to the builder */
public Builder part(IToolPart part) {
return part(part, 1);
}
/** Adds a part to the builder */
public Builder part(Supplier<? extends IToolPart> part) {
return part(part, 1);
}
/** Builds the module */
public PartStatsModule build() {
return new PartStatsModule(statProvider, parts.build());
}
}
}