Jump to content

[Solved] [1.7.10] Making a container have 0 slots sometimes, 5 other times


IceMetalPunk

Recommended Posts

I'm a long-time programmer, but very new to Forge (and somewhat new to Java). I'm working on a small mod to get myself into the language and API, and it's all going well, except I've hit a roadblock.

 

The mod is supposed to add "Ender hoppers" with a slightly different functionality from the regular ones, which it does. These hoppers store the UUID of the players who place them in an ownerUUID member variable, then are able to pull/push to and from their owner's Ender Chest inventory. This is all working just fine.

 

However, I'm trying to make it so that if a player opens the hopper's inventory, if they're not the owner, they won't be able to use any of the hopper's slots--it'll be "locked", effectively. I figured this would be easy enough by making a separate Container class and GUI class for a "locked" Ender hopper and displaying that one if the activating player isn't a match. If they're both passed a 0-slot inventory (i.e. a new class that simply implements IInventory but doesn't ever set any slots), it *should* display an unusable inventory, right?

 

At least, that was what I thought. Instead, if a non-owner player right-clicks on the Ender hopper, no GUI shows up. Even worse, their player inventory gets all screwed up, with items moving around to seemingly random slots, including armor, inventory, and hotbar slots. I can't seem to figure out what I'm doing wrong here.

 

Here's the relevant code (imports excluded for brevity):

 

EnderHoppers.java (main mod class) GUI registration:

 

NetworkRegistry.INSTANCE.registerGuiHandler(this, new EnderHopperGui());

 

 

EnderHopperGui.java:

 

public class EnderHopperGui implements IGuiHandler {

@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
	// TODO Auto-generated method stub
        TileEntity tileEntity = world.getTileEntity(x, y, z);
        if(tileEntity instanceof TileEntityEnderHopper){
        	if (ID==0) {
        		return new ContainerHopper(player.inventory, (TileEntityEnderHopper) tileEntity);
        	}
        	else {
        		return new ContainerLockedEnderHopper(player.inventory, new EmptyInventory());
        	}
        }
        return null;
}

@Override
public Object getClientGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
        TileEntity tileEntity = world.getTileEntity(x, y, z);
        
        if(tileEntity instanceof TileEntityEnderHopper){
        	if (ID==0) {
                return new GuiHopper(player.inventory, (TileEntityEnderHopper) tileEntity);
        	}
        	else {
        		return new GuiLockedEnderHopper(player.inventory, (TileEntityEnderHopper) tileEntity);
        	}
        }
        return null;
}

}

 

 

(EmptyInventory is just a class which implements IInventory and returns 0, null, or false appropriately for all methods.)

 

BlockEnderHopper.java onBlockActivated method:

 

    public boolean onBlockActivated(World p_149727_1_, int p_149727_2_, int p_149727_3_, int p_149727_4_, EntityPlayer p_149727_5_, int p_149727_6_, float p_149727_7_, float p_149727_8_, float p_149727_9_)
    {
        if (p_149727_1_.isRemote)
        {
            return true;
        }
        else
        {
            TileEntityEnderHopper tileentityhopper = func_149920_e(p_149727_1_, p_149727_2_, p_149727_3_, p_149727_4_);

            if (tileentityhopper != null)
            {
            	if (p_149727_5_.getGameProfile().getId().equals(tileentityhopper.getOwner())) {
            		p_149727_5_.openGui(EnderHoppers.instance, 0, p_149727_1_, p_149727_2_, p_149727_3_, p_149727_4_);
            	}
            	else {
            		p_149727_5_.openGui(EnderHoppers.instance, 1, p_149727_1_, p_149727_2_, p_149727_3_, p_149727_4_);
            	}
            }
            return true;
        }
    }

 

 

(getOwner() returns the tile entity's ownerUUID, which I've verified is correct. GUI 0 is a normal, unlocked Ender hopper, which works; GUI 1 is a locked Ender hopper, which does not work.)

 

GUILockedEnderHopper.java:

 

@SideOnly(Side.CLIENT)
public class GuiLockedEnderHopper extends GuiContainer
{
    private static final ResourceLocation field_147085_u = new ResourceLocation("enderhoppers:textures/gui/container/locked_ender_hopper.png");
    private IInventory field_147084_v;
    private IInventory field_147083_w;
    private TileEntityEnderHopper hopper;
    private static final String __OBFID = "CL_00000759";

    public GuiLockedEnderHopper(InventoryPlayer p_i1092_1_, TileEntityEnderHopper hop)
    {
        super(new ContainerLockedEnderHopper(p_i1092_1_, hop));
        this.field_147084_v = p_i1092_1_;
        this.field_147083_w = hop;
        this.allowUserInput = false;
        this.ySize = 133;
    }

    /**
     * Draw the foreground layer for the GuiContainer (everything in front of the items)
     */
    protected void drawGuiContainerForegroundLayer(int p_146979_1_, int p_146979_2_)
    {
    	String name=((TileEntityEnderHopper)(field_147083_w)).getOwnerName();
        this.fontRendererObj.drawString("Bound to "+name, 8, 6, 4210752);
        this.fontRendererObj.drawString("Bound to "+name, 8, this.ySize - 96 + 2, 4210752);
    }

    protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_)
    {
        GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
        this.mc.getTextureManager().bindTexture(field_147085_u);
        int k = (this.width - this.xSize) / 2;
        int l = (this.height - this.ySize) / 2;
        this.drawTexturedModalRect(k, l, 0, 0, this.xSize, this.ySize);
    }
}

 

 

(The getOwnerName() method returns the string name of the owner of the hopper. I'm 100% sure the texture is loading properly as it worked before I tried making it 0-slots.)

 

ContainerLockedEnderHopper.java:

 

public class ContainerLockedEnderHopper extends Container
{
    private final IInventory field_94538_a;
    private static final String __OBFID = "CL_00001750";

    public ContainerLockedEnderHopper(InventoryPlayer p_i1814_1_, IInventory p_i1814_2_)
    {
        this.field_94538_a = p_i1814_2_;
        p_i1814_2_.openInventory();
        byte b0 = 51;
        int i;

        // Hopper slots
        for (i = 0; i < p_i1814_2_.getSizeInventory(); ++i)
        {
            this.addSlotToContainer(new Slot(p_i1814_2_, i, 44 + i * 18, 20));
        }

        // 3x9 inventory slots
        for (i = 0; i < 3; ++i)
        {
            for (int j = 0; j < 9; ++j)
            {
                this.addSlotToContainer(new Slot(p_i1814_1_, j + i * 9 + 9, 8 + j * 18, i * 18 + b0));
            }
        }

        // Hotbar slots
        for (i = 0; i < 9; ++i)
        {
            this.addSlotToContainer(new Slot(p_i1814_1_, i, 8 + i * 18, 58 + b0));
        }
    }

    public boolean canInteractWith(EntityPlayer p_75145_1_)
    {
    	return false;
        //return this.field_94538_a.isUseableByPlayer(p_75145_1_);
    }

    /**
     * Called when a player shift-clicks on a slot. You must override this or you will crash when someone does that.
     */
    public ItemStack transferStackInSlot(EntityPlayer p_82846_1_, int p_82846_2_)
    {
        ItemStack itemstack = null;
        Slot slot = (Slot)this.inventorySlots.get(p_82846_2_);

        if (slot != null && slot.getHasStack())
        {
            ItemStack itemstack1 = slot.getStack();
            itemstack = itemstack1.copy();

            if (p_82846_2_ < this.field_94538_a.getSizeInventory())
            {
                if (!this.mergeItemStack(itemstack1, this.field_94538_a.getSizeInventory(), this.inventorySlots.size(), true))
                {
                    return null;
                }
            }
            else if (!this.mergeItemStack(itemstack1, 0, this.field_94538_a.getSizeInventory(), false))
            {
                return null;
            }

            if (itemstack1.stackSize == 0)
            {
                slot.putStack((ItemStack)null);
            }
            else
            {
                slot.onSlotChanged();
            }
        }

        return itemstack;
    }

    /**
     * Called when the container is closed.
     */
    public void onContainerClosed(EntityPlayer p_75134_1_)
    {
        super.onContainerClosed(p_75134_1_);
        this.field_94538_a.closeInventory();
    }
}

 

 

I tried setting canInteractWith() to always return false, thinking that would do my job without needing the EmptyInventory class, but it didn't seem to do anything at all no matter what it returned, so I moved on to trying the EmptyInventory method.

 

Can anyone see where I've gone wrong, or maybe a better/easier way to get this functionality working?

Whatever Minecraft needs, it is most likely not yet another tool tier.

Link to comment
Share on other sites

*EDIT* Oops! I figured out the problem...I had canInteractWith returning false constantly, which stops the container from showing up >_< . Fixed it all now! Thanks for your help; the LockedSlot class idea is definitely more elegant than my EmptyInventory technique :)

 

*Original post below saved for the archives...*

 

Ah! That sounds like a good idea. And yet, it still doesn't work :( It doesn't mess up the player's inventory anymore, but it still doesn't show the GUI. Here's the code I've updated from the original above, plus I've deleted the EmptyInventory class:

 

EnderHopperGui.java:

 

	@Override
public Object getServerGuiElement(int ID, EntityPlayer player, World world, int x, int y, int z) {
	// TODO Auto-generated method stub
        TileEntity tileEntity = world.getTileEntity(x, y, z);
        if(tileEntity instanceof TileEntityEnderHopper){
        	if (ID==0) {
        		return new ContainerHopper(player.inventory, (TileEntityEnderHopper) tileEntity);
        	}
        	else {
        		return new ContainerLockedEnderHopper(player.inventory,  (TileEntityEnderHopper) tileEntity);
        	}
        }
        return null;
}

 

 

ContainerLockedHopper.java:

 

public ContainerLockedEnderHopper(InventoryPlayer p_i1814_1_, IInventory p_i1814_2_)
    {
        this.field_94538_a = p_i1814_2_;
        p_i1814_2_.openInventory();
        byte b0 = 51;
        int i;

        // Hopper slots
        for (i = 0; i < p_i1814_2_.getSizeInventory(); ++i)
        {
            this.addSlotToContainer(new LockedSlot(p_i1814_2_, i, 44 + i * 18, 20));
        }

        // 3x9 inventory slots
        for (i = 0; i < 3; ++i)
        {
            for (int j = 0; j < 9; ++j)
            {
                this.addSlotToContainer(new Slot(p_i1814_1_, j + i * 9 + 9, 8 + j * 18, i * 18 + b0));
            }
        }

        // Hotbar slots
        for (i = 0; i < 9; ++i)
        {
            this.addSlotToContainer(new Slot(p_i1814_1_, i, 8 + i * 18, 58 + b0));
        }
    }

 

 

LockedSlot.java:

 

package enderhoppers;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;

public class LockedSlot extends Slot {

public LockedSlot(IInventory p_i1824_1_, int p_i1824_2_, int p_i1824_3_, int p_i1824_4_) {
	super(p_i1824_1_, p_i1824_2_, p_i1824_3_, p_i1824_4_);
}

@Override
public boolean canTakeStack(EntityPlayer player) {
	return false;
}

}

 

 

Not sure why the UI isn't even showing up at all...

Whatever Minecraft needs, it is most likely not yet another tool tier.

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Thank you! I have been looking for a solution to the problem for 3 months now, without finding an answer. The problem with displaying the skin was precisely on version 1.18.2, even in a single player game and only with Forge. Moreover, everything worked correctly on another computer. I'm already tired of looking for the problem. I deleted everything I could from the programs on my PC, nothing helped. I saw your post and unchecked IPv6 in the properties of my network connection and the problem disappeared! Thank you, you saved my nerve cells! Sorry for my English.
    • I once had a friend who shared a fascinating story about his spending habits. He was an avid World of Warcraft player, and his obsession with the game reached a new level when he decided to invest a substantial amount of money in amirdrassil the dream's hope boost services for his characters. Despite my initial shock at the expense, he explained that it was his way of enhancing his gaming experience. This memory serves as a reminder that people are willing to go to great lengths to pursue their passions, even if it means spending a significant sum.
    • I've been playing the ATFC modpack recently, however I've been having some performance issues. I tried to fix this by adding various performance mods - but it's only created more issues. This is my log file: https://pastebin.com/9a6r2ah4 I use PrismMC, an external launcher - separate from the Official Minecraft Launcher. I run ZorinOS 16.3 (A Linux Distro). I have 16Gb of RAM, I have an Intel Core i5-4570 CPU, and I have a NVIDIA GeForce GTX 1050 Ti GPU. This is the beginning of the error: [main/ERROR] [ne.mi.fm.lo.mo.ModDiscoverer/SCAN]: Failed to build unique mod list after mod discovery. net.minecraftforge.fml.loading.EarlyLoadingException: Duplicate mods found Help would be greatly appreciated! Sorry if my formatting is wrong - I'm very new here.
    • I believe I posted this topic in the wrong forum so I shall post it again. Hello, I am getting an error when trying to load into a personal modpack of mine. It's been giving this error ever since I started working on adding mods again, and I don't know what's causing it. I don't have a crash report since it is merely me getting kicked from my singleplayer world but I do have the error from the logs. I can provide the full log and debug.log on mclogs or pastebin if required. [26Sep2023 19:45:40.003] [Server thread/ERROR] [net.minecraft.server.network.ServerLoginPacketListenerImpl/]: Couldn't place player in world java.util.NoSuchElementException: No value present at java.util.Optional.orElseThrow(Optional.java:377) ~[?:?] at potionstudios.byg.common.world.LevelBiomeTracker.lambda$fromServer$6(LevelBiomeTracker.java:55) ~[Oh_The_Biomes_You'll_Go-forge-1.19.2-2.0.1.4.jar%23514!/:**.**.**.**] at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:178) ~[?:?] at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:992) ~[?:?] at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[?:?] at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[?:?] at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) ~[?:?] at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) ~[?:?] at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?] at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) ~[?:?] at potionstudios.byg.common.world.LevelBiomeTracker.fromServer(LevelBiomeTracker.java:55) ~[Oh_The_Biomes_You'll_Go-forge-1.19.2-2.0.1.4.jar%23514!/:**.**.**.**] at net.minecraft.server.level.ServerLevel.handler$bkb000$warnExperimentalBYG(ServerLevel.java:3269) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?] at net.minecraft.server.level.ServerLevel.m_8853_(ServerLevel.java) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?] at net.minecraft.server.level.ServerLevel.m_8834_(ServerLevel.java:780) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?] at net.minecraft.server.players.PlayerList.m_11261_(PlayerList.java:198) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?] at net.minecraft.server.network.ServerLoginPacketListenerImpl.m_143699_(ServerLoginPacketListenerImpl.java:156) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?] at net.minecraft.server.network.ServerLoginPacketListenerImpl.m_10055_(ServerLoginPacketListenerImpl.java:143) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?] at net.minecraft.server.network.ServerLoginPacketListenerImpl.m_9933_(ServerLoginPacketListenerImpl.java:75) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?] at net.minecraft.network.Connection.m_129483_(Connection.java:248) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?] at net.minecraft.server.network.ServerConnectionListener.m_9721_(ServerConnectionListener.java:143) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?] at net.minecraft.server.MinecraftServer.m_5703_(MinecraftServer.java:880) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?] at net.minecraft.server.MinecraftServer.m_5705_(MinecraftServer.java:806) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?] at net.minecraft.client.server.IntegratedServer.m_5705_(IntegratedServer.java:84) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?] at net.minecraft.server.MinecraftServer.m_130011_(MinecraftServer.java:654) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?] at net.minecraft.server.MinecraftServer.m_206580_(MinecraftServer.java:244) ~[client-1.19.2-20220805.130853-srg.jar%23585!/:?]  
    • When trying to open Minecraft with the modpack installed it simply does not open and does not generate any crash-report, I only get the following log Forge 1.20.1 Server Log [#nhetr9s] - mclo.gs [27sep.2023 20:20:52.088] [main/INFO] [cpw.mods.modlauncher.Launcher/MODLAUNCHER]: ModLauncher running: args [--username, Raven, --version, 1.20.1-forge-47.2.0, --gameDir, C:\Users\ADMIN\AppData\Roaming\.minecraft, --assetsDir, C:\Users\ADMIN\AppData\Roaming\.minecraft\assets, --assetIndex, 5, --uuid, c133294fda623a7fb0c85f27d7f0f3fc, --accessToken, ????????, --clientId, 0, --xuid, 0, --userType, mojang, --versionType, release, --width, 854, --height, 480, --launchTarget, forgeclient, --fml.forgeVersion, 47.2.0, --fml.mcVersion, 1.20.1, --fml.forgeGroup, net.minecraftforge, --fml.mcpVersion, 20230612.114412] [27sep.2023 20:20:52.095] [main/INFO] [cpw.mods.modlauncher.Launcher/MODLAUNCHER]: ModLauncher 10.0.9+10.0.9+main.dcd20f30 starting: java version 17.0.8 by Microsoft; OS Windows 10 arch amd64 version 10.0 [27sep.2023 20:20:54.925] [main/INFO] [net.minecraftforge.fml.loading.ImmediateWindowHandler/]: Loading ImmediateWindowProvider fmlearlywindow [27sep.2023 20:20:55.087] [main/INFO] [EARLYDISPLAY/]: Trying GL version 4.6 [27sep.2023 20:20:55.109] [main/INFO] [EARLYDISPLAY/]: Trying GL version 4.5 [27sep.2023 20:20:55.111] [main/INFO] [EARLYDISPLAY/]: Trying GL version 4.4 [27sep.2023 20:20:55.113] [main/INFO] [EARLYDISPLAY/]: Trying GL version 4.3 [27sep.2023 20:20:55.115] [main/INFO] [EARLYDISPLAY/]: Trying GL version 4.2 [27sep.2023 20:20:55.124] [main/INFO] [EARLYDISPLAY/]: Trying GL version 4.1 [27sep.2023 20:20:55.132] [main/INFO] [EARLYDISPLAY/]: Trying GL version 4.0 [27sep.2023 20:20:55.156] [main/INFO] [EARLYDISPLAY/]: Requested GL version 4.0 got version 4.0 [27sep.2023 20:20:55.345] [main/INFO] [mixin/]: SpongePowered MIXIN Subsystem Version=0.8.5 Source=union:/C:/Users/ADMIN/AppData/Roaming/.minecraft/libraries/org/spongepowered/mixin/0.8.5/mixin-0.8.5.jar%23100!/ Service=ModLauncher Env=CLIENT [27sep.2023 20:20:55.421] [pool-4-thread-1/INFO] [EARLYDISPLAY/]: GL info: Intel(R) HD Graphics 2500 GL version 4.0.0 - Build 10.18.10.5161, Intel [27sep.2023 20:20:56.983] [main/WARN] [net.minecraftforge.fml.loading.moddiscovery.ModFileParser/LOADING]: Mod file C:\Users\ADMIN\AppData\Roaming\.minecraft\libraries\net\minecraftforge\fmlcore\1.20.1-47.2.0\fmlcore-1.20.1-47.2.0.jar is missing mods.toml file [27sep.2023 20:20:56.987] [main/WARN] [net.minecraftforge.fml.loading.moddiscovery.ModFileParser/LOADING]: Mod file C:\Users\ADMIN\AppData\Roaming\.minecraft\libraries\net\minecraftforge\javafmllanguage\1.20.1-47.2.0\javafmllanguage-1.20.1-47.2.0.jar is missing mods.toml file [27sep.2023 20:20:56.991] [main/WARN] [net.minecraftforge.fml.loading.moddiscovery.ModFileParser/LOADING]: Mod file C:\Users\ADMIN\AppData\Roaming\.minecraft\libraries\net\minecraftforge\lowcodelanguage\1.20.1-47.2.0\lowcodelanguage-1.20.1-47.2.0.jar is missing mods.toml file [27sep.2023 20:20:56.994] [main/WARN] [net.minecraftforge.fml.loading.moddiscovery.ModFileParser/LOADING]: Mod file C:\Users\ADMIN\AppData\Roaming\.minecraft\libraries\net\minecraftforge\mclanguage\1.20.1-47.2.0\mclanguage-1.20.1-47.2.0.jar is missing mods.toml file [27sep.2023 20:20:58.045] [main/WARN] [net.minecraftforge.jarjar.selection.JarSelector/]: Attempted to select two dependency jars from JarJar which have the same identification: Mod File:  and Mod File: . Using Mod File:  [27sep.2023 20:20:58.047] [main/WARN] [net.minecraftforge.jarjar.selection.JarSelector/]: Attempted to select a dependency jar for JarJar which was passed in as source: geckolib. Using Mod File: C:\Users\ADMIN\AppData\Roaming\.minecraft\mods\geckolib-forge-1.20.1-4.2.3.jar [27sep.2023 20:20:58.047] [main/INFO] [net.minecraftforge.fml.loading.moddiscovery.JarInJarDependencyLocator/]: Found 40 dependencies adding them to mods collection [27sep.2023 20:20:58.639] [main/INFO] [org.groovymc.gml.mappings.MappingsProvider/]: Starting runtime mappings setup... [27sep.2023 20:20:58.669] [main/INFO] [org.groovymc.gml.internal.locator.ModLocatorInjector/]: Injecting ScriptModLocator candidates... [27sep.2023 20:20:58.686] [main/INFO] [org.groovymc.gml.scriptmods.ScriptModLocator/]: Injected Jimfs file system [27sep.2023 20:20:58.695] [main/INFO] [org.groovymc.gml.scriptmods.ScriptModLocator/]: Skipped loading script mods from directory C:\Users\ADMIN\AppData\Roaming\.minecraft\mods\scripts as it did not exist. [27sep.2023 20:20:58.704] [main/INFO] [org.groovymc.gml.internal.locator.ModLocatorInjector/]: Injected ScriptModLocator mod candidates. Found 0 valid mod candidates and 0 broken mod files. [27sep.2023 20:21:03.252] [GML Mappings Thread/INFO] [org.groovymc.gml.mappings.MappingsProvider/]: Loaded runtime mappings in 4271ms [27sep.2023 20:21:03.253] [GML Mappings Thread/INFO] [org.groovymc.gml.mappings.MappingsProvider/]: Finished runtime mappings setup.  
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.