From 931f0f04e802d38926958dd4dc17ccad9867ab16 Mon Sep 17 00:00:00 2001 From: Jonas Gunz Date: Sat, 18 Apr 2020 02:20:31 +0200 Subject: Made Cauldron usable with Dispenser Buckets and Bottles can empty Dispenser, Shulkerboxes can be Cleaned. --- .../re/jag/parquet/BucketDispenserBehavior.java | 44 +++++++++++++++ .../jag/parquet/GlassBottleDispenserBehavior.java | 63 ++++++++++++++++++++++ src/main/java/re/jag/parquet/Parquet.java | 21 ++++++++ .../re/jag/parquet/PotionDispenserBehavior.java | 43 +++++++++++++++ .../parquet/ShulkerPlacementDispenserBehavior.java | 54 +++++++++++++++++++ .../jag/parquet/WaterBucketDispenserBehavior.java | 46 ++++++++++++++++ .../java/re/jag/parquet/mixin/BootstrapMixin.java | 19 +++++++ 7 files changed, 290 insertions(+) create mode 100644 src/main/java/re/jag/parquet/BucketDispenserBehavior.java create mode 100644 src/main/java/re/jag/parquet/GlassBottleDispenserBehavior.java create mode 100644 src/main/java/re/jag/parquet/PotionDispenserBehavior.java create mode 100644 src/main/java/re/jag/parquet/ShulkerPlacementDispenserBehavior.java create mode 100644 src/main/java/re/jag/parquet/WaterBucketDispenserBehavior.java create mode 100644 src/main/java/re/jag/parquet/mixin/BootstrapMixin.java (limited to 'src/main/java/re/jag') diff --git a/src/main/java/re/jag/parquet/BucketDispenserBehavior.java b/src/main/java/re/jag/parquet/BucketDispenserBehavior.java new file mode 100644 index 0000000..0dabf5a --- /dev/null +++ b/src/main/java/re/jag/parquet/BucketDispenserBehavior.java @@ -0,0 +1,44 @@ +package re.jag.parquet; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.CauldronBlock; +import net.minecraft.block.DispenserBlock; +import net.minecraft.block.FluidDrainable; +import net.minecraft.block.dispenser.FallibleItemDispenserBehavior; +import net.minecraft.fluid.Fluid; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.math.BlockPointer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; + +public class BucketDispenserBehavior extends FallibleItemDispenserBehavior { + public ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) { + this.success = false; + World world = pointer.getWorld(); + BlockPos block_pos = pointer.getBlockPos().offset((Direction)pointer.getBlockState().get(DispenserBlock.FACING)); + BlockState state = world.getBlockState(block_pos); + Block block = state.getBlock(); + if (block instanceof FluidDrainable) { + Fluid fluid = ((FluidDrainable)block).tryDrainFluid(world, block_pos, state); + + //Mojang, why are you here? + if (!(fluid instanceof net.minecraft.fluid.BaseFluid)) { + return super.dispenseSilently(pointer, stack); + } + //TODO if not work, add item = ... + fluid.getBucketItem(); + } + if (block instanceof CauldronBlock) { + if(state.get(CauldronBlock.LEVEL) >= 3) { + ((CauldronBlock)block).setLevel(world, block_pos, state, 0); + this.success = true; + return new ItemStack(Items.WATER_BUCKET, 1); + } + return stack; + } + return super.dispenseSilently(pointer, stack); + } +} diff --git a/src/main/java/re/jag/parquet/GlassBottleDispenserBehavior.java b/src/main/java/re/jag/parquet/GlassBottleDispenserBehavior.java new file mode 100644 index 0000000..851a769 --- /dev/null +++ b/src/main/java/re/jag/parquet/GlassBottleDispenserBehavior.java @@ -0,0 +1,63 @@ +package re.jag.parquet; + +import net.minecraft.block.BeehiveBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.CauldronBlock; +import net.minecraft.block.DispenserBlock; +import net.minecraft.block.dispenser.FallibleItemDispenserBehavior; +import net.minecraft.block.entity.BeehiveBlockEntity; +import net.minecraft.block.entity.DispenserBlockEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.potion.PotionUtil; +import net.minecraft.potion.Potions; +import net.minecraft.tag.BlockTags; +import net.minecraft.tag.FluidTags; +import net.minecraft.util.math.BlockPointer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; + +public class GlassBottleDispenserBehavior extends FallibleItemDispenserBehavior { + + //TODO Port over to bucket? + private ItemStack insert_first_free_or_drop(BlockPointer blockPointer, ItemStack emptyBottleStack, ItemStack filledBottleStack) { + emptyBottleStack.decrement(1); + if (emptyBottleStack.isEmpty()) { + return filledBottleStack.copy(); + } + if (((DispenserBlockEntity)blockPointer.getBlockEntity()).addToFirstFreeSlot(filledBottleStack.copy()) < 0) { + this.dispense(blockPointer, filledBottleStack.copy()); + } + return emptyBottleStack; + } + + public ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) { + this.success = false; + World world = pointer.getWorld(); + BlockPos block_pos = pointer.getBlockPos().offset((Direction)pointer.getBlockState().get(DispenserBlock.FACING)); + BlockState state = world.getBlockState(block_pos); + Block block = state.getBlock(); + if (block.matches(BlockTags.BEEHIVES) && ((Integer)state.get(BeehiveBlock.HONEY_LEVEL)).intValue() >= 5) { + ((BeehiveBlock)state.getBlock()).takeHoney(world, state, block_pos, null, BeehiveBlockEntity.BeeState.BEE_RELEASED); + this.success = true; + return insert_first_free_or_drop(pointer, stack, new ItemStack(Items.HONEY_BOTTLE)); + } + if (block instanceof CauldronBlock) { + int fill_level = state.get(CauldronBlock.LEVEL); + if(fill_level > 0) { + ((CauldronBlock)block).setLevel(world, block_pos, state, fill_level - 1); + this.success = true; + return insert_first_free_or_drop(pointer, stack, PotionUtil.setPotion( new ItemStack(Items.POTION), Potions.WATER ) ); + } + return stack; + } + if (world.getFluidState(block_pos).matches(FluidTags.WATER)) { + this.success = true; + return insert_first_free_or_drop(pointer, stack, PotionUtil.setPotion(new ItemStack(Items.POTION), Potions.WATER)); + } + return super.dispenseSilently(pointer, stack); + } +} + diff --git a/src/main/java/re/jag/parquet/Parquet.java b/src/main/java/re/jag/parquet/Parquet.java index a7e1d27..fc8bcaa 100644 --- a/src/main/java/re/jag/parquet/Parquet.java +++ b/src/main/java/re/jag/parquet/Parquet.java @@ -3,7 +3,13 @@ package re.jag.parquet; import com.mojang.brigadier.CommandDispatcher; import net.fabricmc.api.ModInitializer; +import net.minecraft.block.Blocks; +import net.minecraft.block.DispenserBlock; +import net.minecraft.block.ShulkerBoxBlock; +import net.minecraft.block.dispenser.BlockPlacementDispenserBehavior; +import net.minecraft.item.Items; import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.util.DyeColor; import re.jag.parquet.commands.CameraMode; import re.jag.parquet.commands.Savedata; @@ -19,5 +25,20 @@ public class Parquet implements ModInitializer { CameraMode.register(dispatcher); System.out.println("[parquet] Registered commands"); } + + public static void registerCustomDispenserBehavior() { + //TODO Maybe rewrite Cauldron onUse to not only acccept players? + DispenserBlock.registerBehavior(Blocks.SHULKER_BOX.asItem(), new ShulkerPlacementDispenserBehavior()); + for (DyeColor dye_color : DyeColor.values()) { + DispenserBlock.registerBehavior(ShulkerBoxBlock.get(dye_color).asItem(), new ShulkerPlacementDispenserBehavior()); + } + + DispenserBlock.registerBehavior(Items.WATER_BUCKET, new WaterBucketDispenserBehavior()); + DispenserBlock.registerBehavior(Items.BUCKET, new BucketDispenserBehavior()); + DispenserBlock.registerBehavior(Items.GLASS_BOTTLE, new GlassBottleDispenserBehavior()); + DispenserBlock.registerBehavior(Items.POTION, new PotionDispenserBehavior()); + + System.out.println("Registered Custom Dispenser behaviors"); + } } diff --git a/src/main/java/re/jag/parquet/PotionDispenserBehavior.java b/src/main/java/re/jag/parquet/PotionDispenserBehavior.java new file mode 100644 index 0000000..8959ae5 --- /dev/null +++ b/src/main/java/re/jag/parquet/PotionDispenserBehavior.java @@ -0,0 +1,43 @@ +package re.jag.parquet; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.CauldronBlock; +import net.minecraft.block.DispenserBlock; +import net.minecraft.block.FluidDrainable; +import net.minecraft.block.dispenser.FallibleItemDispenserBehavior; +import net.minecraft.fluid.Fluid; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.potion.Potion; +import net.minecraft.potion.PotionUtil; +import net.minecraft.potion.Potions; +import net.minecraft.util.math.BlockPointer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; + +public class PotionDispenserBehavior extends FallibleItemDispenserBehavior { + public ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) { + this.success = false; + World world = pointer.getWorld(); + BlockPos block_pos = pointer.getBlockPos().offset((Direction)pointer.getBlockState().get(DispenserBlock.FACING)); + BlockState state = world.getBlockState(block_pos); + Block block = state.getBlock(); + + + if (PotionUtil.getPotion(stack) == Potions.WATER) { + if (block instanceof CauldronBlock) { + int fill_level = state.get(CauldronBlock.LEVEL); + if(fill_level < 3) { + ((CauldronBlock)block).setLevel(world, block_pos, state, fill_level + 1); + this.success = true; + return new ItemStack(Items.GLASS_BOTTLE, 1); + } + return stack; + } + } + return super.dispenseSilently(pointer, stack); + } +} diff --git a/src/main/java/re/jag/parquet/ShulkerPlacementDispenserBehavior.java b/src/main/java/re/jag/parquet/ShulkerPlacementDispenserBehavior.java new file mode 100644 index 0000000..20be74f --- /dev/null +++ b/src/main/java/re/jag/parquet/ShulkerPlacementDispenserBehavior.java @@ -0,0 +1,54 @@ +package re.jag.parquet; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.CauldronBlock; +import net.minecraft.block.DispenserBlock; +import net.minecraft.block.ShulkerBoxBlock; +import net.minecraft.block.dispenser.BlockPlacementDispenserBehavior; +import net.minecraft.item.AutomaticItemPlacementContext; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.stat.Stats; +import net.minecraft.util.ActionResult; +import net.minecraft.util.math.BlockPointer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; + +public class ShulkerPlacementDispenserBehavior extends BlockPlacementDispenserBehavior{ + protected ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) { + this.success = false; + + Item item = stack.getItem(); + + if (item instanceof BlockItem) { + Direction direction = (Direction)pointer.getBlockState().get(DispenserBlock.FACING); + BlockPos block_pos = pointer.getBlockPos().offset(direction); + Block block = ((BlockItem)item).getBlock(); + + if (block instanceof ShulkerBoxBlock && !pointer.getWorld().isClient()) { + BlockState state = pointer.getWorld().getBlockState(block_pos); + if (state.getBlock() instanceof CauldronBlock) { + int fill_level = state.get(CauldronBlock.LEVEL); + if (fill_level > 0) { + ItemStack itemStack5 = new ItemStack(Blocks.SHULKER_BOX, 1); + if (stack.hasTag()) { + itemStack5.setTag(stack.getTag().copy()); + } + ((CauldronBlock)state.getBlock()).setLevel(pointer.getWorld(), block_pos, state, fill_level - 1); + + this.success = true; + return itemStack5; + } + + //fail if cauldron empty + return stack; + } + } + } + + return super.dispenseSilently(pointer, stack); + } +} diff --git a/src/main/java/re/jag/parquet/WaterBucketDispenserBehavior.java b/src/main/java/re/jag/parquet/WaterBucketDispenserBehavior.java new file mode 100644 index 0000000..8d38645 --- /dev/null +++ b/src/main/java/re/jag/parquet/WaterBucketDispenserBehavior.java @@ -0,0 +1,46 @@ +package re.jag.parquet; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.CauldronBlock; +import net.minecraft.block.DispenserBlock; +import net.minecraft.block.dispenser.FallibleItemDispenserBehavior; +import net.minecraft.item.BucketItem; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.math.BlockPointer; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; + +public class WaterBucketDispenserBehavior extends FallibleItemDispenserBehavior{ + + public ItemStack dispenseSilently(BlockPointer pointer, ItemStack stack) { + this.success = false; + + BucketItem bucket_item = (BucketItem)stack.getItem(); + BlockPos block_pos = pointer.getBlockPos().offset((Direction)pointer.getBlockState().get(DispenserBlock.FACING)); + World world = pointer.getWorld(); + if (bucket_item.placeFluid(null, world, block_pos, null)) { + bucket_item.onEmptied(world, stack, block_pos); + this.success = true; + return new ItemStack(Items.BUCKET); + } + + BlockState state = pointer.getWorld().getBlockState(block_pos); + Block facing_block = state.getBlock(); + + if ( facing_block instanceof CauldronBlock) { + if (state.get(CauldronBlock.LEVEL) >= 3) { + return stack; + } + ((CauldronBlock)facing_block).setLevel(world, block_pos, state, 3); + + this.success = true; + return new ItemStack(Items.BUCKET, 1); + } + + this.success = true; + return this.dispense(pointer, stack); + } +} diff --git a/src/main/java/re/jag/parquet/mixin/BootstrapMixin.java b/src/main/java/re/jag/parquet/mixin/BootstrapMixin.java new file mode 100644 index 0000000..04b448e --- /dev/null +++ b/src/main/java/re/jag/parquet/mixin/BootstrapMixin.java @@ -0,0 +1,19 @@ +package re.jag.parquet.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; + +import net.minecraft.Bootstrap; + +import re.jag.parquet.Parquet; + +@Mixin(Bootstrap.class) +public abstract class BootstrapMixin { + + @Inject(method="initialize", at = @At("RETURN")) + private static void onInitialize(CallbackInfo ci) { + Parquet.registerCustomDispenserBehavior(); + } +} -- cgit v1.2.3