/
AttributeModule.java
116 lines (101 loc) · 4.88 KB
/
AttributeModule.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
package slimeknights.tconstruct.library.modifiers.modules.behavior;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.AttributeModifier.Operation;
import slimeknights.mantle.data.loadable.Loadables;
import slimeknights.mantle.data.loadable.primitive.StringLoadable;
import slimeknights.mantle.data.loadable.record.RecordLoadable;
import slimeknights.mantle.data.registry.GenericLoaderRegistry.IGenericLoader;
import slimeknights.tconstruct.library.json.LevelingValue;
import slimeknights.tconstruct.library.json.TinkerLoadables;
import slimeknights.tconstruct.library.modifiers.ModifierEntry;
import slimeknights.tconstruct.library.modifiers.ModifierHook;
import slimeknights.tconstruct.library.modifiers.TinkerHooks;
import slimeknights.tconstruct.library.modifiers.hook.behavior.AttributesModifierHook;
import slimeknights.tconstruct.library.modifiers.modules.AttributeModuleBuilder;
import slimeknights.tconstruct.library.modifiers.modules.ModifierModule;
import slimeknights.tconstruct.library.modifiers.modules.ModifierModuleCondition;
import slimeknights.tconstruct.library.modifiers.modules.ModifierModuleCondition.ConditionalModifierModule;
import slimeknights.tconstruct.library.tools.nbt.IToolStackView;
import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.function.BiConsumer;
/**
* Module to add an attribute to a tool
*/
public record AttributeModule(String unique, Attribute attribute, Operation operation, LevelingValue amount, UUID[] slotUUIDs, ModifierModuleCondition condition) implements AttributesModifierHook, ModifierModule, ConditionalModifierModule {
private static final List<ModifierHook<?>> DEFAULT_HOOKS = List.of(TinkerHooks.ATTRIBUTES);
public static final RecordLoadable<AttributeModule> LOADER = RecordLoadable.create(
StringLoadable.DEFAULT.field("unique", AttributeModule::unique),
Loadables.ATTRIBUTE.field("attribute", AttributeModule::attribute),
TinkerLoadables.OPERATION.field("operation", AttributeModule::operation),
LevelingValue.LOADABLE.directField(AttributeModule::amount),
TinkerLoadables.EQUIPMENT_SLOT_SET.field("slots", m -> uuidsToSlots(m.slotUUIDs)),
ModifierModuleCondition.FIELD,
(unique, attribute, operation, amount, slots, condition) -> new AttributeModule(unique, attribute, operation, amount, slotsToUUIDs(unique, slots), condition));
/** Gets the UUID from a name */
public static UUID getUUID(String name, EquipmentSlot slot) {
return UUID.nameUUIDFromBytes((name + "." + slot.getName()).getBytes());
}
/** Converts a list of slots to an array of UUIDs at each index */
public static UUID[] slotsToUUIDs(String name, Collection<EquipmentSlot> slots) {
UUID[] slotUUIDs = new UUID[6];
for (EquipmentSlot slot : slots) {
slotUUIDs[slot.getFilterFlag()] = getUUID(name, slot);
}
return slotUUIDs;
}
/** Maps the UUID array to a set for serializing */
public static Set<EquipmentSlot> uuidsToSlots(UUID[] uuids) {
Set<EquipmentSlot> set = EnumSet.noneOf(EquipmentSlot.class);
for (EquipmentSlot slot : EquipmentSlot.values()) {
if (uuids[slot.getFilterFlag()] != null) {
set.add(slot);
}
}
return set;
}
@Override
public void addAttributes(IToolStackView tool, ModifierEntry modifier, EquipmentSlot slot, BiConsumer<Attribute,AttributeModifier> consumer) {
if (condition.matches(tool, modifier)) {
UUID uuid = slotUUIDs[slot.getFilterFlag()];
if (uuid != null) {
consumer.accept(attribute, new AttributeModifier(uuid, unique + "." + slot.getName(), amount.compute(tool, modifier), operation));
}
}
}
@Override
public List<ModifierHook<?>> getDefaultHooks() {
return DEFAULT_HOOKS;
}
@Override
public IGenericLoader<? extends ModifierModule> getLoader() {
return LOADER;
}
/** Creates a new builder instance */
public static Builder builder(Attribute attribute, Operation operation) {
return new Builder(attribute, operation);
}
public static class Builder extends AttributeModuleBuilder<Builder,AttributeModule> {
private EquipmentSlot[] slots = EquipmentSlot.values();
protected Builder(Attribute attribute, Operation operation) {
super(attribute, operation);
}
/** Adds the given slots to this builder */
public Builder slots(EquipmentSlot... slots) {
this.slots = slots;
return this;
}
@Override
public AttributeModule amount(float flat, float eachLevel) {
if (unique == null) {
throw new IllegalStateException("Must set unique for attributes");
}
return new AttributeModule(unique, attribute, operation, new LevelingValue(flat, eachLevel), slotsToUUIDs(unique, List.of(slots)), condition);
}
}
}