From e9d2be34c0ed4c91165fac7dd10a50146fd1bb87 Mon Sep 17 00:00:00 2001 From: gnembon Date: Sat, 8 Jun 2019 01:11:34 -0300 Subject: [PATCH] cactus and block rotator --- src/main/java/carpet/CarpetSettings.java | 12 ++-- .../java/carpet/helpers/BlockRotator.java | 68 +++++++++++++------ .../carpet/mixins/Bootstrap_cactusMixin.java | 25 +++++++ .../java/carpet/mixins/DirectionMixin.java | 23 ++++++- .../DispenserBehaviour_cactusMixin.java | 21 ++++++ .../mixins/HopperBlock_cactusMixin.java | 26 +++++++ .../mixins/ItemUsageContext_cactusMixin.java | 27 ++++++++ ...rPlayerInteractionManager_cactusMixin.java | 30 ++++++++ src/main/resources/carpet.mixins.json | 7 +- 9 files changed, 209 insertions(+), 30 deletions(-) create mode 100644 src/main/java/carpet/mixins/Bootstrap_cactusMixin.java create mode 100644 src/main/java/carpet/mixins/DispenserBehaviour_cactusMixin.java create mode 100644 src/main/java/carpet/mixins/HopperBlock_cactusMixin.java create mode 100644 src/main/java/carpet/mixins/ItemUsageContext_cactusMixin.java create mode 100644 src/main/java/carpet/mixins/ServerPlayerInteractionManager_cactusMixin.java diff --git a/src/main/java/carpet/CarpetSettings.java b/src/main/java/carpet/CarpetSettings.java index 203d6ec4..1ab584e8 100644 --- a/src/main/java/carpet/CarpetSettings.java +++ b/src/main/java/carpet/CarpetSettings.java @@ -105,7 +105,7 @@ public class CarpetSettings .defaultTrue().wip(), rule("flippinCactus", "creative survival", "Players can flip and rotate blocks when holding cactus") .extraInfo("Doesn't cause block updates when rotated/flipped", - "Applies to pistons, observers, droppers, repeaters, stairs, glazed terracotta etc...").wip(), + "Applies to pistons, observers, droppers, repeaters, stairs, glazed terracotta etc..."), rule("hopperCounters", "commands creative survival","hoppers pointing to wool will count items passing through them") .extraInfo("Enables /counter command, and actions while placing red and green carpets on wool blocks", "Use /counter reset to reset the counter, and /counter to query", @@ -162,7 +162,7 @@ public class CarpetSettings ((MinecraftServer_motdInterface)CarpetServer.minecraft_server).checkMOTD()), rule("rotatorBlock", "experimental", "Cactus in dispensers rotates blocks.") .extraInfo("Cactus in a dispenser gives the dispenser the ability to rotate the blocks " + - "that are in front of it anti-clockwise if possible.").wip(), + "that are in front of it anti-clockwise if possible."), rule("viewDistance", "creative", "Changes the view distance of the server.") .extraInfo("Set to 0 to not override the value in server settings.") .choices("0", "0 12 16 32 64").setNotStrict() @@ -724,8 +724,12 @@ public class CarpetSettings public CarpetSettingEntry wip() { return validate( (s, n) -> { - if (s != null) - Messenger.m(s, "r Work in progress - limited or no functionality available for "+n); + if (s != null) + try + { + Messenger.m(s, "r Work in progress - limited or no functionality available for "+n); + } + catch (NullPointerException ignored) { } }); } } diff --git a/src/main/java/carpet/helpers/BlockRotator.java b/src/main/java/carpet/helpers/BlockRotator.java index b3cc2b32..68b71b5e 100644 --- a/src/main/java/carpet/helpers/BlockRotator.java +++ b/src/main/java/carpet/helpers/BlockRotator.java @@ -21,6 +21,7 @@ import net.minecraft.block.RepeaterBlock; import net.minecraft.block.SlabBlock; import net.minecraft.block.StairsBlock; import net.minecraft.block.TrapdoorBlock; +import net.minecraft.block.dispenser.FallibleItemDispenserBehavior; import net.minecraft.block.enums.BlockHalf; import net.minecraft.block.enums.ComparatorMode; import net.minecraft.block.enums.SlabType; @@ -31,6 +32,7 @@ import net.minecraft.item.ItemPlacementContext; import net.minecraft.item.ItemStack; import net.minecraft.util.BlockRotation; import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPointer; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; @@ -40,13 +42,16 @@ import net.minecraft.world.World; public class BlockRotator { - public static boolean flipBlockWithCactus(World worldIn, BlockPos pos, BlockState state, PlayerEntity playerIn, Hand hand, Direction facing, float hitX, float hitY, float hitZ) + public static boolean flipBlockWithCactus(BlockState state, World world, PlayerEntity player, Hand hand, BlockHitResult hit) { - if (!playerIn.abilities.allowModifyWorld || !CarpetSettings.getBool("flippinCactus") || !player_holds_cactus_mainhand(playerIn)) + if (!player.abilities.allowModifyWorld || !CarpetSettings.getBool("flippinCactus") || !player_holds_cactus_mainhand(player)) { return false; } - return flip_block(worldIn, pos, state, playerIn, hand, facing, hitX, hitY, hitZ); + CarpetSettings.impendingFillSkipUpdates = true; + boolean retval = flip_block(state, world, player, hand, hit); + CarpetSettings.impendingFillSkipUpdates = false; + return retval; } public static BlockState alternativeBlockPlacement(Block block, ItemPlacementContext context)//World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer) @@ -185,66 +190,69 @@ public class BlockRotator - public static boolean flip_block(World worldIn, BlockPos pos, BlockState state, PlayerEntity playerIn, Hand hand, Direction facing, float hitX, float hitY, float hitZ) + public static boolean flip_block(BlockState state, World world, PlayerEntity player, Hand hand, BlockHitResult hit) { Block block = state.getBlock(); + BlockPos pos = hit.getBlockPos(); + Vec3d hitVec = hit.getPos().subtract(pos.getX(), pos.getY(), pos.getZ()); + Direction facing = hit.getSide(); if ( (block instanceof GlazedTerracottaBlock) || (block instanceof AbstractRedstoneGateBlock) || (block instanceof RailBlock) || (block instanceof TrapdoorBlock) || (block instanceof LeverBlock) || (block instanceof FenceGateBlock)) { - worldIn.setBlockState(pos, block.rotate(state, BlockRotation.CLOCKWISE_90), 2 | 1024); + world.setBlockState(pos, state.rotate(BlockRotation.CLOCKWISE_90), 2 | 1024); } else if ((block instanceof ObserverBlock) || (block instanceof EndRodBlock)) { - worldIn.setBlockState(pos, state.with(FacingBlock.FACING, (Direction) state.get(FacingBlock.FACING).getOpposite()), 2 | 1024); + world.setBlockState(pos, state.with(FacingBlock.FACING, (Direction) state.get(FacingBlock.FACING).getOpposite()), 2 | 1024); } else if (block instanceof DispenserBlock) { - worldIn.setBlockState(pos, state.with(DispenserBlock.FACING, state.get(DispenserBlock.FACING).getOpposite()), 2 | 1024); + world.setBlockState(pos, state.with(DispenserBlock.FACING, state.get(DispenserBlock.FACING).getOpposite()), 2 | 1024); } else if (block instanceof PistonBlock) { if (!(state.get(PistonBlock.EXTENDED))) - worldIn.setBlockState(pos, state.with(FacingBlock.FACING, state.get(FacingBlock.FACING).getOpposite()), 2 | 1024); + world.setBlockState(pos, state.with(FacingBlock.FACING, state.get(FacingBlock.FACING).getOpposite()), 2 | 1024); } else if (block instanceof SlabBlock) { if (((SlabBlock) block).hasSidedTransparency(state)) { - worldIn.setBlockState(pos, state.with(SlabBlock.TYPE, state.get(SlabBlock.TYPE) == SlabType.TOP ? SlabType.BOTTOM : SlabType.TOP), 2 | 1024); + world.setBlockState(pos, state.with(SlabBlock.TYPE, state.get(SlabBlock.TYPE) == SlabType.TOP ? SlabType.BOTTOM : SlabType.TOP), 2 | 1024); } } else if (block instanceof HopperBlock) { if ((Direction)state.get(HopperBlock.FACING) != Direction.DOWN) { - worldIn.setBlockState(pos, state.with(HopperBlock.FACING, state.get(HopperBlock.FACING).rotateYClockwise()), 2 | 1024); + world.setBlockState(pos, state.with(HopperBlock.FACING, state.get(HopperBlock.FACING).rotateYClockwise()), 2 | 1024); } } else if (block instanceof StairsBlock) { //LOG.error(String.format("hit with facing: %s, at side %.1fX, X %.1fY, Y %.1fZ",facing, hitX, hitY, hitZ)); - if ((facing == Direction.UP && hitY == 1.0f) || (facing == Direction.DOWN && hitY == 0.0f)) + if ((facing == Direction.UP && hitVec.y == 1.0f) || (facing == Direction.DOWN && hitVec.y == 0.0f)) { - worldIn.setBlockState(pos, state.with(StairsBlock.HALF, state.get(StairsBlock.HALF) == BlockHalf.TOP ? BlockHalf.BOTTOM : BlockHalf.TOP ), 2 | 1024); + world.setBlockState(pos, state.with(StairsBlock.HALF, state.get(StairsBlock.HALF) == BlockHalf.TOP ? BlockHalf.BOTTOM : BlockHalf.TOP ), 2 | 1024); } else { boolean turn_right; if (facing == Direction.NORTH) { - turn_right = (hitX <= 0.5); + turn_right = (hitVec.x <= 0.5); } else if (facing == Direction.SOUTH) { - turn_right = !(hitX <= 0.5); + turn_right = !(hitVec.x <= 0.5); } else if (facing == Direction.EAST) { - turn_right = (hitZ <= 0.5); + turn_right = (hitVec.z <= 0.5); } else if (facing == Direction.WEST) { - turn_right = !(hitZ <= 0.5); + turn_right = !(hitVec.z <= 0.5); } else { @@ -252,11 +260,11 @@ public class BlockRotator } if (turn_right) { - worldIn.setBlockState(pos, block.rotate(state, BlockRotation.COUNTERCLOCKWISE_90), 2 | 1024); + world.setBlockState(pos, state.rotate(BlockRotation.COUNTERCLOCKWISE_90), 2 | 1024); } else { - worldIn.setBlockState(pos, block.rotate(state, BlockRotation.CLOCKWISE_90), 2 | 1024); + world.setBlockState(pos, state.rotate(BlockRotation.CLOCKWISE_90), 2 | 1024); } } } @@ -264,7 +272,7 @@ public class BlockRotator { return false; } - worldIn.scheduleBlockRender(pos); + world.scheduleBlockRender(pos); return true; } private static boolean player_holds_cactus_mainhand(PlayerEntity playerIn) @@ -279,10 +287,26 @@ public class BlockRotator && (entity instanceof PlayerEntity)) { PlayerEntity player = (PlayerEntity)entity; - return (!player.getMainHandStack().isEmpty() - && player.getMainHandStack().getItem() instanceof BlockItem && - ((BlockItem) (player.getMainHandStack().getItem())).getBlock() == Blocks.CACTUS); + return (!player.getOffHandStack().isEmpty() + && player.getOffHandStack().getItem() instanceof BlockItem && + ((BlockItem) (player.getOffHandStack().getItem())).getBlock() == Blocks.CACTUS); } return false; } + + public static class CactusDispenserBehaviour extends FallibleItemDispenserBehavior + { + @Override + protected ItemStack dispenseSilently(BlockPointer source, ItemStack stack) + { + if (CarpetSettings.getBool("rotatorBlock")) + { + return BlockRotator.dispenserRotate(source, stack); + } + else + { + return super.dispenseSilently(source, stack); + } + } + } } diff --git a/src/main/java/carpet/mixins/Bootstrap_cactusMixin.java b/src/main/java/carpet/mixins/Bootstrap_cactusMixin.java new file mode 100644 index 00000000..6002743c --- /dev/null +++ b/src/main/java/carpet/mixins/Bootstrap_cactusMixin.java @@ -0,0 +1,25 @@ +package carpet.mixins; + +import carpet.helpers.BlockRotator; +import net.minecraft.Bootstrap; +import net.minecraft.block.Blocks; +import net.minecraft.block.DispenserBlock; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Bootstrap.class) +public abstract class Bootstrap_cactusMixin +{ + @Inject(method = "initialize", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/dispenser/DispenserBehavior;registerDefaults()V", + shift = At.Shift.AFTER + )) + private static void registerCactus(CallbackInfo ci) + { + DispenserBlock.registerBehavior(Blocks.CACTUS.asItem(), new BlockRotator.CactusDispenserBehaviour()); + } + +} diff --git a/src/main/java/carpet/mixins/DirectionMixin.java b/src/main/java/carpet/mixins/DirectionMixin.java index 76bd9a3e..adfeeda3 100644 --- a/src/main/java/carpet/mixins/DirectionMixin.java +++ b/src/main/java/carpet/mixins/DirectionMixin.java @@ -2,6 +2,7 @@ package carpet.mixins; import carpet.CarpetSettings; import carpet.fakes.EntityInterface; +import carpet.helpers.BlockRotator; import net.minecraft.entity.Entity; import net.minecraft.util.math.Direction; import org.spongepowered.asm.mixin.Mixin; @@ -12,15 +13,31 @@ import org.spongepowered.asm.mixin.injection.Redirect; public abstract class DirectionMixin { @Redirect(method = "getEntityFacingOrder", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getYaw(F)F")) - private static float ifGetYaw(Entity entity, float float_1) + private static float getYaw(Entity entity, float float_1) { + float yaw; if (!CarpetSettings.getBool("placementRotationFix")) { - return entity.getYaw(1.0F); + yaw = entity.getYaw(float_1); } else { - return ((EntityInterface) entity).getMainYaw(1.0F); + yaw = ((EntityInterface) entity).getMainYaw(float_1); } + if (BlockRotator.flippinEligibility(entity)) + { + yaw += 180f; + } + return yaw; + } + @Redirect(method = "getEntityFacingOrder", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getPitch(F)F")) + private static float getPitch(Entity entity, float float_1) + { + float pitch = entity.getPitch(float_1); + if (BlockRotator.flippinEligibility(entity)) + { + pitch = -pitch; + } + return pitch; } } diff --git a/src/main/java/carpet/mixins/DispenserBehaviour_cactusMixin.java b/src/main/java/carpet/mixins/DispenserBehaviour_cactusMixin.java new file mode 100644 index 00000000..39535c64 --- /dev/null +++ b/src/main/java/carpet/mixins/DispenserBehaviour_cactusMixin.java @@ -0,0 +1,21 @@ +package carpet.mixins; + +import carpet.helpers.BlockRotator; +import net.minecraft.block.Blocks; +import net.minecraft.block.DispenserBlock; +import net.minecraft.block.dispenser.DispenserBehavior; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +//UNUSED - used Bootstrap_cactus instead cause mixins +@Mixin(DispenserBehavior.class) +public interface DispenserBehaviour_cactusMixin +{ + @Inject(method = "registerDefaults", at = @At("HEAD")) + static void addBlockRotator(CallbackInfo ci) + { + DispenserBlock.registerBehavior(Blocks.CACTUS.asItem(), new BlockRotator.CactusDispenserBehaviour()); + } +} diff --git a/src/main/java/carpet/mixins/HopperBlock_cactusMixin.java b/src/main/java/carpet/mixins/HopperBlock_cactusMixin.java new file mode 100644 index 00000000..5eed6fd6 --- /dev/null +++ b/src/main/java/carpet/mixins/HopperBlock_cactusMixin.java @@ -0,0 +1,26 @@ +package carpet.mixins; + +import carpet.helpers.BlockRotator; +import net.minecraft.block.HopperBlock; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.util.math.Direction; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(HopperBlock.class) +public class HopperBlock_cactusMixin +{ + @Redirect(method = "getPlacementState", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/item/ItemPlacementContext;getSide()Lnet/minecraft/util/math/Direction;" + )) + private Direction getOppositeOpposite(ItemPlacementContext context) + { + if (BlockRotator.flippinEligibility(context.getPlayer())) + { + return context.getSide().getOpposite(); + } + return context.getSide(); + } +} diff --git a/src/main/java/carpet/mixins/ItemUsageContext_cactusMixin.java b/src/main/java/carpet/mixins/ItemUsageContext_cactusMixin.java new file mode 100644 index 00000000..5f9d86b1 --- /dev/null +++ b/src/main/java/carpet/mixins/ItemUsageContext_cactusMixin.java @@ -0,0 +1,27 @@ +package carpet.mixins; + +import carpet.helpers.BlockRotator; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemUsageContext; +import net.minecraft.util.math.Direction; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(ItemUsageContext.class) +public class ItemUsageContext_cactusMixin +{ + @Redirect(method = "getPlayerFacing", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/entity/player/PlayerEntity;getHorizontalFacing()Lnet/minecraft/util/math/Direction;" + )) + private Direction getPlayerFacing(PlayerEntity playerEntity) + { + Direction dir = playerEntity.getHorizontalFacing(); + if (BlockRotator.flippinEligibility(playerEntity)) + { + dir = dir.getOpposite(); + } + return dir; + } +} diff --git a/src/main/java/carpet/mixins/ServerPlayerInteractionManager_cactusMixin.java b/src/main/java/carpet/mixins/ServerPlayerInteractionManager_cactusMixin.java new file mode 100644 index 00000000..3a405cf2 --- /dev/null +++ b/src/main/java/carpet/mixins/ServerPlayerInteractionManager_cactusMixin.java @@ -0,0 +1,30 @@ +package carpet.mixins; + +import carpet.helpers.BlockRotator; +import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.network.ServerPlayerInteractionManager; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.world.World; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(ServerPlayerInteractionManager.class) +public class ServerPlayerInteractionManager_cactusMixin +{ + + @Redirect(method = "interactBlock", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/BlockState;activate(Lnet/minecraft/world/World;Lnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/util/Hand;Lnet/minecraft/util/hit/BlockHitResult;)Z" + )) + private boolean activateWithOptionalCactus(BlockState blockState, World world_1, PlayerEntity playerEntity_1, Hand hand_1, BlockHitResult blockHitResult_1) + { + Boolean flipped = BlockRotator.flipBlockWithCactus(blockState, world_1, playerEntity_1, hand_1, blockHitResult_1); + if (flipped) + return true; + + return blockState.activate(world_1, playerEntity_1, hand_1, blockHitResult_1); + } +} diff --git a/src/main/resources/carpet.mixins.json b/src/main/resources/carpet.mixins.json index c4fd48f5..89f9771e 100644 --- a/src/main/resources/carpet.mixins.json +++ b/src/main/resources/carpet.mixins.json @@ -53,12 +53,17 @@ "PlayerEntity_parrotMixin", "SaplingBlockMixin", "EntityMixin", - "DirectionMixin", "GuardianEntityMixin", "ServerChunkManagerMixin", "SpawnHelperMixin", + "DirectionMixin", + "ServerPlayerInteractionManager_cactusMixin", + "HopperBlock_cactusMixin", + "ItemUsageContext_cactusMixin", + "Bootstrap_cactusMixin", + "HopperBlockEntityMixin", "ContainerMixin", "ClientConnectionMixin",