/
EmptyBucketCauldronRecipe.java
103 lines (91 loc) · 3.76 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
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.fluid.Fluid;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.crafting.IRecipeSerializer;
import net.minecraft.tags.FluidTags;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.SoundEvents;
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) {
// 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() && (!inv.isSimple() || drained.getFluid() == Fluids.WATER);
}).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) {
// update contents
Fluid fluid = drained.getFluid();
inv.setContents(CauldronContentTypes.FLUID.of(fluid));
// fill cauldron
inv.setLevel(3);
// replace held item with container
inv.shrinkStack(1);
inv.setOrGiveStack(handler.getContainer());
// play sound
SoundEvent sound = drained.getFluid().getAttributes().getEmptySound(drained);
if (sound == null) {
sound = fluid.isIn(FluidTags.LAVA) ? SoundEvents.ITEM_BUCKET_EMPTY_LAVA : SoundEvents.ITEM_BUCKET_EMPTY;
}
inv.playSound(sound);
}
});
}
@Override
public ResourceLocation getId() {
return id;
}
@Override
public IRecipeSerializer<?> getSerializer() {
return InspirationsRecipes.emptyBucketSerializer;
}
}