From f240edfa22030fb4737f8af6071c790589c1baca Mon Sep 17 00:00:00 2001 From: Sakura Ryoko Date: Sat, 29 Jun 2024 21:15:23 -0400 Subject: [PATCH] Attempting to fix accurate placement protocol for the Crafter (Doesn't yet work) --- gradle.properties | 6 +- .../java/fi/dy/masa/tweakeroo/Tweakeroo.java | 9 + .../dy/masa/tweakeroo/config/Callbacks.java | 3 +- .../fi/dy/masa/tweakeroo/config/Configs.java | 13 +- .../fi/dy/masa/tweakeroo/config/Hotkeys.java | 6 +- .../dy/masa/tweakeroo/data/DataManager.java | 38 +++ .../masa/tweakeroo/mixin/MixinBlockItem.java | 5 +- .../MixinClientCommonNetworkHandler.java | 24 ++ .../mixin/MixinClientPlayNetworkHandler.java | 13 + .../tweakeroo/tweaks/PlacementHandler.java | 289 +++++++++++++++--- .../tweaks/PlacementHandler_V2Only.java | 176 +++++++++++ .../tweakeroo/tweaks/PlacementTweaks.java | 49 +-- .../tweakeroo/util/EasyPlacementProtocol.java | 79 +++++ .../assets/tweakeroo/lang/en_us.json | 6 + src/main/resources/fabric.mod.json | 2 +- src/main/resources/mixins.tweakeroo.json | 171 ++++++----- 16 files changed, 721 insertions(+), 168 deletions(-) create mode 100644 src/main/java/fi/dy/masa/tweakeroo/data/DataManager.java create mode 100644 src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientCommonNetworkHandler.java create mode 100644 src/main/java/fi/dy/masa/tweakeroo/tweaks/PlacementHandler_V2Only.java create mode 100644 src/main/java/fi/dy/masa/tweakeroo/util/EasyPlacementProtocol.java diff --git a/gradle.properties b/gradle.properties index 9ee533dbc..81e3b2c8f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,11 +9,11 @@ author = masa mod_file_name = tweakeroo-fabric # Current mod version -mod_version = 0.20.999-sakura.8 +mod_version = 0.20.999-sakura.8-accurate_placement.1 # Required malilib version -malilib_version = 0.19.999-sakura.3 -malilib_id = b012771deb +malilib_version = 0.19.999-sakura.5 +malilib_id = eed5e992ac # Minecraft, Fabric Loader and API and mappings versions minecraft_version_out = 1.21 diff --git a/src/main/java/fi/dy/masa/tweakeroo/Tweakeroo.java b/src/main/java/fi/dy/masa/tweakeroo/Tweakeroo.java index ea590e944..98320dec0 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/Tweakeroo.java +++ b/src/main/java/fi/dy/masa/tweakeroo/Tweakeroo.java @@ -4,6 +4,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import fi.dy.masa.malilib.event.InitializationHandler; +import fi.dy.masa.tweakeroo.config.Configs; public class Tweakeroo implements ModInitializer { @@ -17,4 +18,12 @@ public void onInitialize() { InitializationHandler.getInstance().registerInitializationHandler(new InitHandler()); } + + public static void debugLog(String msg, Object... args) + { + if (Configs.Generic.DEBUG_LOGGING.getBooleanValue()) + { + Tweakeroo.logger.info(msg, args); + } + } } diff --git a/src/main/java/fi/dy/masa/tweakeroo/config/Callbacks.java b/src/main/java/fi/dy/masa/tweakeroo/config/Callbacks.java index fc49169ed..2f1aa66b1 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/config/Callbacks.java +++ b/src/main/java/fi/dy/masa/tweakeroo/config/Callbacks.java @@ -90,7 +90,8 @@ public static void init(MinecraftClient mc) Hotkeys.SIT_DOWN_NEARBY_PETS.getKeybind().setCallback((a, k) -> MiscUtils.commandNearbyPets(true)); Hotkeys.STAND_UP_NEARBY_PETS.getKeybind().setCallback((a, k) -> MiscUtils.commandNearbyPets(false)); Hotkeys.SWAP_ELYTRA_CHESTPLATE.getKeybind().setCallback(callbackGeneric); - Hotkeys.TOGGLE_CARPET_AP_PROTOCOL.getKeybind().setCallback(new KeyCallbackToggleBooleanConfigWithMessage(Configs.Generic.CARPET_ACCURATE_PLACEMENT_PROTOCOL)); + //Hotkeys.TOGGLE_CARPET_AP_PROTOCOL.getKeybind().setCallback(new KeyCallbackToggleBooleanConfigWithMessage(Configs.Generic.CARPET_ACCURATE_PLACEMENT_PROTOCOL)); + Hotkeys.TOGGLE_AP_PROTOCOL.getKeybind().setCallback(new KeyCallbackToggleBooleanConfigWithMessage(Configs.Generic.ACCURATE_PLACEMENT_PROTOCOL)); Hotkeys.TOGGLE_GRAB_CURSOR.getKeybind().setCallback(callbackGeneric); Hotkeys.TOOL_PICK.getKeybind().setCallback(callbackGeneric); Hotkeys.WRITE_MAPS_AS_IMAGES.getKeybind().setCallback((a, k) -> MiscUtils.writeAllMapsAsImages()); diff --git a/src/main/java/fi/dy/masa/tweakeroo/config/Configs.java b/src/main/java/fi/dy/masa/tweakeroo/config/Configs.java index c4195387f..3d0d76b49 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/config/Configs.java +++ b/src/main/java/fi/dy/masa/tweakeroo/config/Configs.java @@ -26,6 +26,7 @@ import fi.dy.masa.tweakeroo.Reference; import fi.dy.masa.tweakeroo.tweaks.MiscTweaks; import fi.dy.masa.tweakeroo.tweaks.PlacementTweaks; +import fi.dy.masa.tweakeroo.util.EasyPlacementProtocol; import fi.dy.masa.tweakeroo.util.InventoryUtils; import fi.dy.masa.tweakeroo.util.PlacementRestrictionMode; import fi.dy.masa.tweakeroo.util.SnapAimMode; @@ -36,6 +37,8 @@ public class Configs implements IConfigHandler public static class Generic { + public static final ConfigOptionList ACCURATE_PLACEMENT_PROTOCOL_MODE = new ConfigOptionList ("accuratePlacementProtocolMode", EasyPlacementProtocol.AUTO, "The type of \"accurate placement protocol\" to use.\n- Auto: Uses v3 in single player, and by default Slabs-only in multiplayer,\n unless the server has Carpet mod that sends a 'carpet:hello'\n packet, in which case v2 is used on that server.\n- Version 3: Supported by Tweakeroo itself (in single player) for now.\n- Version 2: Compatible with servers with the Carpet mod\n (either QuickCarpet by skyrising and DeadlyMC,\n or CarpetExtra in addition to FabricCarpet.\n And in both cases the 'accurateBlockPlacement' Carpet rule needs\n to be enabled on the server).\n- Slabs only: Only fixes top slabs. Compatible with Paper servers.\n- None: Does not modify coordinates."); + public static final ConfigBoolean ACCURATE_PLACEMENT_PROTOCOL = new ConfigBoolean ("accuratePlacementProtocol", true, "If enabled, then the Flexible Block Placement and the\nAccurate Block Placement use the protocol implemented in Carpet mod.\n§6Note: This is required for any block rotations to work, other than\n§6blocks that only care about the block side you click on (Hoppers, Logs etc.)"); public static final ConfigInteger AFTER_CLICKER_CLICK_COUNT = new ConfigInteger ("afterClickerClickCount", 1, 1, 32, "The number of right clicks to do per placed block when\ntweakAfterClicker is enabled"); public static final ConfigDouble ANGEL_BLOCK_PLACEMENT_DISTANCE = new ConfigDouble ("angelBlockPlacementDistance", 3, 1, 5, "The distance from the player blocks can be placed in\nthe air when tweakAngelBlock is enabled.\n5 is the maximum the server allows."); public static final ConfigDouble BLOCK_REACH_DISTANCE = new ConfigDouble ("blockReachDistance", 4.5, 1, 64, "The block reach distance to use if the override tweak is enabled.\nThe maximum the game allows is 64.\n§6Do not attempt to use this at a value beyond\n[0.5 - 1.0] higher than the Game Rules defined on a server."); @@ -44,10 +47,10 @@ public static class Generic public static final ConfigOptionList BREAKING_RESTRICTION_MODE = new ConfigOptionList ("breakingRestrictionMode", PlacementRestrictionMode.LINE, "The Breaking Restriction mode to use (hotkey-selectable)"); public static final ConfigColor CHAT_BACKGROUND_COLOR = new ConfigColor ("chatBackgroundColor", "#80000000", "The background color for the chat messages,\nif 'tweakChatBackgroundColor' is enabled"); public static final ConfigString CHAT_TIME_FORMAT = new ConfigString ("chatTimeFormat", "[HH:mm:ss]", "The time format for chat messages, if tweakChatTimestamp is enabled\nUses the Java SimpleDateFormat format specifiers."); - public static final ConfigBoolean CARPET_ACCURATE_PLACEMENT_PROTOCOL = new ConfigBoolean ("carpetAccuratePlacementProtocol", true, "If enabled, then the Flexible Block Placement and the\nAccurate Block Placement use the protocol implemented in Carpet mod.\n§6Note: This is required for any block rotations to work, other than\n§6blocks that only care about the block side you click on (Hoppers, Logs etc.)"); + //public static final ConfigBoolean CARPET_ACCURATE_PLACEMENT_PROTOCOL = new ConfigBoolean ("carpetAccuratePlacementProtocol", true, "If enabled, then the Flexible Block Placement and the\nAccurate Block Placement use the protocol implemented in Carpet mod.\n§6Note: This is required for any block rotations to work, other than\n§6blocks that only care about the block side you click on (Hoppers, Logs etc.)"); public static final ConfigBoolean CLIENT_PLACEMENT_ROTATION = new ConfigBoolean ("clientPlacementRotation", true, "Enable single player and client side placement rotations,\nsuch as Accurate Placement working in single player without Carpet mod"); public static final ConfigInteger CUSTOM_INVENTORY_GUI_SCALE = new ConfigInteger ("customInventoryGuiScale", 2, 1, 10, "The GUI scale value to use for inventory screens, if\n§etweakCustomInventoryScreenScale§r is enabled."); - //public static final ConfigBoolean DEBUG_LOGGING = new ConfigBoolean ("debugLogging", false, "Enables some debug log messages in the game console,\nfor debugging certain issues or crashes."); + public static final ConfigBoolean DEBUG_LOGGING = new ConfigBoolean ("debugLogging", false, "Enables some debug log messages in the game console,\nfor debugging certain issues or crashes."); public static final ConfigOptionList ELYTRA_CAMERA_INDICATOR = new ConfigOptionList ("elytraCameraIndicator", ActiveMode.WITH_KEY, "Whether or not to render the real pitch angle\nindicator when the elytra camera mode is active"); public static final ConfigDouble ENTITY_REACH_DISTANCE = new ConfigDouble ("entityReachDistance", 3.0, 1, 64, "The entity reach distance to use if the override tweak is enabled.\nThe maximum the game allows is 64.\n§6Do not attempt to use this at a value beyond\n[0.5 - 1.0] higher than the Game Rules defined on a server."); public static final ConfigOptionList ENTITY_TYPE_ATTACK_RESTRICTION_WARN = new ConfigOptionList ("entityTypeAttackRestrictionWarn", MessageOutputType.MESSAGE, "Selects which type of warning message to show (if any)\nwhen the Entity Type Attack Restriction feature prevents attacking an entity"); @@ -117,9 +120,11 @@ public static class Generic public static final ConfigDouble ZOOM_FOV = new ConfigDouble ("zoomFov", 30, 0.01, 359.99, "The FOV value used for the zoom feature"); public static final ImmutableList OPTIONS = ImmutableList.of( - CARPET_ACCURATE_PLACEMENT_PROTOCOL, + ACCURATE_PLACEMENT_PROTOCOL_MODE, + ACCURATE_PLACEMENT_PROTOCOL, + //CARPET_ACCURATE_PLACEMENT_PROTOCOL, CLIENT_PLACEMENT_ROTATION, - //DEBUG_LOGGING, + DEBUG_LOGGING, FAST_LEFT_CLICK_ALLOW_TOOLS, FAST_PLACEMENT_REMEMBER_ALWAYS, FREE_CAMERA_PLAYER_INPUTS, diff --git a/src/main/java/fi/dy/masa/tweakeroo/config/Hotkeys.java b/src/main/java/fi/dy/masa/tweakeroo/config/Hotkeys.java index 25230d0a4..ecb3c2ab2 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/config/Hotkeys.java +++ b/src/main/java/fi/dy/masa/tweakeroo/config/Hotkeys.java @@ -48,7 +48,8 @@ public class Hotkeys public static final ConfigHotkey SKIP_WORLD_RENDERING = new ConfigHotkey("skipWorldRendering", "", "Toggles skipping world rendering"); public static final ConfigHotkey STAND_UP_NEARBY_PETS = new ConfigHotkey("standUpNearbyPets", "", "Makes all nearby pets stand up"); public static final ConfigHotkey SWAP_ELYTRA_CHESTPLATE = new ConfigHotkey("swapElytraChestplate", "", "Swaps the currently equipped item in the chest slot between an Elytra and a Chest Plate"); - public static final ConfigHotkey TOGGLE_CARPET_AP_PROTOCOL = new ConfigHotkey("toggleCarpetAccuratePlacementProtocol", "", "Toggles the value of the Generic -> 'carpetAccuratePlacementProtocol' option"); + //public static final ConfigHotkey TOGGLE_CARPET_AP_PROTOCOL = new ConfigHotkey("toggleCarpetAccuratePlacementProtocol", "", "Toggles the value of the Generic -> 'carpetAccuratePlacementProtocol' option"); + public static final ConfigHotkey TOGGLE_AP_PROTOCOL = new ConfigHotkey("toggleAccuratePlacementProtocol", "", "Toggles the value of the Generic -> 'accuratePlacementProtocol' option"); public static final ConfigHotkey TOGGLE_GRAB_CURSOR = new ConfigHotkey("toggleGrabCursor", "", "Grabs or ungrabs the mouse cursor, depending on the current state"); public static final ConfigHotkey TOOL_PICK = new ConfigHotkey("toolPick", "", "Switches to the effective tool for the targeted block"); public static final ConfigHotkey WRITE_MAPS_AS_IMAGES = new ConfigHotkey("writeMapsAsImages", "", "Writes all the currently available maps as images\nto the 'config/tweakeroo/map_images//' directory"); @@ -94,7 +95,8 @@ public class Hotkeys SKIP_WORLD_RENDERING, STAND_UP_NEARBY_PETS, SWAP_ELYTRA_CHESTPLATE, - TOGGLE_CARPET_AP_PROTOCOL, + //TOGGLE_CARPET_AP_PROTOCOL, + TOGGLE_AP_PROTOCOL, TOGGLE_GRAB_CURSOR, TOOL_PICK, WRITE_MAPS_AS_IMAGES, diff --git a/src/main/java/fi/dy/masa/tweakeroo/data/DataManager.java b/src/main/java/fi/dy/masa/tweakeroo/data/DataManager.java new file mode 100644 index 000000000..b4677682c --- /dev/null +++ b/src/main/java/fi/dy/masa/tweakeroo/data/DataManager.java @@ -0,0 +1,38 @@ +package fi.dy.masa.tweakeroo.data; + +import net.minecraft.util.Identifier; + +public class DataManager +{ + private static final DataManager INSTANCE = new DataManager(); + private boolean hasCarpetServer; + public static final Identifier CARPET_HELLO = Identifier.of("carpet", "hello"); + + private DataManager() + { + } + + public static DataManager getInstance() { return INSTANCE; } + + public void reset(boolean isLogout) + { + if (isLogout) + { + //Tweakeroo.logger.info("DataManager#reset() - log-out"); + } + else + { + //Tweakeroo.logger.info("DataManager#reset() - dimension change or log-in"); + } + } + + public void setHasCarpetServer(boolean toggle) + { + this.hasCarpetServer = toggle; + } + + public boolean hasCarpetServer() + { + return this.hasCarpetServer; + } +} diff --git a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinBlockItem.java b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinBlockItem.java index 356d89b9c..30bf5ac28 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinBlockItem.java +++ b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinBlockItem.java @@ -41,7 +41,8 @@ private void modifyPlacementState(ItemPlacementContext ctx, CallbackInfoReturnab if (stateOrig != null && this.canPlace(ctx, stateOrig)) { UseContext context = UseContext.from(ctx, ctx.getHand()); - cir.setReturnValue(PlacementHandler.getStateForPlacement(stateOrig, context)); + //cir.setReturnValue(PlacementHandler_V2Only.getStateForPlacement(stateOrig, context)); + cir.setReturnValue(PlacementHandler.applyPlacementProtocolToPlacementState(stateOrig, context)); } } } @@ -60,7 +61,7 @@ private BlockState modifyPlacementState(BlockItem item, ItemPlacementContext ctx if (stateOriginal != null && Configs.Generic.CLIENT_PLACEMENT_ROTATION.getBooleanValue()) { UseContext context = UseContext.from(ctx, Hand.MAIN); - return PlacementHandler.getStateForPlacement(stateOriginal, context); + return PlacementHandler_V2Only.getStateForPlacement(stateOriginal, context); } return stateOriginal; diff --git a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientCommonNetworkHandler.java b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientCommonNetworkHandler.java new file mode 100644 index 000000000..ae7f31afb --- /dev/null +++ b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientCommonNetworkHandler.java @@ -0,0 +1,24 @@ +package fi.dy.masa.tweakeroo.mixin; + +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; +import net.minecraft.client.network.ClientCommonNetworkHandler; +import net.minecraft.network.packet.s2c.common.CustomPayloadS2CPacket; +import fi.dy.masa.tweakeroo.Tweakeroo; +import fi.dy.masa.tweakeroo.data.DataManager; + +@Mixin(ClientCommonNetworkHandler.class) +public class MixinClientCommonNetworkHandler +{ + @Inject(method = "onCustomPayload(Lnet/minecraft/network/packet/s2c/common/CustomPayloadS2CPacket;)V", at = @At("HEAD")) + private void tweakeroo_onCustomPayload(CustomPayloadS2CPacket packet, CallbackInfo ci) + { + if (packet.payload().getId().id().equals(DataManager.CARPET_HELLO)) + { + Tweakeroo.debugLog("ClientCommonNetworkHandler#tweakeroo_onCustomPayload(): received carpet hello packet"); + DataManager.getInstance().setHasCarpetServer(true); + } + } +} diff --git a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayNetworkHandler.java b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayNetworkHandler.java index b4e496b88..ff02a5e75 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayNetworkHandler.java +++ b/src/main/java/fi/dy/masa/tweakeroo/mixin/MixinClientPlayNetworkHandler.java @@ -1,5 +1,7 @@ package fi.dy.masa.tweakeroo.mixin; +import fi.dy.masa.tweakeroo.Tweakeroo; +import fi.dy.masa.tweakeroo.data.DataManager; import fi.dy.masa.tweakeroo.data.ServerDataSyncer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -7,6 +9,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.network.packet.CustomPayload; import net.minecraft.network.packet.s2c.play.DeathMessageS2CPacket; import net.minecraft.network.packet.s2c.play.ScreenHandlerSlotUpdateS2CPacket; import fi.dy.masa.tweakeroo.config.FeatureToggle; @@ -52,4 +55,14 @@ private void onCommandTree(CallbackInfo ci) ServerDataSyncer.getInstance().recheckOpStatus(); } } + + @Inject(method = "onCustomPayload", at = @At("HEAD")) + private void tweakeroo_onCustomPayload(CustomPayload payload, CallbackInfo ci) + { + if (payload.getId().id().equals(DataManager.CARPET_HELLO)) + { + Tweakeroo.debugLog("MixinClientPlayNetworkHandler#tweakeroo_onCustomPayload(): received carpet hello packet"); + DataManager.getInstance().setHasCarpetServer(true); + } + } } diff --git a/src/main/java/fi/dy/masa/tweakeroo/tweaks/PlacementHandler.java b/src/main/java/fi/dy/masa/tweakeroo/tweaks/PlacementHandler.java index e39a53910..261cc104d 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/tweaks/PlacementHandler.java +++ b/src/main/java/fi/dy/masa/tweakeroo/tweaks/PlacementHandler.java @@ -1,82 +1,165 @@ package fi.dy.masa.tweakeroo.tweaks; import javax.annotation.Nullable; -import net.minecraft.block.BedBlock; -import net.minecraft.block.Block; -import net.minecraft.block.BlockState; -import net.minecraft.block.ComparatorBlock; -import net.minecraft.block.RepeaterBlock; -import net.minecraft.block.StairsBlock; -import net.minecraft.block.TrapdoorBlock; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import com.google.common.collect.ImmutableSet; +import net.minecraft.block.*; import net.minecraft.block.enums.BlockHalf; import net.minecraft.block.enums.ComparatorMode; +import net.minecraft.block.enums.Orientation; +import net.minecraft.block.enums.SlabType; +import net.minecraft.client.MinecraftClient; import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemPlacementContext; import net.minecraft.state.property.DirectionProperty; +import net.minecraft.state.property.Properties; +import net.minecraft.state.property.Property; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; +import fi.dy.masa.tweakeroo.Tweakeroo; +import fi.dy.masa.tweakeroo.config.Configs; +import fi.dy.masa.tweakeroo.data.DataManager; +import fi.dy.masa.tweakeroo.util.EasyPlacementProtocol; public class PlacementHandler { - @Nullable - public static BlockState getStateForPlacement(BlockState state, UseContext context) + public static final ImmutableSet> WHITELISTED_PROPERTIES = ImmutableSet.of( + // BooleanProperty: + // INVERTED - DaylightDetector + // OPEN - Barrel, Door, FenceGate, Trapdoor + // PERSISTENT - Leaves + // CAN_SUMMON - Shrieker + Properties.INVERTED, + Properties.OPEN, + Properties.PERSISTENT, + Properties.CAN_SUMMON, + // EnumProperty: + // ATTACHMENT - Bell + // AXIS - Pillar + // BED_PART - Beds + // BLOCK_HALF - Stairs, Trapdoor + // BLOCK_FACE - Button, Grindstone, Lever + // CHEST_TYPE - Chest + // COMPARATOR_MODE - Comparator + // DOOR_HINGE - Door + // DOUBLE_BLOCK_HALF - Doors, Plants + // ORIENTATION - Crafter + // RAIL_SHAPE / STRAIGHT_RAIL_SHAPE - Rails + // SLAB_TYPE - Slab - PARTIAL ONLY: TOP and BOTTOM, not DOUBLE + // STAIR_SHAPE - Stairs (needed to get the correct state, otherwise the player facing would be a factor) + // BLOCK_FACE - Button, Grindstone, Lever + Properties.ATTACHMENT, + Properties.AXIS, + Properties.BED_PART, + Properties.BLOCK_HALF, + Properties.BLOCK_FACE, + Properties.CHEST_TYPE, + Properties.COMPARATOR_MODE, + Properties.DOOR_HINGE, + Properties.DOUBLE_BLOCK_HALF, + Properties.ORIENTATION, + Properties.RAIL_SHAPE, + Properties.STRAIGHT_RAIL_SHAPE, + Properties.SLAB_TYPE, + Properties.STAIR_SHAPE, + // IntProperty: + // BITES - Cake + // DELAY - Repeater + // NOTE - NoteBlock + // ROTATION - Banner, Sign, Skull + Properties.BITES, + Properties.DELAY, + Properties.NOTE, + Properties.ROTATION + ); + + public static EasyPlacementProtocol getEffectiveProtocolVersion() { - Vec3d hitVec = context.getHitVec(); - @Nullable DirectionProperty property = fi.dy.masa.malilib.util.BlockUtils.getFirstDirectionProperty(state); - int x = (int) (hitVec.x - (double) context.getPos().getX()); - int rawFacingIndex = x & 0xF; + EasyPlacementProtocol protocol = (EasyPlacementProtocol) Configs.Generic.ACCURATE_PLACEMENT_PROTOCOL_MODE.getOptionListValue(); - if (rawFacingIndex >= 2 && property != null) + if (protocol == EasyPlacementProtocol.AUTO) { - Direction facingOrig = state.get(property); - Direction facing = facingOrig; - int decodedFacingIndex = ((x - 2) / 2); - - if (decodedFacingIndex == 6) // the opposite of the normal facing requested + if (MinecraftClient.getInstance().isInSingleplayer()) { - facing = facing.getOpposite(); + return EasyPlacementProtocol.V3; } - else if (decodedFacingIndex >= 0 && decodedFacingIndex <= 5) - { - facing = Direction.byId(decodedFacingIndex); - if (property.getValues().contains(facing) == false) - { - facing = context.getEntity().getHorizontalFacing().getOpposite(); - } + if (DataManager.getInstance().hasCarpetServer()) + { + return EasyPlacementProtocol.V2; } - //System.out.printf("plop facing: %s -> %s (raw: %d, dec: %d)\n", facingOrig, facing, rawFacingIndex, decodedFacingIndex); + return EasyPlacementProtocol.SLAB_ONLY; + } - if (facing != facingOrig && property.getValues().contains(facing)) - { - if (state.getBlock() instanceof BedBlock) - { - BlockPos headPos = context.pos.offset(facing); - ItemPlacementContext ctx = context.getItemPlacementContext(); + return protocol; + } - if (context.getWorld().getBlockState(headPos).canReplace(ctx) == false) - { - return null; - } - } + @Nullable + public static BlockState applyPlacementProtocolToPlacementState(BlockState state, UseContext context) + { + EasyPlacementProtocol protocol = getEffectiveProtocolVersion(); + + if (protocol == EasyPlacementProtocol.V3) + { + return applyPlacementProtocolV3(state, context); + } + else if (protocol == EasyPlacementProtocol.V2) + { + return applyPlacementProtocolV2(state, context); + } + else + { + return state; + } + } + + public static BlockState applyPlacementProtocolV2(BlockState state, UseContext context) + { + int protocolValue = (int) (context.getHitVec().x - (double) context.getPos().getX()) - 2; + + if (protocolValue < 0) + { + return state; + } + + @Nullable DirectionProperty property = fi.dy.masa.malilib.util.BlockUtils.getFirstDirectionProperty(state); + + if (property != null) + { + state = applyDirectionProperty(state, context, property, protocolValue); + + if (state == null) + { + return null; + } + } + else if (state.contains(Properties.AXIS)) + { + Direction.Axis axis = Direction.Axis.VALUES[((protocolValue >> 1) & 0x3) % 3]; - state = state.with(property, facing); + if (Properties.AXIS.getValues().contains(axis)) + { + state = state.with(Properties.AXIS, axis); } } - x &= 0xFFFFFFF0; + // Divide by two, and then remove the 4 bits used for the facing + protocolValue >>>= 5; - if (x >= 16) + if (protocolValue > 0) { Block block = state.getBlock(); if (block instanceof RepeaterBlock) { - Integer delay = (x / 16) + 1; + Integer delay = protocolValue; if (RepeaterBlock.DELAY.getValues().contains(delay)) { @@ -87,15 +170,127 @@ else if (block instanceof ComparatorBlock) { state = state.with(ComparatorBlock.MODE, ComparatorMode.SUBTRACT); } - else if (block instanceof TrapdoorBlock) + } + + if (state.contains(Properties.BLOCK_HALF)) + { + state = state.with(Properties.BLOCK_HALF, protocolValue > 0 ? BlockHalf.TOP : BlockHalf.BOTTOM); + } + + return state; + } + + public static > BlockState applyPlacementProtocolV3(BlockState state, UseContext context) + { + int protocolValue = (int) (context.getHitVec().x - (double) context.getPos().getX()) - 2; + System.out.printf("raw protocol value in: 0x%08X\n", protocolValue); + + if (protocolValue < 0) + { + return state; + } + + @Nullable DirectionProperty property = fi.dy.masa.malilib.util.BlockUtils.getFirstDirectionProperty(state); + + // DirectionProperty - allow all except: VERTICAL_DIRECTION (PointedDripstone) + if (property != null && property != Properties.VERTICAL_DIRECTION) + { + System.out.printf("applying: 0x%08X\n", protocolValue); + state = applyDirectionProperty(state, context, property, protocolValue); + + if (state == null) { - state = state.with(TrapdoorBlock.HALF, BlockHalf.TOP); + return null; } - else if (block instanceof StairsBlock && state.get(StairsBlock.HALF) == BlockHalf.BOTTOM) + + // Consume the bits used for the facing + protocolValue >>>= 3; + } + // Consume the lowest unused bit + protocolValue >>>= 1; + + List> propList = new ArrayList<>(state.getBlock().getStateManager().getProperties()); + propList.sort(Comparator.comparing(Property::getName)); + + try + { + for (Property p : propList) { - state = state.with(StairsBlock.HALF, BlockHalf.TOP); + if ((p instanceof DirectionProperty) == false && + WHITELISTED_PROPERTIES.contains(p)) + { + @SuppressWarnings("unchecked") + Property prop = (Property) p; + List list = new ArrayList<>(prop.getValues()); + list.sort(Comparable::compareTo); + + int requiredBits = MathHelper.floorLog2(MathHelper.smallestEncompassingPowerOfTwo(list.size())); + int bitMask = ~(0xFFFFFFFF << requiredBits); + int valueIndex = protocolValue & bitMask; + System.out.printf("trying to apply valInd: %d, bits: %d, prot val: 0x%08X\n", valueIndex, requiredBits, protocolValue); + + if (valueIndex >= 0 && valueIndex < list.size()) + { + T value = list.get(valueIndex); + + if (state.get(prop).equals(value) == false && + value != SlabType.DOUBLE) // don't allow duping slabs by forcing a double slab via the protocol + { + System.out.printf("applying %s: %s\n", prop.getName(), value); + state = state.with(prop, value); + } + + protocolValue >>>= requiredBits; + } + } } } + catch (Exception e) + { + Tweakeroo.logger.warn("Exception trying to apply placement protocol value", e); + } + + return state; + } + + private static BlockState applyDirectionProperty(BlockState state, UseContext context, + DirectionProperty property, int protocolValue) + { + Direction facingOrig = state.get(property); + Direction facing = facingOrig; + int decodedFacingIndex = (protocolValue & 0xF) >> 1; + + if (decodedFacingIndex == 6) // the opposite of the normal facing requested + { + facing = facing.getOpposite(); + } + else if (decodedFacingIndex >= 0 && decodedFacingIndex <= 5) + { + facing = Direction.byId(decodedFacingIndex); + + if (property.getValues().contains(facing) == false) + { + facing = context.getEntity().getHorizontalFacing().getOpposite(); + } + } + + System.out.printf("plop facing: %s -> %s (raw: %d, dec: %d)\n", facingOrig, facing, protocolValue, decodedFacingIndex); + + if (facing != facingOrig && property.getValues().contains(facing)) + { + if (state.getBlock() instanceof BedBlock) + { + BlockPos headPos = context.pos.offset(facing); + ItemPlacementContext ctx = context.getItemPlacementContext(); + + if (context.getWorld().getBlockState(headPos).canReplace(ctx) == false) + { + return null; + } + } + + state = state.with(property, facing); + } return state; } diff --git a/src/main/java/fi/dy/masa/tweakeroo/tweaks/PlacementHandler_V2Only.java b/src/main/java/fi/dy/masa/tweakeroo/tweaks/PlacementHandler_V2Only.java new file mode 100644 index 000000000..8d68f5a40 --- /dev/null +++ b/src/main/java/fi/dy/masa/tweakeroo/tweaks/PlacementHandler_V2Only.java @@ -0,0 +1,176 @@ +package fi.dy.masa.tweakeroo.tweaks; + +import javax.annotation.Nullable; +import net.minecraft.block.BedBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ComparatorBlock; +import net.minecraft.block.RepeaterBlock; +import net.minecraft.block.StairsBlock; +import net.minecraft.block.TrapdoorBlock; +import net.minecraft.block.enums.BlockHalf; +import net.minecraft.block.enums.ComparatorMode; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemPlacementContext; +import net.minecraft.state.property.DirectionProperty; +import net.minecraft.util.Hand; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; + +@Deprecated +public class PlacementHandler_V2Only +{ + @Nullable + public static BlockState getStateForPlacement(BlockState state, UseContext context) + { + Vec3d hitVec = context.getHitVec(); + @Nullable DirectionProperty property = fi.dy.masa.malilib.util.BlockUtils.getFirstDirectionProperty(state); + int x = (int) (hitVec.x - (double) context.getPos().getX()); + int rawFacingIndex = x & 0xF; + + if (rawFacingIndex >= 2 && property != null) + { + Direction facingOrig = state.get(property); + Direction facing = facingOrig; + int decodedFacingIndex = ((x - 2) / 2); + + if (decodedFacingIndex == 6) // the opposite of the normal facing requested + { + facing = facing.getOpposite(); + } + else if (decodedFacingIndex >= 0 && decodedFacingIndex <= 5) + { + facing = Direction.byId(decodedFacingIndex); + + if (property.getValues().contains(facing) == false) + { + facing = context.getEntity().getHorizontalFacing().getOpposite(); + } + } + + //System.out.printf("plop facing: %s -> %s (raw: %d, dec: %d)\n", facingOrig, facing, rawFacingIndex, decodedFacingIndex); + + if (facing != facingOrig && property.getValues().contains(facing)) + { + if (state.getBlock() instanceof BedBlock) + { + BlockPos headPos = context.pos.offset(facing); + ItemPlacementContext ctx = context.getItemPlacementContext(); + + if (context.getWorld().getBlockState(headPos).canReplace(ctx) == false) + { + return null; + } + } + + state = state.with(property, facing); + } + } + + x &= 0xFFFFFFF0; + + if (x >= 16) + { + Block block = state.getBlock(); + + if (block instanceof RepeaterBlock) + { + Integer delay = (x / 16) + 1; + + if (RepeaterBlock.DELAY.getValues().contains(delay)) + { + state = state.with(RepeaterBlock.DELAY, delay); + } + } + else if (block instanceof ComparatorBlock) + { + state = state.with(ComparatorBlock.MODE, ComparatorMode.SUBTRACT); + } + else if (block instanceof TrapdoorBlock) + { + state = state.with(TrapdoorBlock.HALF, BlockHalf.TOP); + } + else if (block instanceof StairsBlock && state.get(StairsBlock.HALF) == BlockHalf.BOTTOM) + { + state = state.with(StairsBlock.HALF, BlockHalf.TOP); + } + } + + return state; + } + + public static class UseContext + { + private final World world; + private final BlockPos pos; + private final Direction side; + private final Vec3d hitVec; + private final LivingEntity entity; + private final Hand hand; + @Nullable private final ItemPlacementContext itemPlacementContext; + + private UseContext(World world, BlockPos pos, Direction side, Vec3d hitVec, + LivingEntity entity, Hand hand, @Nullable ItemPlacementContext itemPlacementContext) + { + this.world = world; + this.pos = pos; + this.side = side; + this.hitVec = hitVec; + this.entity = entity; + this.hand = hand; + this.itemPlacementContext = itemPlacementContext; + } + + /* + public static UseContext of(World world, BlockPos pos, Direction side, Vec3d hitVec, LivingEntity entity, Hand hand) + { + return new UseContext(world, pos, side, hitVec, entity, hand, null); + } + */ + + public static UseContext from(ItemPlacementContext ctx, Hand hand) + { + Vec3d pos = ctx.getHitPos(); + return new UseContext(ctx.getWorld(), ctx.getBlockPos(), ctx.getSide(), new Vec3d(pos.x, pos.y, pos.z), + ctx.getPlayer(), hand, ctx); + } + + public World getWorld() + { + return this.world; + } + + public BlockPos getPos() + { + return this.pos; + } + + public Direction getSide() + { + return this.side; + } + + public Vec3d getHitVec() + { + return this.hitVec; + } + + public LivingEntity getEntity() + { + return this.entity; + } + + public Hand getHand() + { + return this.hand; + } + + @Nullable + public ItemPlacementContext getItemPlacementContext() + { + return this.itemPlacementContext; + } + } +} diff --git a/src/main/java/fi/dy/masa/tweakeroo/tweaks/PlacementTweaks.java b/src/main/java/fi/dy/masa/tweakeroo/tweaks/PlacementTweaks.java index d94c2b125..d8a56c931 100644 --- a/src/main/java/fi/dy/masa/tweakeroo/tweaks/PlacementTweaks.java +++ b/src/main/java/fi/dy/masa/tweakeroo/tweaks/PlacementTweaks.java @@ -132,7 +132,7 @@ public static boolean onProcessRightClickPre(PlayerEntity player, Hand hand) { if (isEmulatedClick == false) { - //System.out.printf("onProcessRightClickPre storing stack: %s\n", stackOriginal); + System.out.printf("onProcessRightClickPre storing stack: %s\n", stackOriginal); cacheStackInHand(hand); } @@ -147,7 +147,7 @@ public static boolean onProcessRightClickPre(PlayerEntity player, Hand hand) public static void onProcessRightClickPost(PlayerEntity player, Hand hand) { - //System.out.printf("onProcessRightClickPost -> tryRestockHand with: %s, current: %s\n", stackBeforeUse[hand.ordinal()], player.getHeldItem(hand)); + System.out.printf("onProcessRightClickPost -> tryRestockHand with: %s, current: %s\n", stackBeforeUse[hand.ordinal()], player.getStackInHand(hand)); tryRestockHand(player, hand, stackBeforeUse[hand.ordinal()]); } @@ -361,7 +361,7 @@ public static ActionResult onProcessRightClickBlock( return ActionResult.PASS; } - //System.out.printf("onProcessRightClickBlock() pos: %s, side: %s, part: %s, hitVec: %s\n", posIn, sideIn, hitPart, hitVec); + System.out.printf("onProcessRightClickBlock() pos: %s, side: %s, part: %s, hitVec: %s\n", posIn, sideIn, hitPart, hitVec); ActionResult result = tryPlaceBlock(controller, player, world, posIn, sideIn, sideRotated, yaw, hitVec, hand, hitPart, true); // Store the initial click data for the fast placement mode @@ -387,7 +387,7 @@ public static ActionResult onProcessRightClickBlock( sideRotatedFirst = sideRotated; playerYawFirst = yaw; stackBeforeUse[hand.ordinal()] = stackPre; - //System.out.printf("plop store @ %s\n", posFirst); + System.out.printf("plop store @ %s\n", posFirst); } return result; @@ -501,7 +501,7 @@ private static ActionResult tryPlaceBlock( { facing = facing.getOpposite(); } - //System.out.printf("accurate - IN - facing: %s\n", facing); + System.out.printf("accurate - IN - facing: %s\n", facing); } else if (flexible == false || rotation == false) { @@ -541,7 +541,7 @@ else if (flexible == false || rotation == false) if (accurateReverse) { - //System.out.printf("accurate - REVERSE - facingOrig: %s, facingNew: %s\n", facing, facing.getOpposite()); + System.out.printf("accurate - REVERSE - facingOrig: %s, facingNew: %s\n", facing, facing.getOpposite()); if (accurateIn || flexible == false || rotation == false) { facing = facing.getOpposite(); @@ -551,7 +551,8 @@ else if (flexible == false || rotation == false) handleAccurate = true; } - if ((handleAccurate || afterClicker) && Configs.Generic.CARPET_ACCURATE_PLACEMENT_PROTOCOL.getBooleanValue()) + //if ((handleAccurate || afterClicker) && Configs.Generic.CARPET_ACCURATE_PLACEMENT_PROTOCOL.getBooleanValue()) + if ((handleAccurate || afterClicker) && Configs.Generic.ACCURATE_PLACEMENT_PROTOCOL.getBooleanValue()) { // Carpet-Extra mod accurate block placement protocol support double relX = hitVec.x - posNew.getX(); @@ -568,13 +569,13 @@ else if (flexible == false || rotation == false) x += afterClickerClickCount * 16; } - //System.out.printf("accurate - pre hitVec: %s\n", hitVec); - //System.out.printf("processRightClickBlockWrapper facing: %s, x: %.3f, pos: %s, side: %s\n", facing, x, pos, side); + System.out.printf("accurate - pre hitVec: %s\n", hitVec); + System.out.printf("processRightClickBlockWrapper facing: %s, x: %.3f, pos: %s, side: %s\n", facing, x, posNew, side); hitVec = new Vec3d(x, hitVec.y, hitVec.z); - //System.out.printf("accurate - post hitVec: %s\n", hitVec); + System.out.printf("accurate - post hitVec: %s\n", hitVec); } - //System.out.printf("accurate - facing: %s, side: %s, posNew: %s, hit: %s\n", facing, side, posNew, hitVec); + System.out.printf("accurate - facing: %s, side: %s, posNew: %s, hit: %s\n", facing, side, posNew, hitVec); return processRightClickBlockWrapper(controller, player, world, posNew, side, hitVec, hand); } @@ -585,7 +586,7 @@ else if (flexible == false || rotation == false) if (canPlaceBlockIntoPosition(world, posNew, ctx)) { - //System.out.printf("tryPlaceBlock() pos: %s, side: %s, part: %s, hitVec: %s\n", posNew, side, hitPart, hitVec); + System.out.printf("tryPlaceBlock() pos: %s, side: %s, part: %s, hitVec: %s\n", posNew, side, hitPart, hitVec); return handleFlexibleBlockPlacement(controller, player, world, posNew, side, playerYaw, hitVec, hand, hitPart); } else @@ -704,7 +705,7 @@ private static ActionResult processRightClickBlockWrapper( Vec3d hitVecIn, Hand hand) { - //System.out.printf("processRightClickBlockWrapper() start @ %s, side: %s, hand: %s\n", pos, side, hand); + System.out.printf("processRightClickBlockWrapper() start @ %s, side: %s, hand: %s\n", posIn, sideIn, hand); if (FeatureToggle.TWEAK_PLACEMENT_LIMIT.getBooleanValue() && placementCount >= Configs.Generic.PLACEMENT_LIMIT.getIntegerValue()) { @@ -749,7 +750,7 @@ private static ActionResult processRightClickBlockWrapper( if (posFirst != null && isPositionAllowedByPlacementRestriction(posIn, sideIn) == false) { - //System.out.printf("processRightClickBlockWrapper() PASS @ %s, side: %s\n", pos, side); + System.out.printf("processRightClickBlockWrapper() PASS @ %s, side: %s\n", posIn, sideIn); return ActionResult.PASS; } @@ -766,7 +767,8 @@ private static ActionResult processRightClickBlockWrapper( // Carpet-Extra mod accurate block placement protocol support if (flexible && rotation && accurate == false && - Configs.Generic.CARPET_ACCURATE_PLACEMENT_PROTOCOL.getBooleanValue() && + //Configs.Generic.CARPET_ACCURATE_PLACEMENT_PROTOCOL.getBooleanValue() && + Configs.Generic.ACCURATE_PLACEMENT_PROTOCOL.getBooleanValue() && isFacingValidFor(facing, stackOriginal)) { facing = facing.getOpposite(); // go from block face to click on to the requested facing @@ -779,7 +781,7 @@ private static ActionResult processRightClickBlockWrapper( x += afterClickerClickCount * 16; } - //System.out.printf("processRightClickBlockWrapper req facing: %s, x: %.3f, pos: %s, sideIn: %s\n", facing, x, posIn, sideIn); + System.out.printf("processRightClickBlockWrapper req facing: %s, x: %.3f, pos: %s, sideIn: %s\n", facing, x, posIn, sideIn); hitVecIn = new Vec3d(x, hitVecIn.y, hitVecIn.z); } @@ -802,7 +804,7 @@ private static ActionResult processRightClickBlockWrapper( InventoryUtils.trySwapCurrentToolIfNearlyBroken(); - //System.out.printf("processRightClickBlockWrapper() pos: %s, side: %s, hitVec: %s\n", pos, side, hitVec); + System.out.printf("processRightClickBlockWrapper() pos: %s, side: %s, hitVec: %s\n", posIn, sideIn, hitVecIn); ActionResult result; if (InventoryUtils.canUnstackingItemNotFitInInventory(stackOriginal, player)) @@ -811,7 +813,7 @@ private static ActionResult processRightClickBlockWrapper( } else { - //System.out.printf("processRightClickBlockWrapper() PLACE @ %s, side: %s, hit: %s\n", pos, side, hitVec); + System.out.printf("processRightClickBlockWrapper() PLACE @ %s, side: %s, hit: %s\n", posIn, sideIn, hitVecIn); BlockHitResult context = new BlockHitResult(hitVecIn, sideIn, posIn, false); result = controller.interactBlock(player, hand, context); } @@ -823,16 +825,18 @@ private static ActionResult processRightClickBlockWrapper( // This restock needs to happen even with the pick-before-place tweak active, // otherwise the fast placement mode's checks (getHandWithItem()) will fail... - //System.out.printf("processRightClickBlockWrapper -> tryRestockHand with: %s, current: %s\n", stackOriginal, player.getHeldItem(hand)); + System.out.printf("processRightClickBlockWrapper -> tryRestockHand with: %s, current: %s\n", stackOriginal, player.getStackInHand(hand)); tryRestockHand(player, hand, stackOriginal); if (FeatureToggle.TWEAK_AFTER_CLICKER.getBooleanValue() && - Configs.Generic.CARPET_ACCURATE_PLACEMENT_PROTOCOL.getBooleanValue() == false && + //Configs.Generic.CARPET_ACCURATE_PLACEMENT_PROTOCOL.getBooleanValue() == false && + Configs.Generic.ACCURATE_PLACEMENT_PROTOCOL.getBooleanValue() == false && world.getBlockState(posPlacement) != stateBefore) { + // TODO --> Add EasyPlacement handling? for (int i = 0; i < afterClickerClickCount; i++) { - //System.out.printf("processRightClickBlockWrapper() after-clicker - i: %d, pos: %s, side: %s, hitVec: %s\n", i, pos, side, hitVec); + System.out.printf("processRightClickBlockWrapper() after-clicker - i: %d, pos: %s, side: %s, hitVec: %s\n", i, posPlacement, sideIn, hitVecIn); BlockHitResult context = new BlockHitResult(hitVecIn, sideIn, posPlacement, false); result = controller.interactBlock(player, hand, context); } @@ -875,6 +879,7 @@ private static ActionResult handleFlexibleBlockPlacement( @Nullable HitPart hitPart) { Direction facing = Direction.fromHorizontal(MathHelper.floor((playerYaw * 4.0F / 360.0F) + 0.5D) & 3); + Direction facingOrig = facing; float yawOrig = player.getYaw(); if (hitPart == HitPart.CENTER) @@ -895,7 +900,7 @@ else if (hitPart == HitPart.RIGHT) player.setYaw(yaw); player.networkHandler.sendPacket(new PlayerMoveC2SPacket.LookAndOnGround(yaw, pitch, player.isOnGround())); - //System.out.printf("handleFlexibleBlockPlacement() pos: %s, side: %s, facing orig: %s facing new: %s\n", pos, side, facingOrig, facing); + System.out.printf("handleFlexibleBlockPlacement() pos: %s, side: %s, facing orig: %s facing new: %s\n", pos, side, facingOrig, facing); ActionResult result = processRightClickBlockWrapper(controller, player, world, pos, side, hitVec, hand); player.setYaw(yawOrig); diff --git a/src/main/java/fi/dy/masa/tweakeroo/util/EasyPlacementProtocol.java b/src/main/java/fi/dy/masa/tweakeroo/util/EasyPlacementProtocol.java new file mode 100644 index 000000000..c320d9d77 --- /dev/null +++ b/src/main/java/fi/dy/masa/tweakeroo/util/EasyPlacementProtocol.java @@ -0,0 +1,79 @@ +package fi.dy.masa.tweakeroo.util; + +import com.google.common.collect.ImmutableList; +import fi.dy.masa.malilib.config.IConfigOptionListEntry; +import fi.dy.masa.malilib.util.StringUtils; + +public enum EasyPlacementProtocol implements IConfigOptionListEntry +{ + AUTO ("auto", "tweakeroo.gui.label.easy_place_protocol.auto"), + V3 ("v3", "tweakeroo.gui.label.easy_place_protocol.v3"), + V2 ("v2", "tweakeroo.gui.label.easy_place_protocol.v2"), + SLAB_ONLY ("slabs_only", "tweakeroo.gui.label.easy_place_protocol.slabs_only"), + NONE ("none", "tweakeroo.gui.label.easy_place_protocol.none"); + + public static final ImmutableList VALUES = ImmutableList.copyOf(values()); + + private final String configString; + private final String translationKey; + + EasyPlacementProtocol(String configString, String translationKey) + { + this.configString = configString; + this.translationKey = translationKey; + } + + @Override + public String getStringValue() + { + return this.configString; + } + + @Override + public String getDisplayName() + { + return StringUtils.translate(this.translationKey); + } + + @Override + public IConfigOptionListEntry cycle(boolean forward) + { + int id = this.ordinal(); + + if (forward) + { + if (++id >= values().length) + { + id = 0; + } + } + else + { + if (--id < 0) + { + id = values().length - 1; + } + } + + return values()[id % values().length]; + } + + @Override + public EasyPlacementProtocol fromString(String name) + { + return fromStringStatic(name); + } + + public static EasyPlacementProtocol fromStringStatic(String name) + { + for (EasyPlacementProtocol val : VALUES) + { + if (val.configString.equalsIgnoreCase(name)) + { + return val; + } + } + + return EasyPlacementProtocol.AUTO; + } +} diff --git a/src/main/resources/assets/tweakeroo/lang/en_us.json b/src/main/resources/assets/tweakeroo/lang/en_us.json index 938840946..eb5e9a4cc 100644 --- a/src/main/resources/assets/tweakeroo/lang/en_us.json +++ b/src/main/resources/assets/tweakeroo/lang/en_us.json @@ -14,6 +14,12 @@ "tweakeroo.gui.button.misc.command_block.hover.update_execution": "Whether or not multiple triggers per game tick are allowed", + "tweakeroo.gui.label.easy_place_protocol.auto": "Auto", + "tweakeroo.gui.label.easy_place_protocol.none": "None", + "tweakeroo.gui.label.easy_place_protocol.slabs_only": "Slabs only", + "tweakeroo.gui.label.easy_place_protocol.v2": "Version 2", + "tweakeroo.gui.label.easy_place_protocol.v3": "Version 3", + "tweakeroo.gui.title.configs": "Tweakeroo Configs - %s", "tweakeroo.hotkeys.category.disable_toggle_hotkeys": "Disable Toggle Hotkeys", diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 8aa58f3cb..3b4836605 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -34,6 +34,6 @@ "depends": { "minecraft": ">=1.21", - "malilib": ">=0.19.999-sakura.3" + "malilib": ">=0.19.999-sakura.5" } } diff --git a/src/main/resources/mixins.tweakeroo.json b/src/main/resources/mixins.tweakeroo.json index 700fe60b7..bd6eed2ce 100644 --- a/src/main/resources/mixins.tweakeroo.json +++ b/src/main/resources/mixins.tweakeroo.json @@ -1,88 +1,87 @@ { - "required": true, - "package": "fi.dy.masa.tweakeroo.mixin", - "minVersion": "0.8", - "compatibilityLevel": "JAVA_17", - "client": [ - "IMixinAbstractBlock", - "IMixinAbstractHorseEntity", - "IMixinAxeItem", - "IMixinChunkLightProvider", - "IMixinClientWorld", - "IMixinCommandBlockExecutor", - "IMixinCustomizeFlatLevelScreen", - "IMixinDataQueryHandler", - "IMixinShovelItem", - "IMixinSimpleOption", - "MixinAbstractClientPlayerEntity", - "MixinAbstractInventoryScreen", - "MixinAbstractSignEditScreen", - "MixinBackgroundRenderer", - "MixinBatEntity", - "MixinBeaconBlockEntityRenderer", - "MixinBlockEntityRenderDispatcher", - "MixinBlockItem", - "MixinBossBarHud", - "MixinBuiltChunk", - "MixinChatHud", - "MixinChatScreen", - "MixinChunkBuilder_BuiltChunk", - "MixinClientBossBar", - "MixinClientCommandSource", - "MixinClientPlayerEntity", - "MixinClientPlayerInteractionManager", - "MixinClientPlayNetworkHandler", - "MixinClientWorld", - "MixinClientWorld_Properties", - "MixinCloneCommand", - "MixinCommandBlockScreen", - "MixinCreativeInventoryScreen", - "MixinDataQueryHandler", - "MixinDimensionEffects_Nether", - "MixinEntity", - "MixinEntityRenderDispatcher", - "MixinExplosion", - "MixinFillCommand", - "MixinGameRenderer", - "MixinGameRenderer_ViewBob", - "MixinHeldItemRenderer", - "MixinInGameHud", - "MixinItem", - "MixinItemEntity", - "MixinItemGroup", - "MixinItemStack", - "MixinKeyboardInput", - "MixinLightingProvider", - "MixinLivingEntity", - "MixinMinecraftClient", - "MixinMobSpawnerBlockEntityRenderer", - "MixinMobSpawnerLogic", - "MixinMouse", - "MixinNetherPortalBlock", - "MixinObserverBlock", - "MixinParticleManager", - "MixinPlayerAbilities", - "MixinPlayerEntity", - "MixinRavagerEntity", - "MixinScaffoldingBlock", - "MixinSculkSensor", - "MixinServerPlayNetworkHandler", - "MixinShulkerBoxBlock", - "MixinSignBlockEntity", - "MixinSlimeBlock", - "MixinStructureBlockBlockEntity", - "MixinTeleportSpectatorMenu", - "MixinTradeOffer", - "MixinUpdateStructureBlockC2SPacket", - "MixinWindow", - "MixinWorld", - "MixinWorldRenderer" - ], - "mixinPriority": 990, - "injectors": { - "defaultRequire": 0 - }, - "mixins": [ - "MixinServerChunkLoadingManager" - ] + "required": true, + "package": "fi.dy.masa.tweakeroo.mixin", + "minVersion": "0.8", + "compatibilityLevel": "JAVA_17", + "client": [ + "IMixinAbstractBlock", + "IMixinAbstractHorseEntity", + "IMixinAxeItem", + "IMixinChunkLightProvider", + "IMixinClientWorld", + "IMixinCommandBlockExecutor", + "IMixinCustomizeFlatLevelScreen", + "IMixinDataQueryHandler", + "IMixinShovelItem", + "IMixinSimpleOption", + "MixinAbstractClientPlayerEntity", + "MixinAbstractInventoryScreen", + "MixinAbstractSignEditScreen", + "MixinBackgroundRenderer", + "MixinBatEntity", + "MixinBeaconBlockEntityRenderer", + "MixinBlockEntityRenderDispatcher", + "MixinBlockItem", + "MixinBossBarHud", + "MixinBuiltChunk", + "MixinChatHud", + "MixinChatScreen", + "MixinChunkBuilder_BuiltChunk", + "MixinClientBossBar", + "MixinClientCommandSource", + "MixinClientCommonNetworkHandler", + "MixinClientPlayerEntity", + "MixinClientPlayerInteractionManager", + "MixinClientPlayNetworkHandler", + "MixinClientWorld", + "MixinClientWorld_Properties", + "MixinCloneCommand", + "MixinCommandBlockScreen", + "MixinCreativeInventoryScreen", + "MixinDataQueryHandler", + "MixinDimensionEffects_Nether", + "MixinEntity", + "MixinEntityRenderDispatcher", + "MixinExplosion", + "MixinFillCommand", + "MixinGameRenderer", + "MixinGameRenderer_ViewBob", + "MixinHeldItemRenderer", + "MixinInGameHud", + "MixinItem", + "MixinItemEntity", + "MixinItemGroup", + "MixinItemStack", + "MixinKeyboardInput", + "MixinLightingProvider", + "MixinLivingEntity", + "MixinMinecraftClient", + "MixinMobSpawnerBlockEntityRenderer", + "MixinMobSpawnerLogic", + "MixinMouse", + "MixinNetherPortalBlock", + "MixinObserverBlock", + "MixinParticleManager", + "MixinPlayerAbilities", + "MixinPlayerEntity", + "MixinRavagerEntity", + "MixinScaffoldingBlock", + "MixinSculkSensor", + "MixinServerChunkLoadingManager", + "MixinServerPlayNetworkHandler", + "MixinShulkerBoxBlock", + "MixinSignBlockEntity", + "MixinSlimeBlock", + "MixinStructureBlockBlockEntity", + "MixinTeleportSpectatorMenu", + "MixinTradeOffer", + "MixinUpdateStructureBlockC2SPacket", + "MixinWindow", + "MixinWorld", + "MixinWorldRenderer" + ], + "mixinPriority": 990, + "injectors": { + "defaultRequire": 0 + } }