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

[1.16.5] Help with Capability (Inventory)


Luis_ST
 Share

Recommended Posts

I want to overwrite the vanilla ender chest container that the enderchest uses the double chest container.

I looked in the enderchest class vanilla uses PlayerEntity#getInventoryEnderChest

to open the gui so my question how to creat my own enderchest gui with 54 slots?

 

I know that I have to create my own capability. do I have to create a completely new one or can I use IItemHandler in my TileEntity?

because in the forge doc to capabilities it says that I can use persisting capabilities.

if I can use an existing capability, is this capability unique for each player?

(this is the first time that i use capabilities so i have no experience with them).

Link to comment
Share on other sites

First, you can't store the inventory in the tile entity, because the ender chest inventory is bound to the player. So you have to use a capability that's attached to the player. You can't use the normal IItemHandler capability for this, because players (and all living entities for that matter) already have it. So you need to make an interface that extends IItemHandler and make a class that extends ItemStackHandler and implements your new interface. Then use that as the capability.

If you want to be really fancy you can make your new inventory only for the additional slots so that the existing ender inventory is carried over once your mod is installed.

 

Then to make the vanilla ender chest open your new container, use PlayerInteractEvent.RightClickBlock.

Link to comment
Share on other sites

34 minutes ago, diesieben07 said:

No, you just need a separate interface because you can't have two capabilities with the same interface.

Now i have my custom Interfacce and a class which extends ItemStackHandler and implements my interface

now i have to create a new capability like forge doc:

@CapabilityInject(MyInterface.class)
public static Capability<MyInterface> ITEM_HANDLER_CAPABILITY = null;

but should the class in which i created the capability extends / implements another class

Link to comment
Share on other sites

17 minutes ago, diesieben07 said:

This is described in the docs on capabilities.

i just read this, and i created this but i'm not sure if this is correct:

 

public class ModCapability {
	
	public ModCapability() {
		
		CapabilityManager.INSTANCE.register(IModItemHandler.class, new Storage(), null);
		
	}
	
	private static class Storage implements IStorage<IModItemHandler> {

		@Override
		public INBT writeNBT(Capability<IModItemHandler> capability, IModItemHandler instance, Direction side) {
			
			return null;
			
		}

		@Override
		public void readNBT(Capability<IModItemHandler> capability, IModItemHandler instance, Direction side, INBT nbt) {
			
			
		}
		
	}
	
}

 

Link to comment
Share on other sites

20 minutes ago, diesieben07 said:

The last parameter for register must not be null.

do i need the factory?

and what's wrong with the factory?

	public ModCapability() {
		
		CapabilityManager.INSTANCE.register(IModItemHandler.class, new Storage(), new Factory());
		
	}
	
	private static class Storage implements IStorage<IModItemHandler> {

		@Override
		public INBT writeNBT(Capability<IModItemHandler> capability, IModItemHandler instance, Direction side) {
			
			return null;
			
		}

		@Override
		public void readNBT(Capability<IModItemHandler> capability, IModItemHandler instance, Direction side, INBT nbt) {
			
			
		}
		
	}
	
	private static class Factory implements Callable<IModItemHandler> {

		@Override
		public IModItemHandler call() throws Exception {
			// what is here wrong?
			return new IModItemHandler();
			
		}
		
	}

 

Link to comment
Share on other sites

5 minutes ago, diesieben07 said:

The Storage and Factory will most likely go away in the future, it was a flawed concept.

You can just make them throw exceptions.

this is now my complet class is this corect:

	@CapabilityInject(IModItemHandler.class)
	public static Capability<IModItemHandler> ITEM_HANDLER_CAPABILITY = null;
	
	public ModCapability() {
		
		CapabilityManager.INSTANCE.register(IModItemHandler.class, new Storage(), new Factory());
		
	}
	
	private static class Storage implements IStorage<IModItemHandler> {

		@Override
		public INBT writeNBT(Capability<IModItemHandler> capability, IModItemHandler instance, Direction side) {
			
			return null;
			
		}

		@Override
		public void readNBT(Capability<IModItemHandler> capability, IModItemHandler instance, Direction side, INBT nbt) {
			
			
		}
		
	}
	
	private static class Factory implements Callable<IModItemHandler> {

		@Override
		public IModItemHandler call() throws Exception {
			
			return null;
			
		}
		
	}

 

Link to comment
Share on other sites

17 hours ago, diesieben07 said:

You already register it...

Another question how to add the extendsEnderChestGui (Generic9x3 ChestContainer) to the Capability (with this two methode \/ )

do I have to synchronize the gui between the server and the client and if so how do I do it since I looked at a few mods on github that use SimpleChannel and an interface is there another way to do this?

 

		@Override
		public INBT writeNBT(Capability<IModItemHandler> capability, IModItemHandler instance, Direction side) {
			
			CompoundNBT nbt = new CompoundNBT();
			return nbt;
			
		}

		@Override
		public void readNBT(Capability<IModItemHandler> capability, IModItemHandler instance, Direction side, INBT nbt) {
			
			
			
		}

 

Edited by Luis_ST
Link to comment
Share on other sites

16 hours ago, Luis_ST said:

Another question how to add the extendsEnderChestGui (Generic9x3 ChestContainer) to the Capability (with this two methode \/ )

Why would you extend EnderChestGui? You need to write your own Gui, the EnderChestGui is based on using the vanilla ender chest.

The two methods you have shown are not relevant, I already told you that IStorage and the generic factory are outdated concepts and not to use them.

 

16 hours ago, Luis_ST said:

muss ich das gui zwischen server und client synchronisieren

No. Container already does this for you.

 

Also, please keep this forum in English.

Link to comment
Share on other sites

1 hour ago, diesieben07 said:

Also, please keep this forum in English.

Sorry I forgot i translate it into english

 

1 hour ago, diesieben07 said:

No. Container already does this for you.

okay thanks, if I don't want to overwrite the block (ender chest).

can I open the gui with the PlayerInteractEvent#RightClickBlock (using NetworkHooks)

the container and when closing save them in the capability?

 

do i have to creat a container with screen or an inventory because the ender chest use an inventory

Edited by Luis_ST
Link to comment
Share on other sites

7 minutes ago, diesieben07 said:

The Container will already modify the capability (IItemHandler) directly.

so i just have to open the container / inventory and forge saves the gui from automatically?

 

22 minutes ago, Luis_ST said:

do i have to creat a container with screen or an inventory because the ender chest use an inventory

?

 

and where i have to put the container/inventory into the capability because when i use the AttachCapabilitiesEvent i got an NullPointerException:

event:

	@SubscribeEvent
	public static void AttachCapabilities(AttachCapabilitiesEvent<Entity> event) {
		
		if (event.getObject() instanceof PlayerEntity && !(event.getObject() instanceof FakePlayer)) {
			
			event.addCapability(new ResourceLocation("cave:extended_enderchest_gui"), new ModCapability.Provider());
			
		}
		
	}

 

and error log:

[10:38:50] [Server thread/ERROR] [ne.mi.ev.EventBus/EVENTBUS]: Exception caught during firing event: null
	Index: 1
	Listeners:
		0: NORMAL
		1: ASM: class net.luis.cave.events.capability.OnAttachCapabilitiesEvent AttachCapabilities(Lnet/minecraftforge/event/AttachCapabilitiesEvent;)V
java.lang.NullPointerException
	at java.base/java.util.Objects.requireNonNull(Objects.java:208)
	at net.luis.cave.init.ModCapability$Provider.<init>(ModCapability.java:59)
	at net.luis.cave.events.capability.OnAttachCapabilitiesEvent.AttachCapabilities(OnAttachCapabilitiesEvent.java:21)
	at net.minecraftforge.eventbus.ASMEventHandler_16_OnAttachCapabilitiesEvent_AttachCapabilities_AttachCapabilitiesEvent.invoke(.dynamic)
	at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:85)
	at net.minecraftforge.eventbus.EventBus.post(EventBus.java:302)
	at net.minecraftforge.eventbus.EventBus.post(EventBus.java:283)
	at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:579)
	at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:573)
	at net.minecraftforge.common.capabilities.CapabilityProvider.gatherCapabilities(CapabilityProvider.java:48)
	at net.minecraftforge.common.capabilities.CapabilityProvider.gatherCapabilities(CapabilityProvider.java:44)
	at net.minecraft.entity.Entity.<init>(Entity.java:221)
	at net.minecraft.entity.LivingEntity.<init>(LivingEntity.java:207)
	at net.minecraft.entity.player.PlayerEntity.<init>(PlayerEntity.java:160)
	at net.minecraft.entity.player.ServerPlayerEntity.<init>(ServerPlayerEntity.java:182)
	at net.minecraft.server.management.PlayerList.createPlayerForUser(PlayerList.java:419)
	at net.minecraft.network.login.ServerLoginNetHandler.tryAcceptPlayer(ServerLoginNetHandler.java:122)
	at net.minecraft.network.login.ServerLoginNetHandler.tick(ServerLoginNetHandler.java:66)
	at net.minecraft.network.NetworkManager.tick(NetworkManager.java:244)
	at net.minecraft.network.NetworkSystem.tick(NetworkSystem.java:151)
	at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:898)
	at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:820)
	at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:84)
	at net.minecraft.server.MinecraftServer.func_240802_v_(MinecraftServer.java:663)
	at net.minecraft.server.MinecraftServer.lambda$startServer$0(MinecraftServer.java:233)
	at java.base/java.lang.Thread.run(Thread.java:832)

[10:38:50] [Server thread/FATAL] [ne.mi.co.ForgeMod/]: Preparing crash report with UUID 3dbca5d1-2854-4053-a647-dfa6633d91c6
[10:38:50] [Server thread/ERROR] [minecraft/MinecraftServer]: Encountered an unexpected exception
net.minecraft.crash.ReportedException: Ticking memory connection
	at net.minecraft.network.NetworkSystem.tick(NetworkSystem.java:154) ~[forge:?] {re:classloading}
	at net.minecraft.server.MinecraftServer.updateTimeLightAndEntities(MinecraftServer.java:898) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.tick(MinecraftServer.java:820) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.integrated.IntegratedServer.tick(IntegratedServer.java:84) ~[forge:?] {re:classloading,pl:runtimedistcleaner:A}
	at net.minecraft.server.MinecraftServer.func_240802_v_(MinecraftServer.java:663) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.MinecraftServer.lambda$startServer$0(MinecraftServer.java:233) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at java.lang.Thread.run(Thread.java:832) [?:?] {}
Caused by: java.lang.NullPointerException
	at java.util.Objects.requireNonNull(Objects.java:208) ~[?:?] {}
	at net.luis.cave.init.ModCapability$Provider.<init>(ModCapability.java:59) ~[main/:?] {re:classloading}
	at net.luis.cave.events.capability.OnAttachCapabilitiesEvent.AttachCapabilities(OnAttachCapabilitiesEvent.java:21) ~[main/:?] {re:classloading}
	at net.minecraftforge.eventbus.ASMEventHandler_16_OnAttachCapabilitiesEvent_AttachCapabilities_AttachCapabilitiesEvent.invoke(.dynamic) ~[?:?] {}
	at net.minecraftforge.eventbus.ASMEventHandler.invoke(ASMEventHandler.java:85) ~[eventbus-4.0.0.jar:?] {}
	at net.minecraftforge.eventbus.EventBus.post(EventBus.java:302) ~[eventbus-4.0.0.jar:?] {}
	at net.minecraftforge.eventbus.EventBus.post(EventBus.java:283) ~[eventbus-4.0.0.jar:?] {}
	at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:579) ~[forge:?] {re:classloading}
	at net.minecraftforge.event.ForgeEventFactory.gatherCapabilities(ForgeEventFactory.java:573) ~[forge:?] {re:classloading}
	at net.minecraftforge.common.capabilities.CapabilityProvider.gatherCapabilities(CapabilityProvider.java:48) ~[forge:?] {re:classloading}
	at net.minecraftforge.common.capabilities.CapabilityProvider.gatherCapabilities(CapabilityProvider.java:44) ~[forge:?] {re:classloading}
	at net.minecraft.entity.Entity.<init>(Entity.java:221) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.entity.LivingEntity.<init>(LivingEntity.java:207) ~[forge:?] {re:classloading}
	at net.minecraft.entity.player.PlayerEntity.<init>(PlayerEntity.java:160) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.entity.player.ServerPlayerEntity.<init>(ServerPlayerEntity.java:182) ~[forge:?] {re:classloading,pl:accesstransformer:B}
	at net.minecraft.server.management.PlayerList.createPlayerForUser(PlayerList.java:419) ~[forge:?] {re:classloading}
	at net.minecraft.network.login.ServerLoginNetHandler.tryAcceptPlayer(ServerLoginNetHandler.java:122) ~[forge:?] {re:classloading}
	at net.minecraft.network.login.ServerLoginNetHandler.tick(ServerLoginNetHandler.java:66) ~[forge:?] {re:classloading}
	at net.minecraft.network.NetworkManager.tick(NetworkManager.java:244) ~[forge:?] {re:classloading}
	at net.minecraft.network.NetworkSystem.tick(NetworkSystem.java:151) ~[forge:?] {re:classloading}
	... 6 more

 

Link to comment
Share on other sites

Just now, Luis_ST said:

so i just have to open the container / inventory and forge saves the gui from automatically?

This has nothing to do with Forge. When you open a Container you give it an inventory. Minecraft's Container code shows the contents of the inventory and will store any modifications directly in the inventory. Of course you still have to write the inventory to disk somehow, but that is unrelated to the fact if the inventory is even shown in a container or not.

 

1 minute ago, Luis_ST said:

and where i have to put the container/inventory into the capability

The container is completely unrelated to the capability. The inventory (i.e. IItemHandler) is the capability implementation.

 

2 minutes ago, Luis_ST said:

and where i have to put the container/inventory into the capability because when i use the AttachCapabilitiesEvent i got an NullPointerException:

event:

[...]

and error log:

How about you show the code that is actually crashing based on the stacktrace?

Link to comment
Share on other sites

3 minutes ago, diesieben07 said:

The container is completely unrelated to the capability. The inventory (i.e. IItemHandler) is the capability implementation.

so i have to use IItemHandler to get and open the gui inside there:

NetworkHooks.openGui(serverPlayer, /*here*/, pos);

 

and:

public class ModCapability {
	
	@CapabilityInject(IModItemHandler.class)
	public static Capability<IModItemHandler> CAPABILITY = null;
	
	public ModCapability() {
		
		CapabilityManager.INSTANCE.register(IModItemHandler.class, new Storage(), new Factory());
		
	}
	
	public static class Storage implements IStorage<IModItemHandler> {
		@Override
		public INBT writeNBT(Capability<IModItemHandler> capability, IModItemHandler instance, Direction side) {
			return null;
		}

		@Override
		public void readNBT(Capability<IModItemHandler> capability, IModItemHandler instance, Direction side, INBT nbt) {
		}
	}
	
	public static class Factory implements Callable<IModItemHandler> {
		@Override
		public IModItemHandler call() throws Exception {
			return null;
		}
	}
	
	public static class Provider implements ICapabilityProvider {

		private final LazyOptional<IModItemHandler> lazyOptional = LazyOptional.of(CAPABILITY::getDefaultInstance);
		
		@Override
		public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
			
			return cap == CAPABILITY ? lazyOptional.cast() : LazyOptional.empty();
			
		}
		
	}
	
}

 

Link to comment
Share on other sites

2 minutes ago, Luis_ST said:

so i have to use IItemHandler to get and open the gui inside there:


NetworkHooks.openGui(serverPlayer, /*here*/, pos);

 

No, you need to implement INamedContainerProvider.

 

2 minutes ago, Luis_ST said:

private final LazyOptional<IModItemHandler> lazyOptional = LazyOptional.of(CAPABILITY::getDefaultInstance);

Obviously you can't do this if your default factory returns null. Use a normal constructor.

Link to comment
Share on other sites

9 minutes ago, diesieben07 said:

No, you need to implement INamedContainerProvider.

do i only have to implement Named ContainerProvider because i currently extends Chest Container / Container and i think thats wrong

 

34 minutes ago, diesieben07 said:

Obviously you can't do this if your default factory returns null. Use a normal constructor.

so like this:

	public static class Provider implements ICapabilityProvider {
		
		@Override
		public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
			
			return null;
			
		}
		
	}

 

Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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.

 Share




×
×
  • Create New...

Important Information

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