-
Notifications
You must be signed in to change notification settings - Fork 755
/
IDisplayModifierRecipe.java
135 lines (114 loc) · 4.85 KB
/
IDisplayModifierRecipe.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
package slimeknights.tconstruct.library.recipe.modifiers.adding;
import com.google.common.collect.Streams;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import slimeknights.tconstruct.library.json.IntRange;
import slimeknights.tconstruct.library.modifiers.Modifier;
import slimeknights.tconstruct.library.modifiers.ModifierEntry;
import slimeknights.tconstruct.library.modifiers.ModifierHooks;
import slimeknights.tconstruct.library.tools.SlotType;
import slimeknights.tconstruct.library.tools.SlotType.SlotCount;
import slimeknights.tconstruct.library.tools.context.ToolRebuildContext;
import slimeknights.tconstruct.library.tools.definition.ToolDefinition;
import slimeknights.tconstruct.library.tools.item.IModifiableDisplay;
import slimeknights.tconstruct.library.tools.nbt.MaterialNBT;
import slimeknights.tconstruct.library.tools.nbt.ModDataNBT;
import slimeknights.tconstruct.library.tools.nbt.ModifierNBT;
import slimeknights.tconstruct.library.tools.nbt.ToolStack;
import javax.annotation.Nullable;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
/** Common interface for modifier recipes that can show in JEI */
public interface IDisplayModifierRecipe extends IModifierRecipe {
/** Gets the number of inputs for this recipe */
int getInputCount();
/**
* Gets an ingredients to display in JEI.
* @param slot Slot index to display
* @return Display item list
*/
List<ItemStack> getDisplayItems(int slot);
/** Gets the result tool before adding the modifier */
List<ItemStack> getToolWithoutModifier();
/** Gets the result tool with this modifier added */
List<ItemStack> getToolWithModifier();
/** Gets the modifier output of this recipe */
ModifierEntry getDisplayResult();
@Override
default Modifier getModifier() {
return getDisplayResult().getModifier();
}
/**
* Gets the range this modifier is valid for
* @return level range, defaults to {@link ModifierEntry#VALID_LEVEL}
*/
default IntRange getLevel() {
return ModifierEntry.VALID_LEVEL;
}
/** Gets the slot type used by this modifier */
@Nullable
default SlotCount getSlots() {
return null;
}
@Nullable
@Override
default SlotType getSlotType() {
SlotCount count = getSlots();
if (count == null) {
return null;
}
return count.type();
}
/** If true, this recipe can be applied incrementally */
default boolean isIncremental() {
return false;
}
/* Helpers */
/** Maps the stream from tool items to applicable tool stacks */
Function<Item,ItemStack> MAP_TOOL_FOR_RENDERING = IModifiableDisplay::getDisplayStack;
/**
* Gets the list of modifiers to display for the given result
* @param result Resulting modifier
* @param self Current modifier to display, will typically be result or a lower level of result
* @return List of modifiers
*/
static List<ModifierEntry> modifiersForResult(ModifierEntry result, @Nullable ModifierEntry self) {
List<ModifierEntry> requirements = result.getHook(ModifierHooks.REQUIREMENTS).displayModifiers(result);
if (self != null) {
return Streams.concat(requirements.stream(), Stream.of(self)).toList();
}
return requirements;
}
/* Gets a copy of the stack with the given modifiers */
static ItemStack withModifiers(ItemStack stack, List<ModifierEntry> modifiers) {
return withModifiers(stack, modifiers, data -> {});
}
/* Gets a copy of the stack with the given modifiers */
static ItemStack withModifiers(ItemStack stack, List<ModifierEntry> modifierList, Consumer<ModDataNBT> persistentDataConsumer) {
ItemStack output = stack.copy();
CompoundTag nbt = output.getOrCreateTag();
// build modifiers list
// go through the builder to ensure they are merged properly
ModifierNBT modifiers = ModifierNBT.builder().add(modifierList).build();
ListTag list = modifiers.serializeToNBT();
nbt.put(ToolStack.TAG_UPGRADES, list);
nbt.put(ToolStack.TAG_MODIFIERS, list);
// build persistent and volatile NBT
CompoundTag persistentNBT = new CompoundTag();
ModDataNBT persistentData = ModDataNBT.readFromNBT(persistentNBT);
CompoundTag volatileNBT = new CompoundTag();
ModDataNBT volatileData = ModDataNBT.readFromNBT(volatileNBT);
persistentDataConsumer.accept(persistentData);
ToolRebuildContext context = new ToolRebuildContext(stack.getItem(), ToolDefinition.EMPTY, MaterialNBT.EMPTY, modifiers, modifiers, persistentData);
for (ModifierEntry entry : modifiers.getModifiers()) {
entry.getHook(ModifierHooks.VOLATILE_DATA).addVolatileData(context, entry, volatileData);
}
nbt.put(ToolStack.TAG_VOLATILE_MOD_DATA, volatileNBT);
nbt.put(ToolStack.TAG_PERSISTENT_MOD_DATA, persistentNBT);
return output;
}
}