Fix taking items with fast clicks (#60)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This commit is contained in:
danyadevandgithub-actions[bot] authored and GitHub committed 2026-02-13 12:06:34 +01:00
1 parent b6517015ad
commit 477ebb5051
10 files changed
+92 -177

No files matched your search

+3 -5
View File
@@ -3,8 +3,8 @@ pluginManagement {
repositories {
maven {
// RetroFuturaGradle
name "GTNH Maven"
url "https://nexus.gtnewhorizons.com/repository/public/"
name = "GTNH Maven"
url = uri("https://nexus.gtnewhorizons.com/repository/public/")
mavenContent {
includeGroup("com.gtnewhorizons")
includeGroupByRegex("com\\.gtnewhorizons\\..+")
@@ -17,7 +17,5 @@ pluginManagement {
}
plugins {
id 'com.gtnewhorizons.gtnhsettingsconvention' version '2.0.19'
id("com.gtnewhorizons.gtnhsettingsconvention") version("2.0.19")
}
@@ -5,7 +5,7 @@ import net.minecraft.item.ItemStack;
public interface IDrawerGroupInteractive extends IDrawerGroup {
ItemStack takeItemsFromSlot(int slot, int count, EntityPlayer player);
ItemStack takeItemsFromSlot(int slot, int count, EntityPlayer player, boolean isHolding);
int putItemsIntoSlot(int slot, ItemStack stack, int count);
@@ -69,7 +69,7 @@ import cpw.mods.fml.relauncher.SideOnly;
import fox.spiteful.avaritia.items.ItemMatterCluster;
import xonin.backhand.api.core.BackhandUtils;
public class BlockDrawers extends BlockContainer implements INetworked, IExtendedBlockClickHandler {
public class BlockDrawers extends BlockContainer implements INetworked {
private static final ResourceLocation blockConfig = new ResourceLocation(
StorageDrawers.MOD_ID + ":textures/blocks/block_config.mcmeta");
@@ -496,13 +496,6 @@ public class BlockDrawers extends BlockContainer implements INetworked, IExtende
return true;
}
@Override
public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY,
float hitZ, boolean invertShift) {
TileEntityDrawers ted = getTileEntitySafe(world, x, y, z);
ted.onClick(player, x, y, z, side, world, hitX, hitY, hitZ, invertShift);
}
@Override
public boolean isSideSolid(IBlockAccess world, int x, int y, int z, ForgeDirection side) {
if (halfDepth) return false;
@@ -1,10 +1,9 @@
package com.jaquadro.minecraft.storagedrawers.block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
public interface IExtendedBlockClickHandler {
public void onBlockClicked(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY,
float hitZ, boolean invertShift);
public void onBlockClicked(EntityPlayer player, int side, float hitX, float hitY, float hitZ, boolean invertShift,
boolean isHolding);
}
@@ -14,8 +14,6 @@ import net.minecraft.network.NetworkManager;
import net.minecraft.network.Packet;
import net.minecraft.network.play.server.S35PacketUpdateTileEntity;
import net.minecraft.util.MathHelper;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.common.util.ForgeDirection;
@@ -43,7 +41,7 @@ import com.jaquadro.minecraft.storagedrawers.api.storage.attribute.ISealable;
import com.jaquadro.minecraft.storagedrawers.api.storage.attribute.LockAttribute;
import com.jaquadro.minecraft.storagedrawers.block.BlockDrawers;
import com.jaquadro.minecraft.storagedrawers.block.BlockDrawersCustom;
import com.jaquadro.minecraft.storagedrawers.common.DrawerClickProperty;
import com.jaquadro.minecraft.storagedrawers.block.IExtendedBlockClickHandler;
import com.jaquadro.minecraft.storagedrawers.config.ConfigManager;
import com.jaquadro.minecraft.storagedrawers.core.ModItems;
import com.jaquadro.minecraft.storagedrawers.inventory.ISideManager;
@@ -52,21 +50,17 @@ import com.jaquadro.minecraft.storagedrawers.network.CountUpdateMessage;
import com.jaquadro.minecraft.storagedrawers.storage.IUpgradeProvider;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.eventhandler.EventPriority;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.PlayerEvent;
import cpw.mods.fml.common.network.NetworkRegistry;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import it.unimi.dsi.fastutil.ints.IntIterators;
public abstract class TileEntityDrawers extends BaseTileEntity implements IDrawerGroupInteractive, ISidedInventory,
IUpgradeProvider, ILockable, ISealable, IProtectable, IDowngradable, CapabilityProvider {
public abstract class TileEntityDrawers extends BaseTileEntity
implements IDrawerGroupInteractive, ISidedInventory, IUpgradeProvider, ILockable, ISealable, IProtectable,
IDowngradable, CapabilityProvider, IExtendedBlockClickHandler {
private IDrawer[] drawers;
private IDrawerInventory inventory;
private int[] autoSides = new int[] { 0, 1, 2, 3, 4, 5 };
private int direction;
private int drawerCapacity = 1;
private boolean shrouded = false;
@@ -75,11 +69,6 @@ public abstract class TileEntityDrawers extends BaseTileEntity implements IDrawe
private boolean hideUpgrade = false;
private boolean downgraded = false;
private int ticksClickedInARow = 9;
private int itemsOutputInARow = 0;
private static boolean eventsRegistered = false;
private UUID owner;
private String securityKey;
@@ -98,11 +87,6 @@ public abstract class TileEntityDrawers extends BaseTileEntity implements IDrawe
protected TileEntityDrawers(int drawerCount) {
initWithDrawerCount(drawerCount);
if (!eventsRegistered) {
TileEntityDrawersEvents eventHandler = new TileEntityDrawersEvents();
MinecraftForge.EVENT_BUS.register(eventHandler);
eventsRegistered = true;
}
}
protected abstract IDrawer createDrawer(int slot);
@@ -393,13 +377,14 @@ public abstract class TileEntityDrawers extends BaseTileEntity implements IDrawe
downgraded = state;
}
public void onClick(EntityPlayer player, int x, int y, int z, int face, World world, float hitX, float hitY,
float hitZ, boolean invertShift) {
@Override
public void onBlockClicked(EntityPlayer player, int face, float hitX, float hitY, float hitZ, boolean invertShift,
boolean isHoldingClick) {
if (getDirection() != face) {
return;
}
BlockDrawers block = (BlockDrawers) world.getBlock(x, y, z);
BlockDrawers block = (BlockDrawers) worldObj.getBlock(xCoord, yCoord, zCoord);
int slot = block.getDrawerSlot(face, hitX, hitY, hitZ);
IDrawer drawer = getDrawer(slot);
@@ -408,7 +393,7 @@ public abstract class TileEntityDrawers extends BaseTileEntity implements IDrawe
}
int amount = getTakeAmount(player, invertShift, drawer);
ItemStack item = takeItemsFromSlot(slot, amount, player);
ItemStack item = takeItemsFromSlot(slot, amount, player, isHoldingClick);
traceItem(item);
@@ -416,7 +401,7 @@ public abstract class TileEntityDrawers extends BaseTileEntity implements IDrawe
return;
}
handleItemTransfer(player, world, block, item, x, y, z, face);
handleItemTransfer(player, block, item, face);
}
private int getTakeAmount(EntityPlayer player, boolean invertShift, IDrawer drawer) {
@@ -432,29 +417,28 @@ public abstract class TileEntityDrawers extends BaseTileEntity implements IDrawe
FMLLog.log(StorageDrawers.MOD_ID, Level.INFO, item == null ? " null item" : " " + item);
}
private void handleItemTransfer(EntityPlayer player, World world, BlockDrawers block, ItemStack item, int x, int y,
int z, int face) {
private void handleItemTransfer(EntityPlayer player, BlockDrawers block, ItemStack item, int face) {
if (!player.inventory.addItemStackToInventory(item)) {
dropFromFace(world, block, item, x, y, z, face);
dropFromFace(block, item, face);
return;
}
playPopSound(world, x, y, z);
playPopSound();
}
private void dropFromFace(World world, BlockDrawers block, ItemStack item, int x, int y, int z, int face) {
private void dropFromFace(BlockDrawers block, ItemStack item, int face) {
ForgeDirection dir = ForgeDirection.getOrientation(face);
block.dropItemStack(world, x + dir.offsetX, y, z + dir.offsetZ, item);
block.dropItemStack(worldObj, xCoord + dir.offsetX, yCoord, zCoord + dir.offsetZ, item);
}
private void playPopSound(World world, int x, int y, int z) {
world.playSoundEffect(
x + 0.5f,
y + 0.5f,
z + 0.5f,
private void playPopSound() {
worldObj.playSoundEffect(
xCoord + 0.5f,
yCoord + 0.5f,
zCoord + 0.5f,
"random.pop",
0.2f,
((world.rand.nextFloat() - world.rand.nextFloat()) * 0.7f + 1) * 2);
((worldObj.rand.nextFloat() - worldObj.rand.nextFloat()) * 0.7f + 1) * 2);
}
public boolean isVoid() {
@@ -613,39 +597,30 @@ public abstract class TileEntityDrawers extends BaseTileEntity implements IDrawe
materialTrim = material;
}
private DrawerClickProperty getProperties(EntityPlayer player) {
return (DrawerClickProperty) player.getExtendedProperties(DrawerClickProperty.PROP_KEY);
}
private float takeWhileHoldingInterval = 6;
private int takeWhileHoldingCountdown = 6;
/**
* Returns an ItemStack that will have a maximum size of {@link ItemStack#getMaxStackSize()}
*/
public ItemStack takeItemsFromSlot(int slot, int count, EntityPlayer player) {
public ItemStack takeItemsFromSlot(int slot, int count, EntityPlayer player, boolean isHoldingClick) {
if (slot < 0 || slot >= getDrawerCount()) return null;
ItemStack stack = getItemsFromSlot(slot, count);
if (stack == null) return null;
DrawerClickProperty property = getProperties(player);
if (isHoldingClick) {
if (--takeWhileHoldingCountdown != 0) {
return null;
}
if (property == null) return null;
if (worldObj.getTotalWorldTime() - property.lastLeftClickTime > 2) {
ticksClickedInARow = 9;
itemsOutputInARow = 0;
takeWhileHoldingInterval = Math.max(takeWhileHoldingInterval - 0.2F, 1);
takeWhileHoldingCountdown = (int) takeWhileHoldingInterval;
} else {
ticksClickedInARow++;
takeWhileHoldingInterval = 6;
takeWhileHoldingCountdown = 6;
}
property.lastLeftClickTime = worldObj.getTotalWorldTime();
int ticksConsecutiveClickRequirement = 50 / (itemsOutputInARow + 5);
if (ticksClickedInARow < ticksConsecutiveClickRequirement) return null;
ticksClickedInARow = 0;
itemsOutputInARow++;
IDrawer drawer = drawers[slot];
drawer.setStoredItemCount(drawer.getStoredItemCount() - stack.stackSize);
@@ -1104,11 +1079,13 @@ public abstract class TileEntityDrawers extends BaseTileEntity implements IDrawe
return inventory.isItemValidForSlot(slot, stack);
}
private class DefaultSideManager implements ISideManager {
private static class DefaultSideManager implements ISideManager {
private static final int[] accessibleSides = new int[] { 0, 1, 2, 3, 4, 5 };
@Override
public int[] getSlotsForSide(int side) {
return autoSides;
public int[] getAccessibleSides() {
return accessibleSides;
}
}
@@ -1220,13 +1197,4 @@ public abstract class TileEntityDrawers extends BaseTileEntity implements IDrawe
}
}
}
private class TileEntityDrawersEvents {
@SubscribeEvent(priority = EventPriority.NORMAL)
public void whenPlayerChangesDimension(PlayerEvent.PlayerChangedDimensionEvent event) {
DrawerClickProperty property = getProperties(event.player);
property.lastLeftClickTime = 0;
}
}
}
@@ -1,49 +0,0 @@
package com.jaquadro.minecraft.storagedrawers.common;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraftforge.common.IExtendedEntityProperties;
import net.minecraftforge.event.entity.EntityEvent;
import com.gtnewhorizon.gtnhlib.eventbus.EventBusSubscriber;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
@EventBusSubscriber
public class DrawerClickProperty implements IExtendedEntityProperties {
public static final String PROP_KEY = "drawer-click";
public long lastLeftClickTime;
@SubscribeEvent
public static void onEntityConstructing(EntityEvent.EntityConstructing event) {
if (event.entity instanceof EntityPlayer player) {
player.registerExtendedProperties(PROP_KEY, new DrawerClickProperty());
}
}
@Override
public void saveNBTData(NBTTagCompound compound) {
NBTTagCompound tag = new NBTTagCompound();
compound.setTag(PROP_KEY, tag);
tag.setLong("lastLeftClickTime", lastLeftClickTime);
}
@Override
public void loadNBTData(NBTTagCompound compound) {
NBTTagCompound tag = compound.getCompoundTag(PROP_KEY);
if (tag != null) {
lastLeftClickTime = tag.getLong("lastLeftClickTime");
}
}
@Override
public void init(Entity entity, World world) {
}
}
@@ -5,5 +5,5 @@ package com.jaquadro.minecraft.storagedrawers.inventory;
*/
public interface ISideManager {
public int[] getSlotsForSide(int side);
int[] getAccessibleSides();
}
@@ -88,9 +88,9 @@ public class StorageInventory implements IDrawerInventory {
@Override
public int[] getAccessibleSlotsFromSide(int side) {
int[] autoSides = sideMan.getSlotsForSide(side);
for (int aside : autoSides) {
if (side == aside) return inventorySlots;
int[] accessibleSides = sideMan.getAccessibleSides();
for (int aSide : accessibleSides) {
if (side == aSide) return inventorySlots;
}
return emptySlots;
@@ -3,11 +3,11 @@ package com.jaquadro.minecraft.storagedrawers.mixins.early;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.PlayerControllerMP;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.Vec3;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@@ -15,6 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.jaquadro.minecraft.storagedrawers.StorageDrawers;
import com.jaquadro.minecraft.storagedrawers.block.tile.TileEntityDrawers;
import com.jaquadro.minecraft.storagedrawers.network.BlockClickMessage;
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
@Mixin(value = PlayerControllerMP.class, priority = 10000)
public abstract class MixinPlayerControllerMP {
@@ -26,36 +27,37 @@ public abstract class MixinPlayerControllerMP {
@Shadow
public float curBlockDamageMP;
@Inject(
@Unique
private boolean storageDrawers$isHoldingClick = false;
@ModifyExpressionValue(
method = "onPlayerDamageBlock",
at = @At(
value = "FIELD",
target = "Lnet/minecraft/client/multiplayer/PlayerControllerMP;curBlockDamageMP:F",
opcode = org.objectweb.asm.Opcodes.PUTFIELD,
shift = At.Shift.AFTER))
private void storageDrawers$checkIfClickingDrawer(int x, int y, int z, int clickedSide, CallbackInfo ci) {
value = "INVOKE",
target = "Lnet/minecraft/block/Block;getPlayerRelativeBlockHardness(Lnet/minecraft/entity/player/EntityPlayer;Lnet/minecraft/world/World;III)F"))
private float storageDrawers$checkIfClickingDrawer(float originalHardness, int x, int y, int z, int clickedSide) {
final var thisTile = mc.theWorld.getTileEntity(x, y, z);
if (!(thisTile instanceof TileEntityDrawers drawer)) return;
if (drawer.getDirection() != clickedSide) return;
if (!(thisTile instanceof TileEntityDrawers drawer) || drawer.getDirection() != clickedSide) {
return originalHardness;
}
final int reach = 5;
double eyeX = mc.thePlayer.posX;
double eyeY = mc.thePlayer.posY + mc.thePlayer.getEyeHeight();
double eyeZ = mc.thePlayer.posZ;
Vec3 lookVec = mc.thePlayer.getLookVec();
Vec3 end = Vec3.createVectorHelper(
eyeX + lookVec.xCoord * reach,
eyeY + lookVec.yCoord * reach,
eyeZ + lookVec.zCoord * reach);
MovingObjectPosition mop = mc.theWorld.rayTraceBlocks(Vec3.createVectorHelper(eyeX, eyeY, eyeZ), end);
MovingObjectPosition mop = mc.objectMouseOver;
float hitX = (float) (mop.hitVec.xCoord - mop.blockX);
float hitY = (float) (mop.hitVec.yCoord - mop.blockY);
float hitZ = (float) (mop.hitVec.zCoord - mop.blockZ);
boolean invertShift = StorageDrawers.config.cache.invertShift;
curBlockDamageMP = 0.0F;
StorageDrawers.network.sendToServer(new BlockClickMessage(x, y, z, clickedSide, hitX, hitY, hitZ, invertShift));
boolean isHolding = this.storageDrawers$isHoldingClick;
this.storageDrawers$isHoldingClick = true;
StorageDrawers.network
.sendToServer(new BlockClickMessage(x, y, z, clickedSide, hitX, hitY, hitZ, invertShift, isHolding));
// Set curBlockDamageMP to 0 by cancelling itself out
return -curBlockDamageMP;
}
@Inject(method = "resetBlockRemoving", at = @At(value = "HEAD"))
private void storageDrawers$resetHoldingClick(CallbackInfo ci) {
this.storageDrawers$isHoldingClick = false;
}
}
@@ -1,6 +1,6 @@
package com.jaquadro.minecraft.storagedrawers.network;
import net.minecraft.block.Block;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import com.jaquadro.minecraft.storagedrawers.block.IExtendedBlockClickHandler;
@@ -21,10 +21,12 @@ public class BlockClickMessage implements IMessage {
private float hitY;
private float hitZ;
private boolean invertShift;
private boolean isHolding;
public BlockClickMessage() {}
public BlockClickMessage(int x, int y, int z, int side, float hitX, float hitY, float hitZ, boolean invertShift) {
public BlockClickMessage(int x, int y, int z, int side, float hitX, float hitY, float hitZ, boolean invertShift,
boolean isHolding) {
this.x = x;
this.y = y;
this.z = z;
@@ -33,6 +35,7 @@ public class BlockClickMessage implements IMessage {
this.hitY = hitY;
this.hitZ = hitZ;
this.invertShift = invertShift;
this.isHolding = isHolding;
}
@Override
@@ -45,6 +48,7 @@ public class BlockClickMessage implements IMessage {
hitY = buf.readFloat();
hitZ = buf.readFloat();
invertShift = buf.readBoolean();
isHolding = buf.readBoolean();
}
@Override
@@ -57,6 +61,7 @@ public class BlockClickMessage implements IMessage {
buf.writeFloat(hitY);
buf.writeFloat(hitZ);
buf.writeBoolean(invertShift);
buf.writeBoolean(isHolding);
}
public static class Handler implements IMessageHandler<BlockClickMessage, IMessage> {
@@ -65,18 +70,17 @@ public class BlockClickMessage implements IMessage {
public IMessage onMessage(BlockClickMessage message, MessageContext ctx) {
if (ctx.side == Side.SERVER) {
World world = ctx.getServerHandler().playerEntity.getEntityWorld();
Block block = world.getBlock(message.x, message.y, message.z);
if (block instanceof IExtendedBlockClickHandler) ((IExtendedBlockClickHandler) block).onBlockClicked(
world,
message.x,
message.y,
message.z,
ctx.getServerHandler().playerEntity,
message.side,
message.hitX,
message.hitY,
message.hitZ,
message.invertShift);
TileEntity tile = world.getTileEntity(message.x, message.y, message.z);
if (tile instanceof IExtendedBlockClickHandler handler) {
handler.onBlockClicked(
ctx.getServerHandler().playerEntity,
message.side,
message.hitX,
message.hitY,
message.hitZ,
message.invertShift,
message.isHolding);
}
}
return null;