Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

[1.16.4] Display Inventory of a different container


Recommended Posts

I am currently wokring on a block which lets you register and see the inventory of registered blocks. I.e. i want to display what is inside a chest which could be 10 blocks away. I am not looking to change its inventory, just look at it. Since i can't just use the LockableLootTileEntity::getItems method I have to set with recreating the inventory by looping through with LockableLootTileEntity::getStackInSlot. Problem is I only get an empty ItemStack (1 air block) from that method. No matter which index. For reference:

private void changeInventory(LockableLootTileEntity te) {
		int size = te.getSizeInventory();
		this.activeInventory = NonNullList.create();
		for(int i = 0; i < size; i++) {
			this.activeInventory.add(te.getStackInSlot(i));
		}
	}

What am I missing. Is there a better way to read an inventory of a different block? Going the normal way via the container does not work either since that field is protected as well.

Link to post
Share on other sites

I thought there would be a forge way to get access to the inventory. I havent yet fully wrapped my head around the capability system which is probably why I didnt think of it. I will get back to you if I cant figure it out by myself.

 

The above code is located in the screen class of my "controler" block. Im using the inventory there in order to just render the ItemStacks. For now I dont plan to add other functionality in the screen. Later on I would want to add a villager interaction but thats some time away.

 

As a side question: This forum is not yet switched over to the official mappings? And if not, will it in the near future? Or will you support both for now?

Link to post
Share on other sites
56 minutes ago, Titmar said:

The above code is located in the screen class of my "controler" block. Im using the inventory there in order to just render the ItemStacks.

There is your issue. Inventories are not known on the client unless you are currently looking at them in a GUI or the block takes extra care to sync them (none of the vanilla blocks do this).

Link to post
Share on other sites
57 minutes ago, Titmar said:

As a side question: This forum is not yet switched over to the official mappings? And if not, will it in the near future? Or will you support both for now?

Personally I switched all my workspaces, but if you ask something in MCP mappings I can convert. But I'll probably answer in Mojang names :P

Link to post
Share on other sites
25 minutes ago, diesieben07 said:

There is your issue. Inventories are not known on the client unless you are currently looking at them in a GUI or the block takes extra care to sync them (none of the vanilla blocks do this).

okay, so even with the capability i wouldnt be able to get the inventory clientside i suppose. How would i sync from server to client in this case? Because apparently

private void changeInventory(LockableLootTileEntity te) {
		IItemHandler handler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(null); 
		if(handler == null) return;
		this.activeInventory = NonNullList.create();
		for(int i = 0; i < handler.getSlots(); i++) {
			this.activeInventory.add(handler.getStackInSlot(i));
		}
	}

does not resolve the issue

Link to post
Share on other sites
19 minutes ago, loordgek said:

you need to look server side for items and sent them to the client

 

I know how to send from client to server via the SimpleChannel Network but I have no idea how to send packets the other way. As in, I could send a request to the server from the client but how would I answer it? How do i send backwards?

Link to post
Share on other sites

I do have said block which you can register inventory blocks to, i call it market. When opening its GUI I have a bunch of buttons which are connected to those registered inventories. When pressing a button i want to show the inventory of its connected block until i chose another (similar to the selection of an active trade with a villager). Now I could of course set some global variable such that it shows the same inventory for every player. But I would like it independent such that every player can browse independently from others.

Link to post
Share on other sites

Okay so I had a bit of a deeper look into the syncing of containers. Vanilla is using the Container::detectAndSendChanges method which in turn uses a list of private listeners it sends those changes to. My current code

Spoiler

In my container class


	public void setActiveInventory(BlockPos pos) {
		if(!(this.te.getWorld().getTileEntity(pos) instanceof LockableLootTileEntity)) {
			return;
		}
		LockableLootTileEntity tile = (LockableLootTileEntity) this.te.getWorld().getTileEntity(pos);
		IItemHandler handler = tile.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).orElse(null);
		if (handler != null) {
			activeInventory = NonNullList.create();
			this.inventorySlots.clear();
			int startX = 108;
			int startY = 34;
			int row = 1;
			int col = 1;
			for (int i = 0; i < handler.getSlots(); i++) {
				this.addSlot(new Slot(tile, i, startX + (col * 16), startY + (row * 16)));
				col++;
				if (col > 9) {
					col = 1;
					row++;
				}
				activeInventory.add(handler.getStackInSlot(i));
			}
			detectAndSendChanges();
		}
	}

 

You see I am resetting the slots and recreate them for the new Inventory which makes the vanilla method unable to detect any changes. Reason being that I would like to be able to support custom sized inventories. Of course I could set a maximum size for the inventory and just clear all slots before refilling them. But that is just limiting functionality.

Now I cant override the Container::detectAndSendChanges method since it uses said private field of listeners making it inaccessible for child classes.

Also, when I call above function setActiveInventory from my Screen class, does that even solve the whole sync issue? Or is there a standard way of doing this? Since opening the GUI creates a new Container every time and I cant access that from anywhere...

Link to post
Share on other sites

If you just want to display the data I wouldn't use normal Slots (they come with a lot of baggage to support interacting with the slot). So I'd just check for changes in the inventory in detectAndSendChanges (similar to how vanilla does it for normal slots) and then send any changes using a custom packet.

Link to post
Share on other sites

Alright, I got it all working now. In the end it was easy after finding out abut the player.openContainer field...

On Button press, send a custom packet. This custom packet tells the server to update the players openContainer like so:

Spoiler

public static void handle(ChangeActiveInventoryMessage message, Supplier<NetworkEvent.Context> contextSupplier) {
		NetworkEvent.Context context = contextSupplier.get();
		context.enqueueWork(() -> {
			ServerPlayerEntity player = context.getSender();
			if(player.openContainer instanceof MarketContainer) {
				((MarketContainer)player.openContainer).setActiveInventory(message.pos);
			}
		});
		context.setPacketHandled(true);
	}

 

Nothing else to do afterwards. Vanilla takes care of the rest apparently. At least for now I havent found any bugs, though I only tested it with a single player and only on a single player world.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



  • Recently Browsing

    No registered users viewing this page.

  • Posts

    • don't use this in separate classes, use the EventBusSubscriber annotation instead https://mcforge.readthedocs.io/en/latest/events/intro/#events
    • Im playing with MultiMC. I get to the "Loading world, Bulding Terrain..." screen and then it goes to minecraft dindn't respond. I've been at this for two hour now. I can't find any articles that deal with this error. I also have OptiFine installed, I tried deleting the options text file and restarting but still no luck. I dunno which information is important so I'll post the full log. ---- Minecraft Crash Report ---- WARNING: coremods are present:   LucraftCoreCoreMod (LucraftCore-1.12.2-2.4.16.jar)   MalisisCorePlugin (malisiscore-1.12.2-6.5.1.jar) Contact their authors BEFORE contacting forge // My bad. Time: 7/23/21 5:25 PM Description: Ticking player java.lang.NoSuchMethodError: lucraft.mods.lucraftcore.superpowers.abilities.Ability.getCurrentPlayerAbilities(Lnet/minecraft/entity/player/EntityPlayer;)Ljava/util/List;     at lucraft.mods.speedsterheroes.abilities.AbilityPhasing$EventHandler.onLivingUpdate(AbilityPhasing.java:82)     at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_54_EventHandler_onLivingUpdate_LivingUpdateEvent.invoke(.dynamic)     at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90)     at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:182)     at net.minecraftforge.common.ForgeHooks.onLivingUpdate(ForgeHooks.java:581)     at net.minecraft.entity.EntityLivingBase.func_70071_h_(EntityLivingBase.java:2095)     at net.minecraft.entity.player.EntityPlayer.func_70071_h_(EntityPlayer.java:234)     at net.minecraft.entity.player.EntityPlayerMP.func_71127_g(EntityPlayerMP.java:382)     at net.minecraft.network.NetHandlerPlayServer.func_73660_a(NetHandlerPlayServer.java:173)     at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.func_73660_a(NetworkDispatcher.java:209)     at net.minecraft.network.NetworkManager.func_74428_b(NetworkManager.java:285)     at net.minecraft.network.NetworkSystem.func_151269_c(NetworkSystem.java:180)     at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:790)     at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:668)     at net.minecraft.server.integrated.IntegratedServer.func_71217_p(IntegratedServer.java:279)     at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:526)     at java.lang.Thread.run(Unknown Source) A detailed walkthrough of the error, its code path and all known details is as follows: --------------------------------------------------------------------------------------- -- Head -- Thread: Server thread Stacktrace:     at lucraft.mods.speedsterheroes.abilities.AbilityPhasing$EventHandler.onLivingUpdate(AbilityPhasing.java:82)     at net.minecraftforge.fml.common.eventhandler.ASMEventHandler_54_EventHandler_onLivingUpdate_LivingUpdateEvent.invoke(.dynamic)     at net.minecraftforge.fml.common.eventhandler.ASMEventHandler.invoke(ASMEventHandler.java:90)     at net.minecraftforge.fml.common.eventhandler.EventBus.post(EventBus.java:182)     at net.minecraftforge.common.ForgeHooks.onLivingUpdate(ForgeHooks.java:581)     at net.minecraft.entity.EntityLivingBase.func_70071_h_(EntityLivingBase.java:2095)     at net.minecraft.entity.player.EntityPlayer.func_70071_h_(EntityPlayer.java:234) -- Player being ticked -- Details:     Entity Type: null (net.minecraft.entity.player.EntityPlayerMP)     Entity ID: 1844     Entity Name: RedcreeperYT_     Entity's Exact location: 453.50, 4.00, 91.50     Entity's Block location: World: (453,4,91), Chunk: (at 5,0,11 in 28,5; contains blocks 448,0,80 to 463,255,95), Region: (0,0; contains chunks 0,0 to 31,31, blocks 0,0,0 to 511,255,511)     Entity's Momentum: 0.00, 0.00, 0.00     Entity's Passengers: []     Entity's Vehicle: ~~ERROR~~ NullPointerException: null Stacktrace:     at net.minecraft.entity.player.EntityPlayerMP.func_71127_g(EntityPlayerMP.java:382)     at net.minecraft.network.NetHandlerPlayServer.func_73660_a(NetHandlerPlayServer.java:173)     at net.minecraftforge.fml.common.network.handshake.NetworkDispatcher$1.func_73660_a(NetworkDispatcher.java:209)     at net.minecraft.network.NetworkManager.func_74428_b(NetworkManager.java:285) -- Ticking connection -- Details:     Connection: net.minecraft.network.NetworkManager@29c7e996 Stacktrace:     at net.minecraft.network.NetworkSystem.func_151269_c(NetworkSystem.java:180)     at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:790)     at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:668)     at net.minecraft.server.integrated.IntegratedServer.func_71217_p(IntegratedServer.java:279)     at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:526)     at java.lang.Thread.run(Unknown Source) -- System Details -- Details:     Minecraft Version: 1.12.2     Operating System: Windows 10 (amd64) version 10.0     Java Version: 1.8.0_291, Oracle Corporation     Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation     Memory: 1306579696 bytes (1246 MB) / 2693267456 bytes (2568 MB) up to 3817865216 bytes (3641 MB)     JVM Flags: 3 total; -XX:HeapDumpPath=MojangTricksIntelDriversForPerformance_javaw.exe_minecraft.exe.heapdump -Xms512m -Xmx4096m     IntCache: cache: 0, tcache: 0, allocated: 0, tallocated: 0     FML: MCP 9.42 Powered by Forge 14.23.5.2855 Optifine OptiFine_1.12.2_HD_U_G6_pre1 19 mods loaded, 19 mods active     States: 'U' = Unloaded 'L' = Loaded 'C' = Constructed 'H' = Pre-initialized 'I' = Initialized 'J' = Post-initialized 'A' = Available 'D' = Disabled 'E' = Errored     | State  | ID              | Version               | Source                                   | Signature                                |     |:------ |:--------------- |:--------------------- |:---------------------------------------- |:---------------------------------------- |     | LCHIJA | minecraft       | 1.12.2                | minecraft.jar                            | None                                     |     | LCHIJA | mcp             | 9.42                  | minecraft.jar                            | None                                     |     | LCHIJA | FML             | 8.0.99.99             | forge-1.12.2-14.23.5.2855-universal.jar  | e3c3d50c7c986df74c645c0ac54639741c90a557 |     | LCHIJA | forge           | 14.23.5.2855          | forge-1.12.2-14.23.5.2855-universal.jar  | e3c3d50c7c986df74c645c0ac54639741c90a557 |     | LCHIJA | securitycraft   | v1.8.22.2             | [1.12.2]+SecurityCraft+v1.8.22.2.jar     | None                                     |     | LCHIJA | customspawner   | 3.11.4                | Custom-Mob-Spawner-Mod-1.12.2.jar        | None                                     |     | LCHIJA | ptrmodellib     | 1.0.4                 | PTRLib-1.0.4.jar                         | None                                     |     | LCHIJA | props           | 2.6.3                 | Decocraft-2.6.3_1.12.2.jar               | None                                     |     | LCHIJA | jei             | 4.16.1.302            | jei_1.12.2-4.16.1.302.jar                | None                                     |     | LCHIJA | speedsterheroes | 1.12.2-2.0.7          | Quicksilver-Mod-1.12.2.jar               | None                                     |     | LCHIJA | lucraftcore     | 1.12.2-2.4.16         | LucraftCore-1.12.2-2.4.16.jar            | None                                     |     | LCHIJA | malisiscore     | 1.12.2-6.5.1-SNAPSHOT | malisiscore-1.12.2-6.5.1.jar             | None                                     |     | LCHIJA | malisisdoors    | 1.12.2-7.3.0          | malisisdoors-1.12.2-7.3.0.jar            | None                                     |     | LCHIJA | mocreatures     | 12.0.5                | Mo-Creatures-Mod-1.12.2.jar              | None                                     |     | LCHIJA | movingelevators | 1.2.34                | movingelevators-1.2.34-mc1.12.jar        | None                                     |     | LCHIJA | scp             | 2.4.0                 | SCP_Lockdown-1.12.2-2.4.0-hotfix.jar     | None                                     |     | LCHIJA | scple           | 1.0                   | scple-1.0.jar                            | None                                     |     | LCHIJA | thejungle       | 1.2006.1222           | Welcome-to-the-Jungle-Mod-1.12.2.jar     | None                                     |     | LCHIJA | worldedit       | 6.1.10                | worldedit-forge-mc1.12.2-6.1.10-dist.jar | None                                     |     Loaded coremods (and transformers):  LucraftCoreCoreMod (LucraftCore-1.12.2-2.4.16.jar)   lucraft.mods.lucraftcore.core.LCTransformer MalisisCorePlugin (malisiscore-1.12.2-6.5.1.jar)        GL info: ~~ERROR~~ RuntimeException: No OpenGL context found in the current thread.     Profiler Position: N/A (disabled)     Player Count: 1 / 8; [EntityPlayerMP['RedcreeperYT_'/1844, l='New World', x=453.50, y=4.00, z=91.50]]     Type: Integrated Server (map_client.txt)     Is Modded: Definitely; Client brand changed to 'fml,forge'     OptiFine Version: OptiFine_1.12.2_HD_U_G6_pre1     OptiFine Build: 20210323-161358     Render Distance Chunks: 8     Mipmaps: 4     Anisotropic Filtering: 1     Antialiasing: 0     Multitexture: false     Shaders: null     OpenGlVersion: 4.6.0 NVIDIA 466.27     OpenGlRenderer: NVIDIA GeForce GTX 1650 SUPER/PCIe/SSE2     OpenGlVendor: NVIDIA Corporation     CpuCount: 4
    • Goal: when Entity attacks player, it dies. Code: public class EventHandler { @SubscribeEvent public static void onLivingAttackEvent(LivingAttackEvent event) { if (event.getEntityLiving().getItemStackFromSlot(EquipmentSlotType.HEAD).getItem() == ItemInit.LAVA_HELMET.get() && event.getEntityLiving().getItemStackFromSlot(EquipmentSlotType.CHEST).getItem() == ItemInit.LAVA_CHEST.get() && event.getEntityLiving().getItemStackFromSlot(EquipmentSlotType.LEGS).getItem() == ItemInit.LAVA_LEGGINGS.get() && event.getEntityLiving().getItemStackFromSlot(EquipmentSlotType.FEET).getItem() == ItemInit.LAVA_BOOTS.get()) { if (event.getSource().getTrueSource().getEntity() instanceof MobEntity) { event.getSource().getTrueSource().getEntity().onKillCommand(); } } } } And: @Mod(LavaArmor.MODID) public class LavaArmor { public static final String MODID = "lavaarmor"; public LavaArmor() { IEventBus bus = FMLJavaModLoadingContext.get().getModEventBus(); bus.addListener(this::setup); ItemInit.ITEMS.register(bus); MinecraftForge.EVENT_BUS.register(this); MinecraftForge.EVENT_BUS.register(EventHandler.class); } @SuppressWarnings("deprecation") private void setup(final FMLCommonSetupEvent event) { } } I think I've done everything I've needed. Moreover, the exact same code works fine in my another project. What's wrong?
    • The same question. The only thing I could find is CommentedFileConfig.preserveInsertionOrder(), but either it doesn't work, or I'm doing something wrong...
  • Topics

  • Who's Online (See full list)

×
×
  • Create New...

Important Information

By using this site, you agree to our Privacy Policy.