diff --git a/src/main/java/com/simibubi/create/AllInteractionBehaviours.java b/src/main/java/com/simibubi/create/AllInteractionBehaviours.java index ee99a46f8..7848d908e 100644 --- a/src/main/java/com/simibubi/create/AllInteractionBehaviours.java +++ b/src/main/java/com/simibubi/create/AllInteractionBehaviours.java @@ -1,48 +1,66 @@ package com.simibubi.create; +import java.util.HashMap; +import java.util.function.Supplier; + +import javax.annotation.Nullable; + +import com.google.common.collect.ImmutableList; import com.simibubi.create.content.contraptions.components.deployer.DeployerMovingInteraction; -import com.simibubi.create.content.contraptions.components.structureMovement.interaction.LeverMovingInteraction; import com.simibubi.create.content.contraptions.components.structureMovement.MovingInteractionBehaviour; +import com.simibubi.create.content.contraptions.components.structureMovement.interaction.DoorMovingInteraction; +import com.simibubi.create.content.contraptions.components.structureMovement.interaction.LeverMovingInteraction; +import com.simibubi.create.content.contraptions.components.structureMovement.interaction.TrapdoorMovingInteraction; import net.minecraft.block.Block; import net.minecraft.block.Blocks; import net.minecraft.util.ResourceLocation; -import javax.annotation.Nullable; - -import java.util.HashMap; -import java.util.function.Supplier; - public class AllInteractionBehaviours { - private static final HashMap> INTERACT_BEHAVIOURS = new HashMap<>(); + private static final HashMap> INTERACT_BEHAVIOURS = + new HashMap<>(); - public static void addInteractionBehaviour (ResourceLocation loc, Supplier behaviour) { - if (INTERACT_BEHAVIOURS.containsKey(loc)) { + public static void addInteractionBehaviour(ResourceLocation loc, Supplier behaviour) { + if (INTERACT_BEHAVIOURS.containsKey(loc)) Create.LOGGER.warn("Interaction behaviour for " + loc.toString() + " was overridden"); - } INTERACT_BEHAVIOURS.put(loc, behaviour); } - public static void addInteractionBehavioiur (Block block, Supplier behaviour) { + public static void addInteractionBehaviour(Block block, Supplier behaviour) { addInteractionBehaviour(block.getRegistryName(), behaviour); } @Nullable - public static MovingInteractionBehaviour of (ResourceLocation loc) { - return (INTERACT_BEHAVIOURS.get(loc) == null) ? null : INTERACT_BEHAVIOURS.get(loc).get(); + public static MovingInteractionBehaviour of(ResourceLocation loc) { + return (INTERACT_BEHAVIOURS.get(loc) == null) ? null + : INTERACT_BEHAVIOURS.get(loc) + .get(); } @Nullable - public static MovingInteractionBehaviour of (Block block) { + public static MovingInteractionBehaviour of(Block block) { return of(block.getRegistryName()); } - public static boolean contains (Block block) { + public static boolean contains(Block block) { return INTERACT_BEHAVIOURS.containsKey(block.getRegistryName()); } - static void register () { + static void register() { addInteractionBehaviour(Blocks.LEVER.getRegistryName(), LeverMovingInteraction::new); addInteractionBehaviour(AllBlocks.DEPLOYER.getId(), DeployerMovingInteraction::new); + + // TODO: Scan registry for instanceof (-> modded door support) + + for (Block trapdoor : ImmutableList.of(Blocks.ACACIA_TRAPDOOR, Blocks.OAK_TRAPDOOR, Blocks.DARK_OAK_TRAPDOOR, + Blocks.SPRUCE_TRAPDOOR, Blocks.JUNGLE_TRAPDOOR, Blocks.BIRCH_TRAPDOOR, Blocks.WARPED_TRAPDOOR, + Blocks.CRIMSON_TRAPDOOR)) { + addInteractionBehaviour(trapdoor.getRegistryName(), TrapdoorMovingInteraction::new); + } + + for (Block door : ImmutableList.of(Blocks.ACACIA_DOOR, Blocks.OAK_DOOR, Blocks.DARK_OAK_DOOR, + Blocks.SPRUCE_DOOR, Blocks.JUNGLE_DOOR, Blocks.BIRCH_DOOR, Blocks.WARPED_DOOR, Blocks.CRIMSON_DOOR)) { + addInteractionBehaviour(door.getRegistryName(), DoorMovingInteraction::new); + } } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovingInteraction.java b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovingInteraction.java index 4c170fbc5..c942df926 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovingInteraction.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/deployer/DeployerMovingInteraction.java @@ -1,73 +1,77 @@ package com.simibubi.create.content.contraptions.components.deployer; +import org.apache.commons.lang3.tuple.MutablePair; + import com.simibubi.create.AllItems; -import com.simibubi.create.Create; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.content.contraptions.components.structureMovement.MovingInteractionBehaviour; - import com.simibubi.create.foundation.utility.NBTHelper; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.world.gen.feature.template.Template.BlockInfo; - import net.minecraft.world.server.ServerWorld; import net.minecraftforge.common.util.Constants; -import org.apache.commons.lang3.tuple.MutablePair; - public class DeployerMovingInteraction extends MovingInteractionBehaviour { + @Override - public boolean handlePlayerInteraction (PlayerEntity player, Hand activeHand, BlockPos localPos, AbstractContraptionEntity contraptionEntity) { - BlockInfo info = contraptionEntity.getContraption().getBlocks().get(localPos); - if (info == null) return false; + public boolean handlePlayerInteraction(PlayerEntity player, Hand activeHand, BlockPos localPos, + AbstractContraptionEntity contraptionEntity) { + BlockInfo info = contraptionEntity.getContraption() + .getBlocks() + .get(localPos); + if (info == null) + return false; MovementContext ctx = null; int index = -1; - for (MutablePair pair : contraptionEntity.getContraption().getActors()) { + for (MutablePair pair : contraptionEntity.getContraption() + .getActors()) { if (info.equals(pair.left)) { ctx = pair.right; - index = contraptionEntity.getContraption().getActors().indexOf(pair); + index = contraptionEntity.getContraption() + .getActors() + .indexOf(pair); break; } } - if (ctx == null) return false; + if (ctx == null) + return false; ItemStack heldStack = player.getItemInHand(activeHand); - // Create.LOGGER.info("<-CTX: " + ctx.data.toString()); - if (heldStack.getItem().equals(AllItems.WRENCH.get())) { + if (heldStack.getItem() + .equals(AllItems.WRENCH.get())) { DeployerTileEntity.Mode mode = NBTHelper.readEnum(ctx.tileData, "Mode", DeployerTileEntity.Mode.class); NBTHelper.writeEnum(ctx.tileData, "Mode", - mode==DeployerTileEntity.Mode.PUNCH ? DeployerTileEntity.Mode.USE : DeployerTileEntity.Mode.PUNCH - ); - // Create.LOGGER.info("Changed mode"); + mode == DeployerTileEntity.Mode.PUNCH ? DeployerTileEntity.Mode.USE : DeployerTileEntity.Mode.PUNCH); + } else { - if (ctx.world.isClientSide) return true; // we'll try again on the server side + if (ctx.world.isClientSide) + return true; // we'll try again on the server side DeployerFakePlayer fake = null; - if ( !(ctx.temporaryData instanceof DeployerFakePlayer) && ctx.world instanceof ServerWorld) { - ctx.temporaryData = new DeployerFakePlayer((ServerWorld) ctx.world); - } else { - fake = (DeployerFakePlayer)ctx.temporaryData; - } - if (fake == null) return false; - fake.inventory.load(ctx.tileData.getList("Inventory", Constants.NBT.TAG_COMPOUND)); - if (ctx.data.contains("HeldItem")) { - player.setItemInHand(activeHand, ItemStack.of(ctx.data.getCompound("HeldItem"))); - fake.setItemInHand(Hand.MAIN_HAND, heldStack); - ctx.tileData.put("HeldItem", heldStack.serializeNBT()); - ctx.data.put("HeldItem", heldStack.serializeNBT()); - } - ctx.tileData.remove("Inventory"); - ctx.temporaryData = fake; - // Create.LOGGER.info("Swapped items"); + + if (!(ctx.temporaryData instanceof DeployerFakePlayer) && ctx.world instanceof ServerWorld) { + DeployerFakePlayer deployerFakePlayer = new DeployerFakePlayer((ServerWorld) ctx.world); + deployerFakePlayer.inventory.load(ctx.tileData.getList("Inventory", Constants.NBT.TAG_COMPOUND)); + ctx.temporaryData = fake = deployerFakePlayer; + ctx.tileData.remove("Inventory"); + } else + fake = (DeployerFakePlayer) ctx.temporaryData; + + if (fake == null) + return false; + + ItemStack deployerItem = fake.getMainHandItem(); + player.setItemInHand(activeHand, deployerItem.copy()); + fake.setItemInHand(Hand.MAIN_HAND, heldStack.copy()); + ctx.tileData.put("HeldItem", heldStack.serializeNBT()); + ctx.data.put("HeldItem", heldStack.serializeNBT()); } - if (index >= 0) { - // Create.LOGGER.info("->CTX: " + ctx.data.toString()); + if (index >= 0) setContraptionActorData(contraptionEntity, index, info, ctx); - } return true; } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 7a6b98cd8..819efe7a9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -257,7 +257,8 @@ public abstract class Contraption { .stream() .map(MountedStorage::getItemHandler) .collect(Collectors.toList()); - inventory = new ContraptionInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); + inventory = + new ContraptionInvWrapper(Arrays.copyOf(list.toArray(), list.size(), IItemHandlerModifiable[].class)); List fluidHandlers = fluidStorage.values() .stream() @@ -320,7 +321,7 @@ public abstract class Contraption { if (!movementAllowed(state, world, pos)) throw AssemblyException.unmovableBlock(pos, state); if (state.getBlock() instanceof AbstractChassisBlock - && !moveChassis(world, pos, forcedDirection, frontier, visited)) + && !moveChassis(world, pos, forcedDirection, frontier, visited)) return false; if (AllBlocks.ADJUSTABLE_CRATE.has(state)) @@ -339,7 +340,7 @@ public abstract class Contraption { Direction offset = state.getValue(StickerBlock.FACING); BlockPos attached = pos.relative(offset); if (!visited.contains(attached) - && !BlockMovementChecks.isNotSupportive(world.getBlockState(attached), offset.getOpposite())) + && !BlockMovementChecks.isNotSupportive(world.getBlockState(attached), offset.getOpposite())) frontier.add(attached); } @@ -391,12 +392,12 @@ public abstract class Contraption { boolean wasVisited = visited.contains(offsetPos); boolean faceHasGlue = superglue.containsKey(offset); boolean blockAttachedTowardsFace = - BlockMovementChecks.isBlockAttachedTowards(blockState, world, offsetPos, offset.getOpposite()); + BlockMovementChecks.isBlockAttachedTowards(blockState, world, offsetPos, offset.getOpposite()); boolean brittle = BlockMovementChecks.isBrittle(blockState); boolean canStick = !brittle && state.canStickTo(blockState) && blockState.canStickTo(state); if (canStick) { if (state.getPistonPushReaction() == PushReaction.PUSH_ONLY - || blockState.getPistonPushReaction() == PushReaction.PUSH_ONLY) { + || blockState.getPistonPushReaction() == PushReaction.PUSH_ONLY) { canStick = false; } if (BlockMovementChecks.isNotSupportive(state, offset)) { @@ -408,7 +409,7 @@ public abstract class Contraption { } if (!wasVisited && (canStick || blockAttachedTowardsFace || faceHasGlue - || (offset == forcedDirection && !BlockMovementChecks.isNotSupportive(state, forcedDirection)))) + || (offset == forcedDirection && !BlockMovementChecks.isNotSupportive(state, forcedDirection)))) frontier.add(offsetPos); if (faceHasGlue) addGlue(superglue.get(offset)); @@ -432,7 +433,8 @@ public abstract class Contraption { frontier.add(offset); if (blockState.getBlock() instanceof MechanicalPistonBlock) { Direction pistonFacing = blockState.getValue(MechanicalPistonBlock.FACING); - if (pistonFacing == direction && blockState.getValue(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) + if (pistonFacing == direction + && blockState.getValue(MechanicalPistonBlock.STATE) == PistonState.EXTENDED) frontier.add(offset); } } @@ -492,7 +494,8 @@ public abstract class Contraption { if (d.getAxis() == facing.getAxis() && AllBlocks.GANTRY_SHAFT.has(offsetState) && offsetState.getValue(GantryShaftBlock.FACING) == facing) frontier.add(offset); - else if (AllBlocks.GANTRY_CARRIAGE.has(offsetState) && offsetState.getValue(GantryCarriageBlock.FACING) == d) + else if (AllBlocks.GANTRY_CARRIAGE.has(offsetState) + && offsetState.getValue(GantryCarriageBlock.FACING) == d) frontier.add(offset); } } @@ -700,8 +703,8 @@ public abstract class Contraption { }); superglue.clear(); - NBTHelper.iterateCompoundList(nbt.getList("Superglue", NBT.TAG_COMPOUND), c -> superglue - .add(Pair.of(NBTUtil.readBlockPos(c.getCompound("Pos")), Direction.from3DDataValue(c.getByte("Direction"))))); + NBTHelper.iterateCompoundList(nbt.getList("Superglue", NBT.TAG_COMPOUND), c -> superglue.add( + Pair.of(NBTUtil.readBlockPos(c.getCompound("Pos")), Direction.from3DDataValue(c.getByte("Direction"))))); seats.clear(); NBTHelper.iterateCompoundList(nbt.getList("Seats", NBT.TAG_COMPOUND), c -> seats.add(NBTUtil.readBlockPos(c))); @@ -725,7 +728,9 @@ public abstract class Contraption { interactors.clear(); NBTHelper.iterateCompoundList(nbt.getList("Interactors", NBT.TAG_COMPOUND), c -> { BlockPos pos = NBTUtil.readBlockPos(c.getCompound("Pos")); - interactors.put(pos, AllInteractionBehaviours.of(getBlocks().get(pos).state.getBlock())); + MovingInteractionBehaviour behaviour = AllInteractionBehaviours.of(getBlocks().get(pos).state.getBlock()); + if (behaviour != null) + interactors.put(pos, behaviour); }); if (spawnData) @@ -960,7 +965,7 @@ public abstract class Contraption { continue; BlockPos add = block.pos.offset(anchor) - .offset(offset); + .offset(offset); if (customBlockRemoval(world, add, block.state)) continue; BlockState oldState = world.getBlockState(add); @@ -991,14 +996,18 @@ public abstract class Contraption { // remove it again, so to prevent an error from being logged by double-removal we add the POI data back now // (code copied from ServerWorld.onBlockStateChange) ServerWorld serverWorld = (ServerWorld) world; - PointOfInterestType.forState(block.state).ifPresent(poiType -> { - world.getServer().execute(() -> { - serverWorld.getPoiManager().add(add, poiType); - DebugPacketSender.sendPoiAddedPacket(serverWorld, add); + PointOfInterestType.forState(block.state) + .ifPresent(poiType -> { + world.getServer() + .execute(() -> { + serverWorld.getPoiManager() + .add(add, poiType); + DebugPacketSender.sendPoiAddedPacket(serverWorld, add); + }); }); - }); - world.markAndNotifyBlock(add, world.getChunkAt(add), block.state, Blocks.AIR.defaultBlockState(), flags, 512); + world.markAndNotifyBlock(add, world.getChunkAt(add), block.state, Blocks.AIR.defaultBlockState(), flags, + 512); block.state.updateIndirectNeighbourShapes(world, add, flags & -2); } } @@ -1017,8 +1026,8 @@ public abstract class Contraption { if (nonBrittles) for (Direction face : Iterate.directions) - state = state.updateShape(face, world.getBlockState(targetPos.relative(face)), world, - targetPos, targetPos.relative(face)); + state = state.updateShape(face, world.getBlockState(targetPos.relative(face)), world, targetPos, + targetPos.relative(face)); BlockState blockState = world.getBlockState(targetPos); if (blockState.getDestroySpeed(world, targetPos) == -1 || (state.getCollisionShape(world, targetPos) @@ -1215,7 +1224,9 @@ public abstract class Contraption { return actors; } - public Map getInteractors () { return interactors; } + public Map getInteractors() { + return interactors; + } public void updateContainedFluid(BlockPos localPos, FluidStack containedFluid) { MountedFluidStorage mountedFluidStorage = fluidStorage.get(localPos); @@ -1228,6 +1239,11 @@ public abstract class Contraption { return new EmptyLighter(this); } + public void invalidateColliders() { + simplifiedEntityColliders = Optional.empty(); + gatherBBsOffThread(); + } + private void gatherBBsOffThread() { getContraptionWorld(); simplifiedEntityColliderProvider = CompletableFuture.supplyAsync(() -> { @@ -1254,10 +1270,10 @@ public abstract class Contraption { switch (axis) { case X: return getMaxDistSqr(blocks, BlockPos::getY, BlockPos::getZ); - case Y: - return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getZ); - case Z: - return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getY); + case Y: + return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getZ); + case Z: + return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getY); } throw new IllegalStateException("Impossible axis"); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovingInteractionBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovingInteractionBehaviour.java index bf2f9aa3b..67eeb10ff 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovingInteractionBehaviour.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MovingInteractionBehaviour.java @@ -1,32 +1,33 @@ package com.simibubi.create.content.contraptions.components.structureMovement; +import org.apache.commons.lang3.tuple.MutablePair; + import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; - import net.minecraft.world.gen.feature.template.Template.BlockInfo; -import org.apache.commons.lang3.tuple.MutablePair; - public abstract class MovingInteractionBehaviour { - public MovingInteractionBehaviour () { } - protected void setContraptionActorData (AbstractContraptionEntity contraptionEntity, int index, BlockInfo info, MovementContext ctx) { + public MovingInteractionBehaviour() {} + + protected void setContraptionActorData(AbstractContraptionEntity contraptionEntity, int index, BlockInfo info, + MovementContext ctx) { contraptionEntity.contraption.actors.remove(index); contraptionEntity.contraption.actors.add(index, MutablePair.of(info, ctx)); - // mark contraption to re-render because we changed actor data ContraptionRenderDispatcher.invalidate(contraptionEntity.contraption); } - protected void setContraptionBlockData (AbstractContraptionEntity contraptionEntity, BlockPos pos, BlockInfo info) { + protected void setContraptionBlockData(AbstractContraptionEntity contraptionEntity, BlockPos pos, BlockInfo info) { contraptionEntity.contraption.blocks.put(pos, info); - // mark contraption to re-render because we changed block data ContraptionRenderDispatcher.invalidate(contraptionEntity.contraption); } - public boolean handlePlayerInteraction (PlayerEntity player, Hand activeHand, BlockPos localPos, AbstractContraptionEntity contraptionEntity) { + public boolean handlePlayerInteraction(PlayerEntity player, Hand activeHand, BlockPos localPos, + AbstractContraptionEntity contraptionEntity) { return true; } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/interaction/DoorMovingInteraction.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/interaction/DoorMovingInteraction.java new file mode 100644 index 000000000..4f270588c --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/interaction/DoorMovingInteraction.java @@ -0,0 +1,38 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.interaction; + +import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; + +import net.minecraft.block.BlockState; +import net.minecraft.block.DoorBlock; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.state.properties.DoubleBlockHalf; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.SoundEvents; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.feature.template.Template.BlockInfo; + +public class DoorMovingInteraction extends SimpleBlockMovingInteraction { + + @Override + protected BlockState handle(PlayerEntity player, Contraption contraption, BlockPos pos, BlockState currentState) { + SoundEvent sound = + currentState.getValue(DoorBlock.OPEN) ? SoundEvents.WOODEN_DOOR_CLOSE : SoundEvents.WOODEN_DOOR_OPEN; + + BlockPos otherPos = currentState.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER ? pos.above() : pos.below(); + BlockInfo info = contraption.getBlocks() + .get(otherPos); + if (info.state.hasProperty(DoorBlock.OPEN)) + setContraptionBlockData(contraption.entity, otherPos, + new BlockInfo(info.pos, info.state.cycle(DoorBlock.OPEN), info.nbt)); + + float pitch = player.level.random.nextFloat() * 0.1F + 0.9F; + playSound(player, sound, pitch); + return currentState.cycle(DoorBlock.OPEN); + } + + @Override + protected boolean updateColliders() { + return true; + } + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/interaction/LeverMovingInteraction.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/interaction/LeverMovingInteraction.java index f1c901f17..5101374b3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/interaction/LeverMovingInteraction.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/interaction/LeverMovingInteraction.java @@ -1,27 +1,19 @@ package com.simibubi.create.content.contraptions.components.structureMovement.interaction; -import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; -import com.simibubi.create.content.contraptions.components.structureMovement.MovingInteractionBehaviour; +import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import net.minecraft.block.BlockState; +import net.minecraft.block.LeverBlock; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.state.properties.BlockStateProperties; -import net.minecraft.util.Hand; -import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvents; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.gen.feature.template.Template.BlockInfo; -public class LeverMovingInteraction extends MovingInteractionBehaviour { +public class LeverMovingInteraction extends SimpleBlockMovingInteraction { + @Override - public boolean handlePlayerInteraction(PlayerEntity player, Hand activeHand, BlockPos localPos, AbstractContraptionEntity contraptionEntity) { - BlockInfo info = contraptionEntity.getContraption().getBlocks().get(localPos); - BlockState newState = info.state.cycle(BlockStateProperties.POWERED); - setContraptionBlockData(contraptionEntity, localPos, new BlockInfo(info.pos, newState, info.nbt)); - player.getCommandSenderWorld().playSound( - null, player.blockPosition(), SoundEvents.LEVER_CLICK, SoundCategory.BLOCKS, 0.3f, - newState.getValue(BlockStateProperties.POWERED) ? 0.6f : 0.5f - ); - return true; + protected BlockState handle(PlayerEntity player, Contraption contraption, BlockPos pos, BlockState currentState) { + playSound(player, SoundEvents.LEVER_CLICK, currentState.getValue(LeverBlock.POWERED) ? 0.5f : 0.6f); + return currentState.cycle(LeverBlock.POWERED); } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/interaction/SimpleBlockMovingInteraction.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/interaction/SimpleBlockMovingInteraction.java new file mode 100644 index 000000000..05decf2a8 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/interaction/SimpleBlockMovingInteraction.java @@ -0,0 +1,45 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.interaction; + +import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; +import com.simibubi.create.content.contraptions.components.structureMovement.MovingInteractionBehaviour; + +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.Hand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.feature.template.Template.BlockInfo; + +public abstract class SimpleBlockMovingInteraction extends MovingInteractionBehaviour { + + @Override + public boolean handlePlayerInteraction(PlayerEntity player, Hand activeHand, BlockPos localPos, + AbstractContraptionEntity contraptionEntity) { + Contraption contraption = contraptionEntity.getContraption(); + BlockInfo info = contraption.getBlocks() + .get(localPos); + + BlockState newState = handle(player, contraption, localPos, info.state); + if (info.state == newState) + return false; + + setContraptionBlockData(contraptionEntity, localPos, new BlockInfo(info.pos, newState, info.nbt)); + if (updateColliders()) + contraption.invalidateColliders(); + return true; + } + + protected boolean updateColliders() { + return false; + } + + protected void playSound(PlayerEntity player, SoundEvent sound, float pitch) { + player.level.playSound(player, player.blockPosition(), sound, SoundCategory.BLOCKS, 0.3f, pitch); + } + + protected abstract BlockState handle(PlayerEntity player, Contraption contraption, BlockPos pos, + BlockState currentState); + +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/interaction/TrapdoorMovingInteraction.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/interaction/TrapdoorMovingInteraction.java new file mode 100644 index 000000000..752c96974 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/interaction/TrapdoorMovingInteraction.java @@ -0,0 +1,28 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.interaction; + +import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; + +import net.minecraft.block.BlockState; +import net.minecraft.block.TrapDoorBlock; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.util.SoundEvent; +import net.minecraft.util.SoundEvents; +import net.minecraft.util.math.BlockPos; + +public class TrapdoorMovingInteraction extends SimpleBlockMovingInteraction { + + @Override + protected BlockState handle(PlayerEntity player, Contraption contraption, BlockPos pos, BlockState currentState) { + SoundEvent sound = currentState.getValue(TrapDoorBlock.OPEN) ? SoundEvents.WOODEN_TRAPDOOR_CLOSE + : SoundEvents.WOODEN_TRAPDOOR_OPEN; + float pitch = player.level.random.nextFloat() * 0.1F + 0.9F; + playSound(player, sound, pitch); + return currentState.cycle(TrapDoorBlock.OPEN); + } + + @Override + protected boolean updateColliders() { + return true; + } + +}