From 78c33e904d0433b53964926db603262d18427ea1 Mon Sep 17 00:00:00 2001 From: Boblet Date: Mon, 23 Jun 2025 16:58:46 +0200 Subject: [PATCH] --- changelog | 5 +- .../java/com/hbm/handler/HbmKeybinds.java | 130 +++++++++++++++--- .../container/ContainerCrateBase.java | 25 ++-- .../com/hbm/items/tool/ItemToolAbility.java | 14 +- .../com/hbm/main/ModEventHandlerClient.java | 70 ---------- src/main/java/com/hbm/main/ServerProxy.java | 2 + src/main/java/com/hbm/util/ArmorRegistry.java | 2 +- 7 files changed, 143 insertions(+), 105 deletions(-) diff --git a/changelog b/changelog index fac243f1a..5f91dbddb 100644 --- a/changelog +++ b/changelog @@ -41,4 +41,7 @@ * Fixed blowtorch having a minimum gas requirement of 1,000mB despite only using 250mB * The gas turbine now uses audio with a 20 tick timeout, fixing a rare issue where the loop gets stuck and never ends * Potentially fixed a dupe caused by using InventoryBogoSorter in combination with crates -* Rapidly spinning dyx should no longer have a state leak that would rotate lighting of unrelated TESRs with it \ No newline at end of file +* Rapidly spinning dyx should no longer have a state leak that would rotate lighting of unrelated TESRs with it +* Fixed issue where mining strange stone with silk touch ability would cause a desync. It also now drops cobblestone, as if silk touch wasn't active at all +* Fixed issue where applying a filter to a mask that doesn't support certain protection types would permanently remove those types from the filter until the game is restarted +* Fixed InventoryBogoSorter being able to move held crates \ No newline at end of file diff --git a/src/main/java/com/hbm/handler/HbmKeybinds.java b/src/main/java/com/hbm/handler/HbmKeybinds.java index 5f85ce886..06a9c90a1 100644 --- a/src/main/java/com/hbm/handler/HbmKeybinds.java +++ b/src/main/java/com/hbm/handler/HbmKeybinds.java @@ -2,19 +2,27 @@ package com.hbm.handler; import com.hbm.inventory.gui.GUICalculator; import com.hbm.items.IKeybindReceiver; +import com.hbm.items.weapon.sedna.ItemGunBaseNT; import cpw.mods.fml.common.FMLCommonHandler; import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import com.hbm.config.GeneralConfig; import com.hbm.extprop.HbmPlayerProps; import com.hbm.main.MainRegistry; import com.hbm.packet.PacketDispatcher; import com.hbm.packet.toserver.KeybindPacket; import cpw.mods.fml.client.registry.ClientRegistry; +import cpw.mods.fml.common.eventhandler.EventPriority; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.common.gameevent.InputEvent.KeyInputEvent; import cpw.mods.fml.common.gameevent.InputEvent.MouseInputEvent; +import cpw.mods.fml.common.gameevent.TickEvent.ClientTickEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.Minecraft; import net.minecraft.client.settings.KeyBinding; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; @@ -64,37 +72,121 @@ public class HbmKeybinds { ClientRegistry.registerKeyBinding(craneLeftKey); ClientRegistry.registerKeyBinding(craneRightKey); ClientRegistry.registerKeyBinding(craneLoadKey); + ClientRegistry.registerKeyBinding(abilityCycle); ClientRegistry.registerKeyBinding(abilityAlt); ClientRegistry.registerKeyBinding(copyToolAlt); ClientRegistry.registerKeyBinding(copyToolCtrl); } - - @SubscribeEvent + + @SideOnly(Side.CLIENT) + @SubscribeEvent(priority = EventPriority.LOW) public void mouseEvent(MouseInputEvent event) { + + /// OVERLAP HANDLING /// + handleOverlap(Mouse.getEventButtonState(), Mouse.getEventButton() - 100); + + /// KEYBIND PROPS /// + handleProps(Mouse.getEventButtonState(), Mouse.getEventButton() - 100); + } + + @SideOnly(Side.CLIENT) + @SubscribeEvent(priority = EventPriority.LOW) + public void keyEvent(KeyInputEvent event) { + + /// OVERLAP HANDLING /// + handleOverlap(Keyboard.getEventKeyState(), Keyboard.getEventKey()); + + /// KEYBIND PROPS /// + handleProps(Keyboard.getEventKeyState(), Keyboard.getEventKey()); + + /// CALCULATOR /// + if(calculatorKey.getIsKeyPressed()) { + MainRegistry.proxy.me().closeScreen(); + FMLCommonHandler.instance().showGuiScreen(new GUICalculator()); + } + } + + /** + * Shitty hack: Keybinds fire before minecraft checks right click on block, which means the tool cycle keybind would fire too. + * If cycle collides with right click and a block is being used, cancel the keybind. + * @param event + */ + @SideOnly(Side.CLIENT) + @SubscribeEvent + public void postClientTick(ClientTickEvent event) { + if(event.phase != event.phase.END) return; EntityPlayer player = MainRegistry.proxy.me(); + if(player == null) return; + if(player.worldObj == null) return; + HbmPlayerProps props = HbmPlayerProps.getData(player); - for(EnumKeybind key : EnumKeybind.values()) { - boolean last = props.getKeyPressed(key); - boolean current = MainRegistry.proxy.getIsKeyPressed(key); + // in theory, this should do the same keybind crap as the main one, but at the end of the client tick, fixing the issue + // of detecting when a block is being interacted with + // in practice, this shit doesn't fucking work. detection fails when the click is sub one tick long + if(Minecraft.getMinecraft().gameSettings.keyBindUseItem.getKeyCode() == abilityCycle.getKeyCode()) { + boolean last = props.getKeyPressed(EnumKeybind.ABILITY_CYCLE); + boolean current = abilityCycle.pressed; if(last != current) { - PacketDispatcher.wrapper.sendToServer(new KeybindPacket(key, current)); - props.setKeyPressed(key, current); - onPressedClient(player, key, current); + PacketDispatcher.wrapper.sendToServer(new KeybindPacket(EnumKeybind.ABILITY_CYCLE, current)); + props.setKeyPressed(EnumKeybind.ABILITY_CYCLE, current); + onPressedClient(player, EnumKeybind.ABILITY_CYCLE, current); } } } - @SubscribeEvent - public void keyEvent(KeyInputEvent event) { - EntityPlayer player = MainRegistry.proxy.me(); - - if(calculatorKey.getIsKeyPressed()) { // handle the calculator client-side only - player.closeScreen(); - FMLCommonHandler.instance().showGuiScreen(new GUICalculator()); + /** Handles keybind overlap. Make sure this runs first before referencing the keybinds set by the extprops */ + public static void handleOverlap(boolean state, int keyCode) { + Minecraft mc = Minecraft.getMinecraft(); + if(GeneralConfig.enableKeybindOverlap && (mc.currentScreen == null || mc.currentScreen.allowUserInput)) { + + //if anything errors here, run ./gradlew clean setupDecompWorkSpace + for(Object o : KeyBinding.keybindArray) { + KeyBinding key = (KeyBinding) o; + + if(keyCode != 0 && key.getKeyCode() == keyCode && KeyBinding.hash.lookup(key.getKeyCode()) != key) { + + key.pressed = state; + if(state && key.pressTime == 0) { + key.pressTime = 1; + } + } + } + + /// GUN HANDLING /// + boolean gunKey = keyCode == HbmKeybinds.gunPrimaryKey.getKeyCode() || keyCode == HbmKeybinds.gunSecondaryKey.getKeyCode() || + keyCode == HbmKeybinds.gunTertiaryKey.getKeyCode() || keyCode == HbmKeybinds.reloadKey.getKeyCode(); + + EntityPlayer player = mc.thePlayer; + + if(player.getHeldItem() != null && player.getHeldItem().getItem() instanceof ItemGunBaseNT) { + + /* Shoot in favor of attacking */ + if(gunKey && keyCode == mc.gameSettings.keyBindAttack.getKeyCode()) { + mc.gameSettings.keyBindAttack.pressed = false; + mc.gameSettings.keyBindAttack.pressTime = 0; + } + + /* Shoot in favor of interacting */ + /*if(gunKey && keyCode == mc.gameSettings.keyBindUseItem.getKeyCode()) { + mc.gameSettings.keyBindUseItem.pressed = false; + mc.gameSettings.keyBindUseItem.pressTime = 0; + }*/ + + /* Scope in favor of picking */ + if(gunKey && keyCode == mc.gameSettings.keyBindPickBlock.getKeyCode()) { + mc.gameSettings.keyBindPickBlock.pressed = false; + mc.gameSettings.keyBindPickBlock.pressTime = 0; + } + } } - + } + + public static void handleProps(boolean state, int keyCode) { + + /// KEYBIND PROPS /// + EntityPlayer player = MainRegistry.proxy.me(); HbmPlayerProps props = HbmPlayerProps.getData(player); for(EnumKeybind key : EnumKeybind.values()) { @@ -102,8 +194,12 @@ public class HbmKeybinds { boolean current = MainRegistry.proxy.getIsKeyPressed(key); if(last != current) { - PacketDispatcher.wrapper.sendToServer(new KeybindPacket(key, current)); + + /// ABILITY HANDLING /// + if(key == EnumKeybind.ABILITY_CYCLE && Minecraft.getMinecraft().gameSettings.keyBindUseItem.getKeyCode() == abilityCycle.getKeyCode()) continue; + props.setKeyPressed(key, current); + PacketDispatcher.wrapper.sendToServer(new KeybindPacket(key, current)); onPressedClient(player, key, current); } } diff --git a/src/main/java/com/hbm/inventory/container/ContainerCrateBase.java b/src/main/java/com/hbm/inventory/container/ContainerCrateBase.java index 06b255a68..05b818a10 100644 --- a/src/main/java/com/hbm/inventory/container/ContainerCrateBase.java +++ b/src/main/java/com/hbm/inventory/container/ContainerCrateBase.java @@ -24,7 +24,9 @@ public class ContainerCrateBase extends ContainerBase { } for(int i = 0; i < 9; i++) { - this.addSlotToContainer(new SlotPlayerCrate(invPlayer, i, playerInvX + i * 18, playerHotbarY)); + this.addSlotToContainer( + invPlayer.currentItem == i ? new SlotPlayerCrateLocked(invPlayer, i, playerInvX + i * 18, playerHotbarY) : + new SlotNonRetarded(invPlayer, i, playerInvX + i * 18, playerHotbarY)); } } @@ -49,29 +51,22 @@ public class ContainerCrateBase extends ContainerBase { tile.closeInventory(); } - public class SlotPlayerCrate extends SlotNonRetarded { + /** + * No touching anything here. No moving around, no taking, no inserting, fuck off. + */ + public class SlotPlayerCrateLocked extends SlotNonRetarded { - public SlotPlayerCrate(IInventory inventory, int id, int x, int y) { + public SlotPlayerCrateLocked(IInventory inventory, int id, int x, int y) { super(inventory, id, x, y); } - - /** - * This prevents the player from moving containers that are being held *at all*, fixing a decently big dupe. - * I hate that this has to be here but... It is what it is. - */ @Override public boolean canTakeStack(EntityPlayer player) { - if(player.inventory.currentItem == this.getSlotIndex() && // If this slot is the current held slot. - this.getStack() != null && this.getStack().getItem() instanceof ItemBlockStorageCrate && // If the slot contains a storage crate. - player.openContainer instanceof ContainerCrateBase && !(ContainerCrateBase.this.tile instanceof TileEntity)) // If the player is currently inside a crate container. - return false; - return super.canTakeStack(player); + return false; } @Override public boolean isItemValid(ItemStack item) { - if(ItemStack.areItemStacksEqual(getStack(), item)) return false; - return super.isItemValid(item); + return false; } } } diff --git a/src/main/java/com/hbm/items/tool/ItemToolAbility.java b/src/main/java/com/hbm/items/tool/ItemToolAbility.java index 06e20e6f7..abe7a137f 100644 --- a/src/main/java/com/hbm/items/tool/ItemToolAbility.java +++ b/src/main/java/com/hbm/items/tool/ItemToolAbility.java @@ -156,6 +156,18 @@ public class ItemToolAbility extends ItemTool implements IDepthRockTool, IGUIPro World world = player.worldObj; Block block = world.getBlock(x, y, z); + + /* + * The original implementation of this always returned FALSE which uses the vanilla block break code. + * This one now returns TRUE when an ability applies and instead relies on breakExtraBlock, which has the minor + * issue of only running on the sever, while the client uses the vanilla implementation. breakExtraBlock was only + * meant to be used for AoE or vein miner and not for the block that's being mined, hence break EXTRA block. + * The consequence was that the server would fail to break keyholes since breakExtraBlock is supposed to exclude + * them, while the client happily removes the block, causing a desync. + * + * Since keyholes aren't processable and exempt from silk touch anyway, we just default to the vanilla implementation in every case. + */ + if(block == ModBlocks.stone_keyhole || block == ModBlocks.stone_keyhole_meta) return false; if(!world.isRemote && (canHarvestBlock(block, stack) || canShearBlock(block, stack, world, x, y, z)) && canOperate(stack)) { Configuration config = getConfiguration(stack); @@ -165,7 +177,7 @@ public class ItemToolAbility extends ItemTool implements IDepthRockTool, IGUIPro boolean skipRef = preset.areaAbility.onDig(preset.areaAbilityLevel, world, x, y, z, player, this); - if (!skipRef) { + if(!skipRef) { breakExtraBlock(world, x, y, z, player, x, y, z); } diff --git a/src/main/java/com/hbm/main/ModEventHandlerClient.java b/src/main/java/com/hbm/main/ModEventHandlerClient.java index 967f76977..2df3bbfd0 100644 --- a/src/main/java/com/hbm/main/ModEventHandlerClient.java +++ b/src/main/java/com/hbm/main/ModEventHandlerClient.java @@ -13,7 +13,6 @@ import com.hbm.extprop.HbmPlayerProps; import com.hbm.handler.ArmorModHandler; import com.hbm.handler.HTTPHandler; import com.hbm.handler.HazmatRegistry; -import com.hbm.handler.HbmKeybinds; import com.hbm.handler.ImpactWorldHandler; import com.hbm.hazard.HazardSystem; import com.hbm.interfaces.IHoldableWeapon; @@ -65,7 +64,6 @@ import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.Loader; import cpw.mods.fml.common.eventhandler.EventPriority; import cpw.mods.fml.common.eventhandler.SubscribeEvent; -import cpw.mods.fml.common.gameevent.InputEvent; import cpw.mods.fml.common.gameevent.TickEvent; import cpw.mods.fml.common.gameevent.TickEvent.ClientTickEvent; import cpw.mods.fml.common.gameevent.TickEvent.Phase; @@ -86,7 +84,6 @@ import net.minecraft.client.renderer.RenderHelper; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.entity.RenderPlayer; import net.minecraft.client.settings.GameSettings; -import net.minecraft.client.settings.KeyBinding; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; @@ -1121,73 +1118,6 @@ public class ModEventHandlerClient { } } - @SideOnly(Side.CLIENT) - @SubscribeEvent(priority = EventPriority.LOW) - public void onMouseClicked(InputEvent.MouseInputEvent event) { - - Minecraft mc = Minecraft.getMinecraft(); - if(GeneralConfig.enableKeybindOverlap && (mc.currentScreen == null || mc.currentScreen.allowUserInput)) { - boolean state = Mouse.getEventButtonState(); - int keyCode = Mouse.getEventButton() - 100; - - //if anything errors here, run ./gradlew clean setupDecompWorkSpace - for(Object o : KeyBinding.keybindArray) { - KeyBinding key = (KeyBinding) o; - - if(key.getKeyCode() == keyCode && KeyBinding.hash.lookup(key.getKeyCode()) != key) { - - key.pressed = state; - if(state && key.pressTime == 0) { - key.pressTime = 1; - } - } - } - - boolean gunKey = keyCode == HbmKeybinds.gunPrimaryKey.getKeyCode() || keyCode == HbmKeybinds.gunSecondaryKey.getKeyCode() || - keyCode == HbmKeybinds.gunTertiaryKey.getKeyCode() || keyCode == HbmKeybinds.reloadKey.getKeyCode(); - - EntityPlayer player = mc.thePlayer; - - if(player.getHeldItem() != null && player.getHeldItem().getItem() instanceof ItemGunBaseNT) { - - /* Shoot in favor of attacking */ - if(gunKey && keyCode == mc.gameSettings.keyBindAttack.getKeyCode()) { - mc.gameSettings.keyBindAttack.pressed = false; - mc.gameSettings.keyBindAttack.pressTime = 0; - } - - if(gunKey && keyCode == mc.gameSettings.keyBindPickBlock.getKeyCode()) { - mc.gameSettings.keyBindPickBlock.pressed = false; - mc.gameSettings.keyBindPickBlock.pressTime = 0; - } - } - } - } - - @SideOnly(Side.CLIENT) - @SubscribeEvent(priority = EventPriority.LOW) - public void onKeyTyped(InputEvent.KeyInputEvent event) { - - Minecraft mc = Minecraft.getMinecraft(); - if(GeneralConfig.enableKeybindOverlap && (mc.currentScreen == null || mc.currentScreen.allowUserInput)) { - boolean state = Keyboard.getEventKeyState(); - int keyCode = Keyboard.getEventKey(); - - //if anything errors here, run ./gradlew clean setupDecompWorkSpace - for(Object o : KeyBinding.keybindArray) { - KeyBinding key = (KeyBinding) o; - - if(keyCode != 0 && key.getKeyCode() == keyCode && KeyBinding.hash.lookup(key.getKeyCode()) != key) { - - key.pressed = state; - if(state && key.pressTime == 0) { - key.pressTime = 1; - } - } - } - } - } - @SideOnly(Side.CLIENT) @SubscribeEvent public void onRenderWorldLastEvent(RenderWorldLastEvent event) { diff --git a/src/main/java/com/hbm/main/ServerProxy.java b/src/main/java/com/hbm/main/ServerProxy.java index fdbe22529..7ec6eaa23 100644 --- a/src/main/java/com/hbm/main/ServerProxy.java +++ b/src/main/java/com/hbm/main/ServerProxy.java @@ -61,11 +61,13 @@ public class ServerProxy { public void displayTooltip(String msg, int id) { displayTooltip(msg, 1000, id); } + public void displayTooltip(String msg, int time, int id) { } public boolean getIsKeyPressed(EnumKeybind key) { return false; } + public EntityPlayer me() { return null; } diff --git a/src/main/java/com/hbm/util/ArmorRegistry.java b/src/main/java/com/hbm/util/ArmorRegistry.java index 98b863080..113976bae 100644 --- a/src/main/java/com/hbm/util/ArmorRegistry.java +++ b/src/main/java/com/hbm/util/ArmorRegistry.java @@ -74,7 +74,7 @@ public class ArmorRegistry { if(filter != null) { //add the HazardClasses from the filter, then remove the ones blacklisted by the mask - List filProt = hazardClasses.get(filter.getItem()); + List filProt = (List) hazardClasses.get(filter.getItem()).clone(); for(HazardClass c : mask.getBlacklist(stack, entity)) filProt.remove(c);