Skip to content

Commit

Permalink
You can now deposit or take water and lava from cauldrons using cups,…
Browse files Browse the repository at this point in the history
… mugs, etc
  • Loading branch information
Sollace committed Jun 20, 2024
1 parent b0a1f9f commit 6d1e3dc
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public void tick(ServerWorld world) {

if (FluidCapacity.get(output) > 0) {
ItemFluids.Transaction t = ItemFluids.Transaction.begin(output);
int amount = tank.withdraw(t, FluidVolumes.CUP);
int amount = tank.withdraw(t, FluidVolumes.BOWL);
if (amount > 0) {
outputSlot.incrementLevelsTransferred(amount);
playSound = true;
Expand All @@ -95,7 +95,7 @@ public void tick(ServerWorld world) {
if (FluidCapacity.get(input) > 0) {
ItemFluids.Transaction t = ItemFluids.Transaction.begin(input);

int amount = tank.deposit(t, FluidVolumes.CUP);
int amount = tank.deposit(t, FluidVolumes.BOWL);
if (amount > 0) {
inputSlot.incrementLevelsTransferred(amount);
inputSlot.setStack(t.toItemStack());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package ivorius.psychedelicraft.fluid.container;

import org.jetbrains.annotations.Nullable;

import ivorius.psychedelicraft.fluid.FluidVolumes;
import ivorius.psychedelicraft.fluid.SimpleFluid;
import ivorius.psychedelicraft.item.component.ItemFluids;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.LeveledCauldronBlock;
import net.minecraft.block.cauldron.CauldronBehavior;
import net.minecraft.fluid.Fluids;
import net.minecraft.item.Item;
import net.minecraft.item.ItemUsage;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.stat.Stats;
import net.minecraft.util.ItemActionResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.event.GameEvent;

public interface FluidCauldronBehavior {
CauldronBehavior AIR = (state, world, pos, player, hand, stack) -> {
ItemFluids.Transaction t = ItemFluids.Transaction.begin(stack.copy());
@Nullable
Block cauldron = t.fluids().fluid().getPhysical().getCauldron();
if (cauldron != null && t.fluids().amount() > FluidVolumes.GLASS_BOTTLE) {
int levels = Math.min(t.fluids().amount() / FluidVolumes.GLASS_BOTTLE, LeveledCauldronBlock.MAX_LEVEL);
Item item = stack.getItem();
t.withdraw(levels * FluidVolumes.GLASS_BOTTLE);
player.setStackInHand(hand, ItemUsage.exchangeStack(stack, player, t.toItemStack()));
player.incrementStat(Stats.USE_CAULDRON);
player.incrementStat(Stats.USED.getOrCreateStat(item));
world.setBlockState(pos, cauldron.getDefaultState().with(LeveledCauldronBlock.LEVEL, levels));
world.playSound(null, pos, SoundEvents.ITEM_BOTTLE_EMPTY, SoundCategory.BLOCKS, 1, 1);
world.emitGameEvent(null, GameEvent.FLUID_PICKUP, pos);
return ItemActionResult.SUCCESS;
}

return ItemActionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
};
CauldronBehavior WATER = createCauldronInteraction(SimpleFluid.forVanilla(Fluids.WATER));
CauldronBehavior LAVA = createCauldronInteraction(SimpleFluid.forVanilla(Fluids.LAVA));

static void register(Item item) {
CauldronBehavior.EMPTY_CAULDRON_BEHAVIOR.map().put(item, FluidCauldronBehavior.AIR);
CauldronBehavior.LAVA_CAULDRON_BEHAVIOR.map().put(item, FluidCauldronBehavior.LAVA);
CauldronBehavior.WATER_CAULDRON_BEHAVIOR.map().put(item, FluidCauldronBehavior.WATER);
}

static CauldronBehavior createCauldronInteraction(SimpleFluid fluidType) {
return (state, world, pos, player, hand, stack) -> {
Item item = stack.getItem();
ItemFluids.Transaction t = ItemFluids.Transaction.begin(stack.copy());
if (t.fluids().isEmpty()) {
ItemFluids fluid = fluidType.getDefaultStack(FluidVolumes.GLASS_BOTTLE);
if (!t.canAccept(fluid)) {
return ItemActionResult.FAIL;
}
if (!world.isClient) {
t.deposit(fluid);
player.setStackInHand(hand, ItemUsage.exchangeStack(stack, player, t.toItemStack()));
player.incrementStat(Stats.USE_CAULDRON);
player.incrementStat(Stats.USED.getOrCreateStat(item));
LeveledCauldronBlock.decrementFluidLevel(state, world, pos);
world.playSound(null, pos, SoundEvents.ITEM_BOTTLE_FILL, SoundCategory.BLOCKS, 1, 1);
world.emitGameEvent(null, GameEvent.FLUID_PICKUP, pos);
}
return ItemActionResult.SUCCESS;
}

if (t.fluids().fluid() != fluidType || t.fluids().amount() < FluidVolumes.GLASS_BOTTLE || !tryIncrementFluidLevel(state, world, pos)) {
return ItemActionResult.PASS_TO_DEFAULT_BLOCK_INTERACTION;
}

player.incrementStat(Stats.USE_CAULDRON);
player.incrementStat(Stats.USED.getOrCreateStat(item));
t.withdraw(FluidVolumes.GLASS_BOTTLE);
world.playSound(null, pos, SoundEvents.ITEM_BOTTLE_EMPTY, SoundCategory.BLOCKS, 1, 1);
player.setStackInHand(hand, ItemUsage.exchangeStack(stack, player, t.toItemStack()));
return ItemActionResult.SUCCESS;
};
}

private static boolean tryIncrementFluidLevel(BlockState state, World world, BlockPos pos) {
if (state.get(LeveledCauldronBlock.LEVEL) < LeveledCauldronBlock.MAX_LEVEL) {
state = state.cycle(LeveledCauldronBlock.LEVEL);
world.setBlockState(pos, state);
world.emitGameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Emitter.of(state));
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ public Block getBlock() {
return block;
}

@Nullable
public Block getCauldron() {
if (standing == Fluids.WATER) {
return Blocks.WATER_CAULDRON;
}
if (standing == Fluids.LAVA) {
return Blocks.LAVA_CAULDRON;
}
return null;
}

@Nullable
public SimpleFluid getType() {
return type;
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/ivorius/psychedelicraft/item/PSItems.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

package ivorius.psychedelicraft.item;

import java.util.List;

import org.joml.Vector3f;

import com.terraformersmc.terraform.boat.api.TerraformBoatTypeRegistry;
Expand All @@ -18,6 +20,7 @@
import ivorius.psychedelicraft.fluid.ConsumableFluid;
import ivorius.psychedelicraft.fluid.FluidVolumes;
import ivorius.psychedelicraft.fluid.Processable;
import ivorius.psychedelicraft.fluid.container.FluidCauldronBehavior;
import ivorius.psychedelicraft.item.component.BagContentsComponent;
import ivorius.psychedelicraft.item.component.FluidCapacity;
import ivorius.psychedelicraft.item.component.PSComponents;
Expand Down Expand Up @@ -289,5 +292,9 @@ static void bootstrap() {
FuelRegistry.INSTANCE.add(CIGAR, 80);
FuelRegistry.INSTANCE.add(CIGARETTE, 50);
FuelRegistry.INSTANCE.add(WOODEN_MUG, 50);

List.of(
WOODEN_MUG, STONE_CUP, GLASS_CHALICE, SHOT_GLASS, BOTTLE, FILLED_BUCKET, FILLED_BOWL, FILLED_GLASS_BOTTLE
).forEach(FluidCauldronBehavior::register);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ static Transaction begin(ItemStack initialStack) {

ItemFluids withdraw(int amount);

/**
* Deposits up to {maxAmount} of the given fluid.
*
* @return The remaining fluid that could not be inserted.
*/
default ItemFluids deposit(ItemFluids fluids) {
return deposit(fluids, fluids.amount());
}
Expand All @@ -190,6 +195,14 @@ default ItemFluids deposit(ItemFluids fluids) {
ItemFluids fluids();

ItemStack toItemStack();

default boolean canAccept(ItemFluids fluids) {
return canAccept(fluids, fluids.amount());
}

default boolean canAccept(ItemFluids fluids, int amount) {
return fluids().canCombine(fluids) && Math.min(fluids.amount(), (capacity() - fluids().amount())) >= amount;
}
}

public static class DirectTransaction implements Transaction {
Expand Down

0 comments on commit 6d1e3dc

Please sign in to comment.