/
EmptyBucketCauldronRecipe.java
109 lines (93 loc) · 3.69 KB
/
EmptyBucketCauldronRecipe.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
package knightminer.inspirations.recipes.recipe.cauldron;
import knightminer.inspirations.library.recipe.cauldron.CauldronContentTypes;
import knightminer.inspirations.library.recipe.cauldron.inventory.ICauldronInventory;
import knightminer.inspirations.library.recipe.cauldron.inventory.IModifyableCauldronInventory;
import knightminer.inspirations.library.recipe.cauldron.recipe.ICauldronRecipe;
import knightminer.inspirations.recipes.InspirationsRecipes;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction;
import net.minecraftforge.fluids.capability.IFluidHandlerItem;
import static net.minecraftforge.fluids.FluidAttributes.BUCKET_VOLUME;
/**
* Recipe to empty a bucket into the cauldron. Supports any generic fluid handler item.
*/
public class EmptyBucketCauldronRecipe implements ICauldronRecipe {
private final ResourceLocation id;
public EmptyBucketCauldronRecipe(ResourceLocation id) {
this.id = id;
}
/**
* Drains a fluid handler of 1000mb fluid
* @param inv Cauldron inventory instnace
* @param handler Fluid handler
* @return Fluid stack drained, or empty if nothing drained
*/
private static FluidStack drain(ICauldronInventory inv, IFluidHandlerItem handler, FluidAction action) {
// drain the fluid from the handler
FluidStack drained;
// if empty, drain anything
if (inv.getLevel() == 0) {
return handler.drain(BUCKET_VOLUME, action);
}
// if filled, drain a specific fluid
return inv.getContents()
.get(CauldronContentTypes.FLUID)
.map(fluid -> handler.drain(new FluidStack(fluid, BUCKET_VOLUME), action))
.orElse(FluidStack.EMPTY);
}
@Override
public boolean matches(ICauldronInventory inv, World worldIn) {
// if full, no fill
int level = inv.getLevel();
if (level == MAX) {
return false;
}
// must have a fluid handler
return FluidUtil.getFluidHandler(inv.getStack()).map(handler -> {
// drain the fluid from the handler
FluidStack drained = drain(inv, handler, FluidAction.SIMULATE);
// ensure the fluid is valid
return !drained.isEmpty() && drained.getAmount() == BUCKET_VOLUME && !drained.hasTag();
}).orElse(false);
}
@Override
public void handleRecipe(IModifyableCauldronInventory inv) {
FluidUtil.getFluidHandler(inv.getStack()).ifPresent(handler -> {
// if we drain less or more, unfortunately the non bucket amount is lost. It passed in simulate, so this is a mod problem
FluidStack drained = drain(inv, handler, FluidAction.EXECUTE);
if (drained.getAmount() >= BUCKET_VOLUME) {
// fill cauldron
inv.setLevel(3);
// update contents
inv.setContents(CauldronContentTypes.FLUID.of(drained.getFluid()));
// replace held item with container
inv.setStack(handler.getContainer());
}
});
}
@Override
public ResourceLocation getId() {
return id;
}
@Override
public IRecipeSerializer<?> getSerializer() {
return InspirationsRecipes.emptyBucketSerializer;
}
/* Extra methods for completion, even though they are mostly unneeded */
/** @deprecated Use {@link #getCraftingResult(ICauldronInventory)} */
@Deprecated
@Override
public ItemStack getRecipeOutput() {
return new ItemStack(Items.BUCKET);
}
@Override
public ItemStack getCraftingResult(ICauldronInventory inv) {
return inv.getStack().getContainerItem().copy();
}
}