From 7e4ca0475e935c5c9bbbd5e4d4a3711558f0b51f Mon Sep 17 00:00:00 2001 From: grimmauld Date: Tue, 1 Sep 2020 22:41:17 +0200 Subject: [PATCH] Add experimental dropper and dispenser movement behaviours. WIP: (probably) unstable, definitely buggy Unfinished: Bottles, maybe spawn eggs --- .../create/AllMovementBehaviours.java | 6 + .../dispenser/ContraptionBlockSource.java | 68 ++++++++ .../dispenser/DispenserMovementBehaviour.java | 56 +++++++ .../dispenser/DropperMovementBehaviour.java | 76 +++++++++ .../IMovedDispenseItemBehaviour.java | 146 ++++++++++++++++++ .../MovedDefaultDispenseItemBehaviour.java | 66 ++++++++ .../MovedProjectileDispenserBehaviour.java | 40 +++++ .../resources/META-INF/accesstransformer.cfg | 5 +- 8 files changed, 462 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/ContraptionBlockSource.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/DispenserMovementBehaviour.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/DropperMovementBehaviour.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/IMovedDispenseItemBehaviour.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/MovedDefaultDispenseItemBehaviour.java create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/MovedProjectileDispenserBehaviour.java diff --git a/src/main/java/com/simibubi/create/AllMovementBehaviours.java b/src/main/java/com/simibubi/create/AllMovementBehaviours.java index bc5274f2d..cf86e8ccb 100644 --- a/src/main/java/com/simibubi/create/AllMovementBehaviours.java +++ b/src/main/java/com/simibubi/create/AllMovementBehaviours.java @@ -6,6 +6,8 @@ import javax.annotation.Nullable; import com.simibubi.create.content.contraptions.components.actors.BellMovementBehaviour; import com.simibubi.create.content.contraptions.components.actors.CampfireMovementBehaviour; +import com.simibubi.create.content.contraptions.components.actors.dispenser.DispenserMovementBehaviour; +import com.simibubi.create.content.contraptions.components.actors.dispenser.DropperMovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import com.tterrag.registrate.util.nullness.NonNullConsumer; @@ -48,5 +50,9 @@ public class AllMovementBehaviours { static void register() { addMovementBehaviour(Blocks.BELL, new BellMovementBehaviour()); addMovementBehaviour(Blocks.CAMPFIRE, new CampfireMovementBehaviour()); + + DispenserMovementBehaviour.gatherMovedDispenseItemBehaviours(); + addMovementBehaviour(Blocks.DISPENSER, new DispenserMovementBehaviour()); + addMovementBehaviour(Blocks.DROPPER, new DropperMovementBehaviour()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/ContraptionBlockSource.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/ContraptionBlockSource.java new file mode 100644 index 000000000..9ff2f2d53 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/ContraptionBlockSource.java @@ -0,0 +1,68 @@ +package com.simibubi.create.content.contraptions.components.actors.dispenser; + +import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import mcp.MethodsReturnNonnullByDefault; +import net.minecraft.block.BlockState; +import net.minecraft.dispenser.IBlockSource; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +import javax.annotation.Nullable; + +@MethodsReturnNonnullByDefault +public class ContraptionBlockSource implements IBlockSource { + private final BlockPos pos; + private final MovementContext context; + private final Direction overrideFacing; + + public ContraptionBlockSource(MovementContext context, BlockPos pos) { + this(context, pos, null); + } + + public ContraptionBlockSource(MovementContext context, BlockPos pos, @Nullable Direction overrideFacing) { + this.pos = pos; + this.context = context; + this.overrideFacing = overrideFacing; + } + + @Override + public double getX() { + return (double)this.pos.getX() + 0.5D; + } + + @Override + public double getY() { + return (double)this.pos.getY() + 0.5D; + } + + @Override + public double getZ() { + return (double)this.pos.getZ() + 0.5D; + } + + @Override + public BlockPos getBlockPos() { + return pos; + } + + @Override + public BlockState getBlockState() { + if(context.state.has(BlockStateProperties.FACING) && overrideFacing != null) + return context.state.with(BlockStateProperties.FACING, overrideFacing); + return context.state; + } + + @Override + @Nullable + public T getBlockTileEntity() { + return null; + } + + @Override + public World getWorld() { + return context.world; + } +} 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 new file mode 100644 index 000000000..6e44c2c9b --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/DispenserMovementBehaviour.java @@ -0,0 +1,56 @@ +package com.simibubi.create.content.contraptions.components.actors.dispenser; + +import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.foundation.utility.VecHelper; +import net.minecraft.block.Blocks; +import net.minecraft.block.DispenserBlock; +import net.minecraft.dispenser.IDispenseItemBehavior; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; + +import java.util.HashMap; + +public class DispenserMovementBehaviour extends DropperMovementBehaviour { + private static final HashMap MOVED_DISPENSE_ITEM_BEHAVIOURS = new HashMap<>(); + + public static void gatherMovedDispenseItemBehaviours() { + IMovedDispenseItemBehaviour.init(); + } + + public static void registerMovedDispenseItemBehaviour(Item item, IMovedDispenseItemBehaviour movedDispenseItemBehaviour) { + MOVED_DISPENSE_ITEM_BEHAVIOURS.put(item, movedDispenseItemBehaviour); + } + + @Override + protected void activate(MovementContext context, BlockPos pos) { + int i = getDispenseSlot(context); + if (i < 0) { + context.world.playEvent(1001, pos, 0); + } else { + ItemStack itemstack = getStacks(context).get(i); + if (MOVED_DISPENSE_ITEM_BEHAVIOURS.containsKey(itemstack.getItem())) { + MOVED_DISPENSE_ITEM_BEHAVIOURS.get(itemstack.getItem()).dispense(itemstack, context, pos); + return; + } + + + int count = itemstack.getCount(); + // 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); + facingVec.normalize(); + 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); + } 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 + } + } + } +} 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 new file mode 100644 index 000000000..525779cbf --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/DropperMovementBehaviour.java @@ -0,0 +1,76 @@ +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; +import net.minecraft.item.Items; +import net.minecraft.util.NonNullList; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.server.ServerWorld; + +import java.util.Random; + +public class DropperMovementBehaviour extends MovementBehaviour { + protected static final MovedDefaultDispenseItemBehaviour defaultBehaviour = new MovedDefaultDispenseItemBehaviour(); + private static final Random RNG = new Random(); + + protected void activate(MovementContext context, BlockPos pos) { + int i = getDispenseSlot(context); + if (i < 0) { + context.world.playEvent(1001, pos, 0); + } else { + defaultBehaviour.dispense(getStacks(context).get(i), context, pos); + } + } + + @Override + public void visitNewPosition(MovementContext context, BlockPos pos) { + if (context.world.isRemote) + return; + collectItems(context); + activate(context, pos); + } + + 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())); + } + + protected NonNullList getStacks(MovementContext context) { + if (!(context.temporaryData instanceof NonNullList) && context.world instanceof ServerWorld) { + NonNullList stacks = NonNullList.withSize(9, ItemStack.EMPTY); + ItemStackHelper.loadAllItems(context.tileData, stacks); + context.temporaryData = stacks; + } + return (NonNullList) context.temporaryData; + } + + @Override + public void writeExtraData(MovementContext context) { + NonNullList stacks = getStacks(context); + if (stacks == null) + return; + ItemStackHelper.saveAllItems(context.tileData, stacks); + } + + @Override + public void stopMoving(MovementContext context) { + super.stopMoving(context); + writeExtraData(context); + } + + protected int getDispenseSlot(MovementContext context) { + int i = -1; + int j = 1; + NonNullList stacks = getStacks(context); + for (int k = 0; k < stacks.size(); ++k) { + if (!stacks.get(k).isEmpty() && RNG.nextInt(j++) == 0 && stacks.get(k).getCount() >= 2) { + i = k; + } + } + return i; + } +} 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 new file mode 100644 index 000000000..b8fdfca0a --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/IMovedDispenseItemBehaviour.java @@ -0,0 +1,146 @@ +package com.simibubi.create.content.contraptions.components.actors.dispenser; + +import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import net.minecraft.entity.IProjectile; +import net.minecraft.entity.item.ExperienceBottleEntity; +import net.minecraft.entity.item.FireworkRocketEntity; +import net.minecraft.entity.item.TNTEntity; +import net.minecraft.entity.projectile.*; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvents; +import net.minecraft.util.Util; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.IWorld; +import net.minecraft.world.World; + +import java.util.Random; + +public interface IMovedDispenseItemBehaviour { + static void init() { + DispenserMovementBehaviour.registerMovedDispenseItemBehaviour(Items.ARROW, new MovedProjectileDispenserBehaviour() { + @Override + protected IProjectile getProjectileEntity(World world, double x, double y, double z, ItemStack itemStack) { + ArrowEntity arrowEntity = new ArrowEntity(world, x, y, z); + arrowEntity.pickupStatus = AbstractArrowEntity.PickupStatus.ALLOWED; + return arrowEntity; + } + }); + + + DispenserMovementBehaviour.registerMovedDispenseItemBehaviour(Items.TIPPED_ARROW, new MovedProjectileDispenserBehaviour() { + @Override + protected IProjectile getProjectileEntity(World world, double x, double y, double z, ItemStack itemStack) { + ArrowEntity arrowEntity = new ArrowEntity(world, x, y, z); + arrowEntity.setPotionEffect(itemStack); + arrowEntity.pickupStatus = AbstractArrowEntity.PickupStatus.ALLOWED; + return arrowEntity; + } + }); + + DispenserMovementBehaviour.registerMovedDispenseItemBehaviour(Items.SPECTRAL_ARROW, new MovedProjectileDispenserBehaviour() { + @Override + protected IProjectile getProjectileEntity(World world, double x, double y, double z, ItemStack itemStack) { + AbstractArrowEntity arrowEntity = new SpectralArrowEntity(world, x, y, z); + arrowEntity.pickupStatus = AbstractArrowEntity.PickupStatus.ALLOWED; + return arrowEntity; + } + }); + + + DispenserMovementBehaviour.registerMovedDispenseItemBehaviour(Items.EGG, new MovedProjectileDispenserBehaviour() { + @Override + protected IProjectile getProjectileEntity(World world, double x, double y, double z, ItemStack itemStack) { + return Util.make(new EggEntity(world, x, y, z), p_218408_1_ -> p_218408_1_.setItem(itemStack)); + } + }); + + + DispenserMovementBehaviour.registerMovedDispenseItemBehaviour(Items.SNOWBALL, new MovedProjectileDispenserBehaviour() { + @Override + protected IProjectile getProjectileEntity(World world, double x, double y, double z, ItemStack itemStack) { + return Util.make(new SnowballEntity(world, x, y, z), p_218409_1_ -> p_218409_1_.setItem(itemStack)); + } + }); + + + DispenserMovementBehaviour.registerMovedDispenseItemBehaviour(Items.EXPERIENCE_BOTTLE, new MovedProjectileDispenserBehaviour() { + @Override + protected IProjectile getProjectileEntity(World world, double x, double y, double z, ItemStack itemStack) { + return Util.make(new ExperienceBottleEntity(world, x, y, z), p_218409_1_ -> p_218409_1_.setItem(itemStack)); + } + + @Override + protected float getProjectileInaccuracy() { + return super.getProjectileInaccuracy() * 0.5F; + } + + @Override + protected float getProjectileVelocity() { + return super.getProjectileVelocity() * 1.25F; + } + }); + + + DispenserMovementBehaviour.registerMovedDispenseItemBehaviour(Items.TNT, new MovedDefaultDispenseItemBehaviour() { + @Override + protected ItemStack dispenseStack(ItemStack itemStack, MovementContext context, BlockPos pos, Vec3d facing) { + double x = pos.getX() + facing.x * .7 + .5; + double y = pos.getY() + facing.y * .7 + .5; + double z = pos.getZ() + facing.z * .7 + .5; + TNTEntity tntentity = new TNTEntity(context.world, x, y, z, null); + tntentity.addVelocity(context.motion.x, context.motion.y, context.motion.z); + context.world.addEntity(tntentity); + context.world.playSound(null, tntentity.getX(), tntentity.getY(), tntentity.getZ(), SoundEvents.ENTITY_TNT_PRIMED, SoundCategory.BLOCKS, 1.0F, 1.0F); + itemStack.shrink(1); + return itemStack; + } + }); + + + DispenserMovementBehaviour.registerMovedDispenseItemBehaviour(Items.FIREWORK_ROCKET, new MovedDefaultDispenseItemBehaviour() { + @Override + protected ItemStack dispenseStack(ItemStack itemStack, MovementContext context, BlockPos pos, Vec3d facing) { + double x = pos.getX() + facing.x * .7 + .5; + double y = pos.getY() + facing.y * .7 + .5; + double z = pos.getZ() + facing.z * .7 + .5; + FireworkRocketEntity fireworkrocketentity = new FireworkRocketEntity(context.world, itemStack, x, y, z, true); + fireworkrocketentity.shoot(facing.x, facing.y, facing.z, 0.5F, 1.0F); + context.world.addEntity(fireworkrocketentity); + itemStack.shrink(1); + return itemStack; + } + + @Override + protected void playDispenseSound(IWorld world, BlockPos pos) { + world.playEvent(1004, pos, 0); + } + }); + + + DispenserMovementBehaviour.registerMovedDispenseItemBehaviour(Items.FIRE_CHARGE, new MovedDefaultDispenseItemBehaviour() { + @Override + protected void playDispenseSound(IWorld world, BlockPos pos) { + world.playEvent(1018, pos, 0); + } + + @Override + protected ItemStack dispenseStack(ItemStack itemStack, MovementContext context, BlockPos pos, Vec3d facing) { + Random random = context.world.rand; + double x = pos.getX() + facing.x * .7 + .5; + double y = pos.getY() + facing.y * .7 + .5; + double z = pos.getZ() + facing.z * .7 + .5; + context.world.addEntity(Util.make(new SmallFireballEntity(context.world, x, y, z, + random.nextGaussian() * 0.05D + facing.x + context.motion.x, random.nextGaussian() * 0.05D + facing.y + context.motion.y, random.nextGaussian() * 0.05D + facing.z + context.motion.z), (p_229425_1_) -> p_229425_1_.setStack(itemStack))); + itemStack.shrink(1); + return itemStack; + } + }); + + + } + + 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 new file mode 100644 index 000000000..73501171b --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/MovedDefaultDispenseItemBehaviour.java @@ -0,0 +1,66 @@ +package com.simibubi.create.content.contraptions.components.actors.dispenser; + +import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import com.simibubi.create.foundation.utility.VecHelper; +import net.minecraft.block.DispenserBlock; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.IWorld; +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_) { + 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; + if (Direction.getFacingFromVector(facing.x, facing.y, facing.z).getAxis() == Direction.Axis.Y) { + d1 = d1 - 0.125D; + } else { + d1 = d1 - 0.15625D; + } + + 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); + p_82486_0_.addEntity(itementity); + } + + @Override + public ItemStack dispense(ItemStack itemStack, MovementContext context, BlockPos pos) { + Vec3d facingVec = new Vec3d(context.state.get(DispenserBlock.FACING).getDirectionVec()); + facingVec = VecHelper.rotate(facingVec, context.rotation.x, context.rotation.y, context.rotation.z); + facingVec.normalize(); + + ItemStack itemstack = this.dispenseStack(itemStack, context, pos, facingVec); + this.playDispenseSound(context.world, pos); + this.spawnDispenseParticles(context.world, pos, facingVec); + return itemstack; + } + + /** + * Dispense the specified stack, play the dispense sound and spawn particles. + */ + protected ItemStack dispenseStack(ItemStack itemStack, MovementContext context, BlockPos pos, Vec3d facing) { + ItemStack itemstack = itemStack.split(1); + doDispense(context.world, itemstack, 6, facing, pos); + return itemStack; + } + + /** + * Play the dispense sound from the specified block. + */ + protected void playDispenseSound(IWorld world, BlockPos pos) { + world.playEvent(1000, pos, 0); + } + + /** + * 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()); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/MovedProjectileDispenserBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/MovedProjectileDispenserBehaviour.java new file mode 100644 index 000000000..924cefff0 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/dispenser/MovedProjectileDispenserBehaviour.java @@ -0,0 +1,40 @@ +package com.simibubi.create.content.contraptions.components.actors.dispenser; + +import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; +import net.minecraft.entity.Entity; +import net.minecraft.entity.IProjectile; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.IWorld; +import net.minecraft.world.World; + +public abstract class MovedProjectileDispenserBehaviour extends MovedDefaultDispenseItemBehaviour { + @Override + protected ItemStack dispenseStack(ItemStack itemStack, MovementContext context, BlockPos pos, Vec3d facing) { + double x = pos.getX() + facing.x * .7 + .5; + double y = pos.getY() + facing.y * .7 + .5; + double z = pos.getZ() + facing.z * .7 + .5; + IProjectile iprojectile = this.getProjectileEntity(context.world, x, y, z, itemStack); + Vec3d effectiveMovementVec = facing.scale(getProjectileVelocity()).add(context.motion); + iprojectile.shoot(effectiveMovementVec.x, effectiveMovementVec.y, effectiveMovementVec.z, (float) effectiveMovementVec.length(), this.getProjectileInaccuracy()); + context.world.addEntity((Entity) iprojectile); + itemStack.shrink(1); + return itemStack; + } + + @Override + protected void playDispenseSound(IWorld world, BlockPos pos) { + world.playEvent(1002, pos, 0); + } + + protected abstract IProjectile getProjectileEntity(World world, double x, double y, double z, ItemStack itemStack); + + protected float getProjectileInaccuracy() { + return 6.0F; + } + + protected float getProjectileVelocity() { + return 1.1F; + } +} diff --git a/src/main/resources/META-INF/accesstransformer.cfg b/src/main/resources/META-INF/accesstransformer.cfg index 5af4e7e17..e5bea6c04 100644 --- a/src/main/resources/META-INF/accesstransformer.cfg +++ b/src/main/resources/META-INF/accesstransformer.cfg @@ -1,4 +1,7 @@ public net.minecraft.network.play.ServerPlayNetHandler field_147365_f # floatingTickCount # CubeParticle -protected net.minecraft.client.particle.Particle field_228343_B_ # collidedY \ No newline at end of file +protected net.minecraft.client.particle.Particle field_228343_B_ # collidedY + +# Dispenser movement behaviour default +public net.minecraft.block.DispenserBlock func_149940_a(Lnet/minecraft/item/ItemStack;)Lnet/minecraft/dispenser/IDispenseItemBehavior; # getBehavior \ No newline at end of file