diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/DispenserMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/DispenserMovementBehaviour.java index 6e44c2c9b..c99b86e14 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/DispenserMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/DispenserMovementBehaviour.java @@ -4,6 +4,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.Blocks; import net.minecraft.block.DispenserBlock; +import net.minecraft.dispenser.DefaultDispenseItemBehavior; import net.minecraft.dispenser.IDispenseItemBehavior; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -31,6 +32,8 @@ public class DispenserMovementBehaviour extends DropperMovementBehaviour { context.world.playEvent(1001, pos, 0); } else { ItemStack itemstack = getStacks(context).get(i); + + // Special dispense item behaviour for moving contraptions if (MOVED_DISPENSE_ITEM_BEHAVIOURS.containsKey(itemstack.getItem())) { MOVED_DISPENSE_ITEM_BEHAVIOURS.get(itemstack.getItem()).dispense(itemstack, context, pos); return; @@ -38,7 +41,7 @@ public class DispenserMovementBehaviour extends DropperMovementBehaviour { int count = itemstack.getCount(); - // Try vanilla registry + // If none is there, try vanilla registry try { Vec3d facingVec = new Vec3d(context.state.get(DispenserBlock.FACING).getDirectionVec()); facingVec = VecHelper.rotate(facingVec, context.rotation.x, context.rotation.y, context.rotation.z); @@ -46,11 +49,15 @@ public class DispenserMovementBehaviour extends DropperMovementBehaviour { Direction clostestFacing = Direction.getFacingFromVector(facingVec.x, facingVec.y, facingVec.z); ContraptionBlockSource blockSource = new ContraptionBlockSource(context, pos, clostestFacing); IDispenseItemBehavior idispenseitembehavior = ((DispenserBlock) Blocks.DISPENSER).getBehavior(itemstack); - idispenseitembehavior.dispense(blockSource, itemstack); + if (idispenseitembehavior.getClass() != DefaultDispenseItemBehavior.class) { // There is a dispense item behaviour registered for the vanilla dispenser + idispenseitembehavior.dispense(blockSource, itemstack); + return; + } } catch (NullPointerException e) { - itemstack.setCount(count); - defaultBehaviour.dispense(itemstack, context, pos); // Something went wrong with the TE being null in ContraptionBlockSource, just drop the item + itemstack.setCount(count); // Something went wrong with the TE being null in ContraptionBlockSource, reset the stack } + + defaultBehaviour.dispense(itemstack, context, pos); // the default: launch the item } } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/DropperMovementBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/DropperMovementBehaviour.java index 525779cbf..e6d7d962f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/DropperMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/DropperMovementBehaviour.java @@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.components.actors.dispenser; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; -import com.simibubi.create.content.logistics.item.filter.FilterItem; import com.simibubi.create.foundation.item.ItemHelper; import net.minecraft.inventory.ItemStackHelper; import net.minecraft.item.ItemStack; @@ -36,9 +35,10 @@ public class DropperMovementBehaviour extends MovementBehaviour { private void collectItems(MovementContext context) { getStacks(context).stream().filter(itemStack -> !itemStack.isEmpty() && itemStack.getItem() != Items.AIR && itemStack.getMaxStackSize() > itemStack.getCount()).forEach(itemStack -> itemStack.grow( - ItemHelper.extract(context.contraption.inventory, stack -> FilterItem.test(context.world, stack, itemStack), ItemHelper.ExtractionCountMode.UPTO, itemStack.getMaxStackSize() - itemStack.getCount(), false).getCount())); + ItemHelper.extract(context.contraption.inventory, itemStack::isItemEqual, ItemHelper.ExtractionCountMode.UPTO, itemStack.getMaxStackSize() - itemStack.getCount(), false).getCount())); } + @SuppressWarnings("unchecked") protected NonNullList getStacks(MovementContext context) { if (!(context.temporaryData instanceof NonNullList) && context.world instanceof ServerWorld) { NonNullList stacks = NonNullList.withSize(9, ItemStack.EMPTY); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/IMovedDispenseItemBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/IMovedDispenseItemBehaviour.java index b8fdfca0a..eaccbc332 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/IMovedDispenseItemBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/IMovedDispenseItemBehaviour.java @@ -1,6 +1,9 @@ package com.simibubi.create.content.contraptions.components.actors.dispenser; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import net.minecraft.block.BeehiveBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; import net.minecraft.entity.IProjectile; import net.minecraft.entity.item.ExperienceBottleEntity; import net.minecraft.entity.item.FireworkRocketEntity; @@ -8,6 +11,11 @@ import net.minecraft.entity.item.TNTEntity; import net.minecraft.entity.projectile.*; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; +import net.minecraft.potion.PotionUtils; +import net.minecraft.potion.Potions; +import net.minecraft.tags.BlockTags; +import net.minecraft.tags.FluidTags; +import net.minecraft.tileentity.BeehiveTileEntity; import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvents; import net.minecraft.util.Util; @@ -15,6 +23,7 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.world.IWorld; import net.minecraft.world.World; +import net.minecraftforge.items.ItemHandlerHelper; import java.util.Random; @@ -140,6 +149,34 @@ public interface IMovedDispenseItemBehaviour { }); + DispenserMovementBehaviour.registerMovedDispenseItemBehaviour(Items.GLASS_BOTTLE, new MovedOptionalDispenseBehaviour() { + @Override + protected ItemStack dispenseStack(ItemStack itemStack, MovementContext context, BlockPos pos, Vec3d facing) { + this.successful = false; + BlockPos interactAt = pos.offset(getClosestFacingDirection(facing)); + BlockState state = context.world.getBlockState(interactAt); + Block block = state.getBlock(); + + if (block.isIn(BlockTags.field_226151_aa_) && state.get(BeehiveBlock.HONEY_LEVEL) >= 5) { // Beehive -> honey bottles + ((BeehiveBlock) block).takeHoney(context.world, state, interactAt, null, BeehiveTileEntity.State.BEE_RELEASED); + this.successful = true; + return placeItemInInventory(itemStack, new ItemStack(Items.field_226638_pX_), context, pos, facing); + } else if (context.world.getFluidState(interactAt).isTagged(FluidTags.WATER)) { + this.successful = true; + return placeItemInInventory(itemStack, PotionUtils.addPotionToItemStack(new ItemStack(Items.POTION), Potions.WATER), context, pos, facing); + } else { + return super.dispenseStack(itemStack, context, pos, facing); + } + } + + private ItemStack placeItemInInventory(ItemStack bottles, ItemStack output, MovementContext context, BlockPos pos, Vec3d facing) { + bottles.shrink(1); + ItemStack remainder = ItemHandlerHelper.insertItem(context.contraption.inventory, output.copy(), false); + if (!remainder.isEmpty()) + super.dispenseStack(output, context, pos, facing); + return bottles; + } + }); } ItemStack dispense(ItemStack itemStack, MovementContext context, BlockPos pos); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/MovedDefaultDispenseItemBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/MovedDefaultDispenseItemBehaviour.java index 73501171b..90d37684f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/MovedDefaultDispenseItemBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/MovedDefaultDispenseItemBehaviour.java @@ -13,7 +13,7 @@ import net.minecraft.world.World; public class MovedDefaultDispenseItemBehaviour implements IMovedDispenseItemBehaviour { - public static void doDispense(World p_82486_0_, ItemStack p_82486_1_, int p_82486_2_, Vec3d facing, BlockPos p_82486_4_) { + public static void doDispense(World p_82486_0_, ItemStack p_82486_1_, int p_82486_2_, Vec3d facing, BlockPos p_82486_4_, MovementContext context) { double d0 = p_82486_4_.getX() + facing.x + .5; double d1 = p_82486_4_.getY() + facing.y + .5; double d2 = p_82486_4_.getZ() + facing.z + .5; @@ -25,7 +25,7 @@ public class MovedDefaultDispenseItemBehaviour implements IMovedDispenseItemBeha ItemEntity itementity = new ItemEntity(p_82486_0_, d0, d1, d2, p_82486_1_); double d3 = p_82486_0_.rand.nextDouble() * 0.1D + 0.2D; - itementity.setMotion(p_82486_0_.rand.nextGaussian() * (double) 0.0075F * (double) p_82486_2_ + facing.getX() * d3, p_82486_0_.rand.nextGaussian() * (double) 0.0075F * (double) p_82486_2_ + facing.getY() * d3, p_82486_0_.rand.nextGaussian() * (double) 0.0075F * (double) p_82486_2_ + facing.getZ() * d3); + itementity.setMotion(p_82486_0_.rand.nextGaussian() * (double) 0.0075F * (double) p_82486_2_ + facing.getX() * d3 + context.motion.x, p_82486_0_.rand.nextGaussian() * (double) 0.0075F * (double) p_82486_2_ + facing.getY() * d3 + context.motion.y, p_82486_0_.rand.nextGaussian() * (double) 0.0075F * (double) p_82486_2_ + facing.getZ() * d3 + context.motion.z); p_82486_0_.addEntity(itementity); } @@ -46,7 +46,7 @@ public class MovedDefaultDispenseItemBehaviour implements IMovedDispenseItemBeha */ protected ItemStack dispenseStack(ItemStack itemStack, MovementContext context, BlockPos pos, Vec3d facing) { ItemStack itemstack = itemStack.split(1); - doDispense(context.world, itemstack, 6, facing, pos); + doDispense(context.world, itemstack, 6, facing, pos, context); return itemStack; } @@ -61,6 +61,10 @@ public class MovedDefaultDispenseItemBehaviour implements IMovedDispenseItemBeha * Order clients to display dispense particles from the specified block and facing. */ protected void spawnDispenseParticles(IWorld world, BlockPos pos, Vec3d facing) { - world.playEvent(2000, pos, Direction.getFacingFromVector(facing.x, facing.y, facing.z).getIndex()); + world.playEvent(2000, pos, getClosestFacingDirection(facing).getIndex()); + } + + protected Direction getClosestFacingDirection(Vec3d exactFacing) { + return Direction.getFacingFromVector(exactFacing.x, exactFacing.y, exactFacing.z); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/MovedOptionalDispenseBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/MovedOptionalDispenseBehaviour.java new file mode 100644 index 000000000..d3eb7e88e --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/MovedOptionalDispenseBehaviour.java @@ -0,0 +1,13 @@ +package com.simibubi.create.content.contraptions.components.actors.dispenser; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IWorld; + +public class MovedOptionalDispenseBehaviour extends MovedDefaultDispenseItemBehaviour { + protected boolean successful = true; + + @Override + protected void playDispenseSound(IWorld world, BlockPos pos) { + world.playEvent(this.successful ? 1000 : 1001, pos, 0); + } +}