i'm gonna brown

This commit is contained in:
HbmMods 2026-06-11 22:14:13 +02:00
parent 3d4e50cd33
commit 279a436639
5 changed files with 219 additions and 29 deletions

View File

@ -5,24 +5,33 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import com.hbm.interfaces.NotableComments;
import com.hbm.inventory.SlotNonRetarded;
import com.hbm.packet.PacketDispatcher;
import com.hbm.packet.toclient.ContainerCustomPayloadPacket;
import com.hbm.tileentity.network.pneumatic.TileEntityPneumoStorageAccess;
import com.hbm.util.ItemStackUtil;
import com.hbm.util.EnumUtil;
import api.hbm.ntl.StackCache;
import api.hbm.ntl.StackCache.CacheSlot;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.inventory.ICrafting;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
public class ContainerPneumoStorageAccess extends Container {
@NotableComments // i long for the day when i never have to look at this fucking horseshit ever again
public class ContainerPneumoStorageAccess extends Container implements ICustomPayloadReceiver {
protected TileEntityPneumoStorageAccess access;
protected InventoryPneumoStorageAccess inventory;
public static final int GRID_SIZE = 6 * 8;
public static final String STACK_SIZE_KEY = "PNEUMO_STACK_SIZE";
public ContainerPneumoStorageAccess(InventoryPlayer invPlayer, TileEntityPneumoStorageAccess access) {
@ -31,7 +40,7 @@ public class ContainerPneumoStorageAccess extends Container {
for(int i = 0; i < 6; i++) {
for(int j = 0; j < 8; j++) {
this.addSlotToContainer(new SlotNonRetarded(inventory, j + i * 8, 8 + j * 18, 17 + i * 18)); // TODO: add a new slot type that holds a long for the amount
this.addSlotToContainer(new SlotPneumo(inventory, j + i * 8, 8 + j * 18, 17 + i * 18));
}
}
@ -57,16 +66,16 @@ public class ContainerPneumoStorageAccess extends Container {
@Override
public ItemStack slotClick(int index, int button, int mode, EntityPlayer player) {
if(index >= 0 && index < 6 * 8) {
if(index >= 0 && index < GRID_SIZE) {
boolean client = player.worldObj.isRemote;
Slot slot = this.getSlot(index);
SlotPneumo slot = (SlotPneumo) this.getSlot(index);
ItemStack held = player.inventory.getItemStack();
if(held == null && slot.getHasStack() && slot.getStack().hasTagCompound()) {
if(held == null && slot.getHasStack()) {
ItemStack stack = slot.getStack().copy();
if(button == 0) {
int toGrab = (int) Math.min(stack.getMaxStackSize(), stack.stackTagCompound.getLong(STACK_SIZE_KEY));
int toGrab = (int) Math.min(stack.getMaxStackSize(), slot.amount);
if(client) {
stack.stackSize = toGrab;
@ -78,19 +87,142 @@ public class ContainerPneumoStorageAccess extends Container {
player.inventory.setItemStack(stack);
}
}
return slot.getStack().copy();
}
return slot.getHasStack() ? slot.getStack().copy() : null;
}
return super.slotClick(index, button, mode, player);
}
@Override
public void addCraftingToCrafters(ICrafting crafting) {
super.addCraftingToCrafters(crafting);
}
/** Used only on the client side to set the contents of a slot after a sync */
@Override
public void putStackInSlot(int index, ItemStack slot) {
this.getSlot(index).putStack(slot);
}
public long[] previousStackSizes = new long[GRID_SIZE];
/**
* All syncing is done using the ICrafting interface (which only EntityPlayerMP implements), each single slot change is one entire fucking
* packet that is sent like a massive pile of pricks to each client. Who cares, right. Issue is, this interface only supports sending of
* ItemStacks and integer values with integer keys for the progress bars. We need longs which are indexed, so at least an extra byte along
* with that. After some fucking about I decided, well vanilla container code is complete fucking shit anyway, why bother with any of that?
* Instead, we just skip all the syncing for that and use our custom crap packet. Depending on whether the stack, the count, or both has changed,
* we send the requested data in a single packet.
*/
@Override
public void detectAndSendChanges() {
// skip the first 6*8 slots, i.e. all the ones visible in the access grid
for(int i = GRID_SIZE; i < this.inventorySlots.size(); i++) {
ItemStack stack0 = ((Slot) this.inventorySlots.get(i)).getStack();
ItemStack stack1 = (ItemStack) this.inventoryItemStacks.get(i);
if(!ItemStack.areItemStacksEqual(stack1, stack0)) {
stack1 = stack0 == null ? null : stack0.copy();
this.inventoryItemStacks.set(i, stack1);
for(int j = 0; j < this.crafters.size(); ++j) {
((ICrafting) this.crafters.get(j)).sendSlotContents(this, i, stack1);
}
}
}
// custom horseshit scum fuck
NBTTagList list = new NBTTagList();
if(this.access.cache != null && !this.access.cache.hasExpired) for(int i = 0; i < GRID_SIZE; i++) {
PneumoMesageType msg = null;
SlotPneumo slot = (SlotPneumo) this.inventorySlots.get(i);
ItemStack actualStack = slot.getStack();
long cachedSize = slot.amount;
CacheSlot cacheSlot = actualStack != null ? this.access.cache.getSlotFromStack(actualStack) : null;
long actualSize = cacheSlot != null ? cacheSlot.stacksize : 0;
if(actualSize <= 0) actualStack = null;
ItemStack cachedStack = (ItemStack) this.inventoryItemStacks.get(i);
if(!ItemStack.areItemStacksEqual(cachedStack, actualStack)) msg = PneumoMesageType.UPDATE_TYPE;
if(cachedSize != actualSize || actualSize > 0 /* HACK: solve this by moving the listing change to the container class and writing the correct amounts on init */) {
if(msg == PneumoMesageType.UPDATE_TYPE) msg = PneumoMesageType.UPDATE_ALL;
if(msg == null) msg = PneumoMesageType.UPDATE_COUNT;
}
if(msg != null) {
cachedStack = actualStack == null ? null : actualStack.copy();
this.inventoryItemStacks.set(i, cachedStack);
slot.amount = actualSize;
NBTTagCompound listEntry = new NBTTagCompound();
listEntry.setByte(KEY_TYPE, (byte) msg.ordinal());
listEntry.setByte(KEY_SLOT_INDEX, (byte) i);
if(msg == PneumoMesageType.UPDATE_ALL || msg == PneumoMesageType.UPDATE_COUNT) {
listEntry.setLong(KEY_LONG_COUNT, actualSize);
}
if(msg == PneumoMesageType.UPDATE_ALL || msg == PneumoMesageType.UPDATE_TYPE) if(actualStack != null) actualStack.writeToNBT(listEntry);
list.appendTag(listEntry);
}
}
if(list.tagCount() > 0) {
NBTTagCompound masterTag = new NBTTagCompound();
masterTag.setTag("list", list);
for(Object o : this.crafters) {
if(o instanceof EntityPlayerMP) {
EntityPlayerMP playerMP = (EntityPlayerMP) o;
PacketDispatcher.wrapper.sendTo(new ContainerCustomPayloadPacket(playerMP.currentWindowId, masterTag), playerMP);
}
}
}
}
public static final String KEY_TYPE = "t";
public static final String KEY_SLOT_INDEX = "s";
public static final String KEY_LONG_COUNT = "lc";
public static enum PneumoMesageType {
UPDATE_COUNT,
UPDATE_TYPE,
UPDATE_ALL;
}
@Override
public void acceptData(int windowId, NBTTagCompound data) {
if(windowId != this.windowId) return;
NBTTagList list = data.getTagList("list", 10);
for(int i = 0; i < list.tagCount(); i++) {
NBTTagCompound listEntry = list.getCompoundTagAt(i);
PneumoMesageType msg = EnumUtil.grabEnumSafely(PneumoMesageType.class, listEntry.getByte(KEY_TYPE));
int slotIndex = listEntry.getByte(KEY_SLOT_INDEX);
SlotPneumo slot = (SlotPneumo) this.inventorySlots.get(slotIndex);
if(msg == PneumoMesageType.UPDATE_ALL || msg == PneumoMesageType.UPDATE_COUNT) slot.amount = listEntry.getLong(KEY_LONG_COUNT);
if(msg == PneumoMesageType.UPDATE_ALL || msg == PneumoMesageType.UPDATE_TYPE) slot.putStack(ItemStack.loadItemStackFromNBT(listEntry));
}
}
@Override
public ItemStack transferStackInSlot(EntityPlayer player, int index) {
return null;
}
public static class SlotPneumo extends SlotNonRetarded {
public long amount;
public SlotPneumo(IInventory inventory, int id, int x, int y) {
super(inventory, id, x, y);
}
}
/** This inventory instance only exists to prepare the contents of a StackCache in such a way that we can use it in a container. */
public static class InventoryPneumoStorageAccess implements IInventory {
@ -115,8 +247,6 @@ public class ContainerPneumoStorageAccess extends Container {
CacheSlot cache = cacheSlots.get(i);
if(cache.displayStack != null) {
slots[i] = cache.displayStack.copy();
ItemStackUtil.addTooltipToStack(slots[i], "x" + cache.stacksize, "in " + cache.monitors.size() + " stacks");
slots[i].stackTagCompound.setLong(STACK_SIZE_KEY, cache.stacksize); // TODO instead of altering the stacks so we can't resolve anything anymore, hijack the progress bar system
}
}
}
@ -125,19 +255,19 @@ public class ContainerPneumoStorageAccess extends Container {
public static final Comparator<CacheSlot> SORT_BY_STACK_SIZE = new Comparator<CacheSlot>() {
@Override
public int compare(CacheSlot o1, CacheSlot o2) {
if(o1.stacksize > o2.stacksize) return 1; if(o1.stacksize < o2.stacksize) return -1;
if(o1.itemId < o2.itemId) return 1; if(o1.itemId > o2.itemId) return -1;
if(o1.meta < o2.meta) return 1; if(o1.meta > o2.meta) return -1;
if(o1.nbt == null && o2.nbt != null) return 1; if(o1.nbt != null && o2.nbt == null) return -1;
if(o1.stacksize > o2.stacksize) return -1; if(o1.stacksize < o2.stacksize) return 1;
if(o1.itemId < o2.itemId) return -1; if(o1.itemId > o2.itemId) return 1;
if(o1.meta < o2.meta) return -1; if(o1.meta > o2.meta) return 1;
if(o1.nbt == null && o2.nbt != null) return -1; if(o1.nbt != null && o2.nbt == null) return 1;
return 0;
}
};
@Override public int getSizeInventory() { return 6 * 9; }
@Override public int getSizeInventory() { return GRID_SIZE; }
@Override public ItemStack getStackInSlot(int slot) { return slots[slot]; }
@Override public int getInventoryStackLimit() { return 64; }
@Override public ItemStack decrStackSize(int slot, int amount) { return null; }
@Override public void setInventorySlotContents(int slot, ItemStack stack) { this.slots[slot] = stack; }
@Override
public ItemStack getStackInSlotOnClosing(int slot) {
@ -149,22 +279,11 @@ public class ContainerPneumoStorageAccess extends Container {
return null;
}
@Override
public void setInventorySlotContents(int slot, ItemStack stack) {
this.slots[slot] = stack;
}
@Override public String getInventoryName() { return "null"; }
@Override public boolean hasCustomInventoryName() { return false; }
@Override public boolean isItemValidForSlot(int slot, ItemStack stack) { return false; }
@Override
public void markDirty() {
}
@Override public void markDirty() { }
@Override public boolean isUseableByPlayer(EntityPlayer player) { return true; }
@Override public void openInventory() { }
@Override public void closeInventory() { }
}

View File

@ -0,0 +1,8 @@
package com.hbm.inventory.container;
import net.minecraft.nbt.NBTTagCompound;
public interface ICustomPayloadReceiver {
public void acceptData(int windowsId, NBTTagCompound data);
}

View File

@ -6,6 +6,7 @@ import org.lwjgl.opengl.GL11;
import static com.hbm.inventory.gui.element.GUIElements.*;
import com.hbm.inventory.container.ContainerPneumoStorageAccess;
import com.hbm.inventory.container.ContainerPneumoStorageAccess.SlotPneumo;
import com.hbm.inventory.gui.element.GUIElements;
import com.hbm.lib.RefStrings;
import com.hbm.tileentity.network.pneumatic.TileEntityPneumoStorageAccess;
@ -14,6 +15,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
@ -34,6 +36,13 @@ public class GUIPneumoStorageAccess extends GuiInfoContainer {
@Override
public void drawScreen(int x, int y, float interp) {
super.drawScreen(x, y, interp);
Slot slot = this.getSlotAtPosition(x, y);
if(slot instanceof SlotPneumo) {
SlotPneumo pneumo = (SlotPneumo) slot;
if(pneumo.getHasStack()) this.drawInfo(new String[] {"x" + pneumo.amount}, x, y - 15);
}
}
@Override

View File

@ -69,6 +69,8 @@ public class PacketDispatcher {
wrapper.registerMessage(HeldItemNBTPacket.Handler.class, HeldItemNBTPacket.class, i++, Side.CLIENT);
//Syncs muzzle flashes of SEDNA guns for clients from other entities/players
wrapper.registerMessage(MuzzleFlashPacket.Handler.class, MuzzleFlashPacket.class, i++, Side.CLIENT);
//Sends custom container-bound payload from a server container to a client one
wrapper.registerMessage(ContainerCustomPayloadPacket.Handler.class, ContainerCustomPayloadPacket.class, i++, Side.CLIENT);
}
}

View File

@ -0,0 +1,52 @@
package com.hbm.packet.toclient;
import com.hbm.inventory.container.ICustomPayloadReceiver;
import com.hbm.main.MainRegistry;
import com.hbm.util.BufferUtil;
import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
public class ContainerCustomPayloadPacket implements IMessage {
int windowId;
NBTTagCompound data;
public ContainerCustomPayloadPacket() { }
public ContainerCustomPayloadPacket(int windowId, NBTTagCompound data) {
this.windowId = windowId;
this.data = data;
}
@Override
public void fromBytes(ByteBuf buf) {
this.windowId = buf.readInt();
this.data = BufferUtil.readNBT(buf);
}
@Override
public void toBytes(ByteBuf buf) {
buf.writeInt(this.windowId);
BufferUtil.writeNBT(buf, this.data);
}
public static class Handler implements IMessageHandler<ContainerCustomPayloadPacket, IMessage> {
@SideOnly(Side.CLIENT) @Override
public IMessage onMessage(ContainerCustomPayloadPacket m, MessageContext ctx) {
EntityPlayer player = MainRegistry.proxy.me();
if(player.openContainer instanceof ICustomPayloadReceiver) {
ICustomPayloadReceiver cus = (ICustomPayloadReceiver) player.openContainer;
cus.acceptData(m.windowId, m.data);
}
return null;
}
}
}