Fix Glass bottle moved dispense behaviour, fix filter for pulled items

This commit is contained in:
grimmauld 2020-09-02 10:20:11 +02:00
parent 7e4ca0475e
commit c81e105964
5 changed files with 71 additions and 10 deletions

View file

@ -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
}
}
}

View file

@ -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<ItemStack> getStacks(MovementContext context) {
if (!(context.temporaryData instanceof NonNullList) && context.world instanceof ServerWorld) {
NonNullList<ItemStack> stacks = NonNullList.withSize(9, ItemStack.EMPTY);

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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);
}
}