-
Notifications
You must be signed in to change notification settings - Fork 754
/
ToolFluidCapability.java
310 lines (270 loc) · 10.7 KB
/
ToolFluidCapability.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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
package slimeknights.tconstruct.library.tools.capability.fluid;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import slimeknights.tconstruct.TConstruct;
import slimeknights.tconstruct.library.modifiers.ModifierEntry;
import slimeknights.tconstruct.library.modifiers.ModifierHooks;
import slimeknights.tconstruct.library.module.ModuleHook;
import slimeknights.tconstruct.library.tools.capability.ToolCapabilityProvider.IToolCapabilityProvider;
import slimeknights.tconstruct.library.tools.nbt.INamespacedNBTView;
import slimeknights.tconstruct.library.tools.nbt.IToolStackView;
import slimeknights.tconstruct.library.tools.nbt.NamespacedNBT;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Iterator;
import java.util.function.Supplier;
/**
* Logic to make a tool a fluid handler
*/
@RequiredArgsConstructor
public class ToolFluidCapability extends FluidModifierHookIterator<ModifierEntry> implements IFluidHandlerItem {
/** Boolean key to set in volatile mod data to enable the fluid capability */
public static final ResourceLocation TOTAL_TANKS = TConstruct.getResource("total_tanks");
/** Modifier hook instance to make an inventory modifier */
public static final ModuleHook<FluidModifierHook> HOOK = ModifierHooks.register(TConstruct.getResource("fluid"), FluidModifierHook.class, FluidModifierHookMerger::new, new FluidModifierHook() {
@Override
public int getTanks(INamespacedNBTView volatileData, ModifierEntry modifier) {
return 0;
}
@Override
public boolean isFluidValid(IToolStackView tool, ModifierEntry modifier, int tank, FluidStack fluid) {
return false;
}
@Override
public int fill(IToolStackView tool, ModifierEntry modifier, FluidStack resource, FluidAction action) {
return 0;
}
@Override
public FluidStack drain(IToolStackView tool, ModifierEntry modifier, FluidStack resource, FluidAction action) {
return FluidStack.EMPTY;
}
@Override
public FluidStack drain(IToolStackView tool, ModifierEntry modifier, int maxDrain, FluidAction action) {
return FluidStack.EMPTY;
}
});
@Getter
private final ItemStack container;
private final Supplier<? extends IToolStackView> tool;
/* Basic inventory */
@Override
public int getTanks() {
return tool.get().getVolatileData().getInt(TOTAL_TANKS);
}
@Override
protected Iterator<ModifierEntry> getIterator(IToolStackView tool) {
return tool.getModifierList().iterator();
}
@Override
protected FluidModifierHook getHook(ModifierEntry entry) {
indexEntry = entry;
return entry.getHook(HOOK);
}
@Nonnull
@Override
public FluidStack getFluidInTank(int tank) {
IToolStackView tool = this.tool.get();
FluidModifierHook hook = findHook(tool, tank);
if (hook != null) {
return hook.getFluidInTank(tool, indexEntry, tank - startIndex);
}
return FluidStack.EMPTY;
}
@Override
public int getTankCapacity(int tank) {
IToolStackView tool = this.tool.get();
FluidModifierHook hook = findHook(tool, tank);
if (hook != null) {
return hook.getTankCapacity(tool, indexEntry, tank - startIndex);
}
return 0;
}
@Override
public boolean isFluidValid(int tank, FluidStack stack) {
IToolStackView tool = this.tool.get();
FluidModifierHook hook = findHook(tool, tank);
if (hook != null) {
return hook.isFluidValid(tool, indexEntry, tank - startIndex, stack);
}
return false;
}
@Override
public int fill(FluidStack resource, FluidAction action) {
return fill(tool.get(), resource, action);
}
@Nonnull
@Override
public FluidStack drain(FluidStack resource, FluidAction action) {
return drain(tool.get(), resource, action);
}
@Nonnull
@Override
public FluidStack drain(int maxDrain, FluidAction action) {
return drain(tool.get(), maxDrain, action);
}
/** Adds the tanks from the fluid modifier to the tool */
public static void addTanks(ModifierEntry modifier, NamespacedNBT volatileData, FluidModifierHook hook) {
volatileData.putInt(TOTAL_TANKS, hook.getTanks(volatileData, modifier) + volatileData.getInt(TOTAL_TANKS));
}
/** Interface for modifiers with fluid capabilities to return */
@SuppressWarnings("unused")
public interface FluidModifierHook {
/**
* Determines how many fluid tanks are used by this modifier
* @param volatileData Tool data to check
* @param modifier Modifier to consider
* @return Number of tanks used
*/
default int getTanks(INamespacedNBTView volatileData, ModifierEntry modifier) {
return 1;
}
/**
* Gets the fluid in the given tank
* @param tool Tool instance
* @param modifier Entry instance
* @param tank Tank index
* @return Fluid in the given tank
*/
default FluidStack getFluidInTank(IToolStackView tool, ModifierEntry modifier, int tank) {
return FluidStack.EMPTY;
}
/**
* Gets the max capacity for the given tank
* @param tool Tool instance
* @param modifier Entry instance
* @param tank Tank index
* @return Fluid in the given tank
*/
default int getTankCapacity(IToolStackView tool, ModifierEntry modifier, int tank) {
return 0;
}
/**
* Checks if the fluid is valid for the given tank
* @param tool Tool instance
* @param modifier Entry instance
* @param tank Tank index
* @param fluid Fluid to insert
* @return True if the fluid is valid
*/
default boolean isFluidValid(IToolStackView tool, ModifierEntry modifier, int tank, FluidStack fluid) {
return true;
}
/**
* Fills fluid into tanks
* @param tool Tool instance
* @param modifier Entry instance
* @param resource FluidStack representing the Fluid and maximum amount of fluid to be filled. If you want to store this stack, make a copy
* @param action If SIMULATE, fill will only be simulated.
* @return Amount of resource that was (or would have been, if simulated) filled.
*/
int fill(IToolStackView tool, ModifierEntry modifier, FluidStack resource, FluidAction action);
/**
* Drains fluid out of tanks, distribution is left entirely to the IFluidHandler.
* @param tool Tool instance
* @param modifier Entry instance
* @param resource FluidStack representing the Fluid and maximum amount of fluid to be drained.
* @param action If SIMULATE, drain will only be simulated.
* @return FluidStack representing the Fluid and amount that was (or would have been, if
* simulated) drained.
*/
FluidStack drain(IToolStackView tool, ModifierEntry modifier, FluidStack resource, FluidAction action);
/**
* Drains fluid out of internal tanks, distribution is left entirely to the IFluidHandler.
* @param tool Tool instance
* @param modifier Entry instance
* @param maxDrain Maximum amount of fluid to drain.
* @param action If SIMULATE, drain will only be simulated.
* @return FluidStack representing the Fluid and amount that was (or would have been, if
* simulated) drained.
*/
FluidStack drain(IToolStackView tool, ModifierEntry modifier, int maxDrain, FluidAction action);
}
/** Logic to merge multiple fluid hooks */
@RequiredArgsConstructor
private static class FluidModifierHookMerger extends FluidModifierHookIterator<FluidModifierHook> implements FluidModifierHook {
private final Collection<FluidModifierHook> modules;
@Override
protected Iterator<FluidModifierHook> getIterator(IToolStackView tool) {
return modules.iterator();
}
@Override
protected FluidModifierHook getHook(FluidModifierHook entry) {
return entry;
}
/** Gets the given hook */
@Nullable
private FluidModifierHook findHook(IToolStackView tool, ModifierEntry modifier, int tank) {
indexEntry = modifier;
return this.findHook(tool, tank);
}
@Override
public int getTanks(INamespacedNBTView volatileData, ModifierEntry modifier) {
int sum = 0;
for (FluidModifierHook module : modules) {
sum += module.getTanks(volatileData, modifier);
}
return sum;
}
@Override
public FluidStack getFluidInTank(IToolStackView tool, ModifierEntry modifier, int tank) {
FluidModifierHook hook = findHook(tool, modifier, tank);
if (hook != null) {
return hook.getFluidInTank(tool, modifier, tank - startIndex);
}
return FluidStack.EMPTY;
}
@Override
public int getTankCapacity(IToolStackView tool, ModifierEntry modifier, int tank) {
FluidModifierHook hook = findHook(tool, modifier, tank);
if (hook != null) {
return hook.getTankCapacity(tool, modifier, tank - startIndex);
}
return 0;
}
@Override
public boolean isFluidValid(IToolStackView tool, ModifierEntry modifier, int tank, FluidStack fluid) {
FluidModifierHook hook = findHook(tool, modifier, tank);
if (hook != null) {
return hook.isFluidValid(tool, modifier, tank - startIndex, fluid);
}
return false;
}
@Override
public int fill(IToolStackView tool, ModifierEntry modifier, FluidStack resource, FluidAction action) {
indexEntry = modifier;
return fill(tool, resource, action);
}
@Override
public FluidStack drain(IToolStackView tool, ModifierEntry modifier, FluidStack resource, FluidAction action) {
indexEntry = modifier;
return drain(tool, resource, action);
}
@Override
public FluidStack drain(IToolStackView tool, ModifierEntry modifier, int maxDrain, FluidAction action) {
indexEntry = modifier;
return drain(tool, maxDrain, action);
}
}
/** Provider instance for a fluid cap */
public static class Provider implements IToolCapabilityProvider {
private final LazyOptional<IFluidHandlerItem> fluidCap;
public Provider(ItemStack stack, Supplier<? extends IToolStackView> toolStack) {
this.fluidCap = LazyOptional.of(() -> new ToolFluidCapability(stack, toolStack));
}
@Override
public <T> LazyOptional<T> getCapability(IToolStackView tool, Capability<T> cap) {
if (cap == ForgeCapabilities.FLUID_HANDLER_ITEM && tool.getVolatileData().getInt(TOTAL_TANKS) > 0) {
return fluidCap.cast();
}
return LazyOptional.empty();
}
}
}