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

37 minutes ago, Luis_ST said:

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

You need both. You need a Container (and the corresponding ContainerType and ScreenFactory) and you need to implement INamedContainerProvider for openGui.

 

39 minutes ago, Luis_ST said:

so like this:


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

 

No... Not at all.

Link to comment
Share on other sites

3 hours ago, diesieben07 said:

You need both. You need a Container (and the corresponding ContainerType and ScreenFactory) and you need to implement INamedContainerProvider for openGui.

I already have that, but how do I open the container in my event?

what do I have to hand over to the method at "null"?

	@SubscribeEvent
	public static void PlayerInteract(PlayerInteractEvent.RightClickBlock event) {
		
		PlayerEntity player = event.getPlayer();
		BlockPos pos = event.getPos();
		World world = event.getWorld();
		BlockState state = world.getBlockState(pos);
		EnderChestInventory enderChestInventory = player.getInventoryEnderChest();
		
		if (state.getBlock() == Blocks.ENDER_CHEST) {
			
			if (!enderChestInventory.isEmpty()) {
				
				InventoryHelper.dropInventoryItems(world, pos, enderChestInventory);
				
			} else {
				
				if (player instanceof ServerPlayerEntity) {
					
					event.setCanceled(true);
					ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;
					NetworkHooks.openGui(serverPlayer, null, pos);
					
				}
				
			}
			
		}

	}

 

3 hours ago, diesieben07 said:

No... Not at all.

you say I should use a constructor, what must be in the constructor and what should the method "getCapability" return

Edited by Luis_ST
Link to comment
Share on other sites

12 minutes ago, Luis_ST said:

what do I have to hand over to the method at "null"?

A new instance of your INamedContainerProvider implementation.

 

13 minutes ago, Luis_ST said:

if (!enderChestInventory.isEmpty()) { InventoryHelper.dropInventoryItems(world, pos, enderChestInventory); }

Why do you do this?

 

13 minutes ago, Luis_ST said:

you say I should use a constructor, what must be in the constructor

This is a class that extends ItemStackHandler, just add the same constructors that that class has and call the super constructors. Your IDE should do this for you automatically.

 

14 minutes ago, Luis_ST said:

what should the method "getCapability" return

you need to check if the queried capability is yours and if so return the LazyOptional containing your capability instance. Otherwise return the empty LazyOptional.

Link to comment
Share on other sites

2 hours ago, diesieben07 said:

A new instance of your INamedContainerProvider implementation.

then like this:

					NetworkHooks.openGui(serverPlayer, new SimpleNamedContainerProvider((id, inventory, playerIn) -> {
						return new ModEnderChestContainer(id, inventory);
					}, ModEnderChestContainer.getContainerName()), pos);

 

2 hours ago, diesieben07 said:

Why do you do this?

This checks whether the player's Enderchest inventory is already in use, as the player may add the mod later. If this is the case,

the existing inventory will be dropped and the new one will be opened with the next click.

 

2 hours ago, diesieben07 said:

This is a class that extends ItemStackHandler, just add the same constructors that that class has and call the super constructors. Your IDE should do this for you automatically.

i dont get a constructor

so this is my complet class:

package net.luis.cave.init;

import java.util.concurrent.Callable;

import net.luis.cave.api.capability.IModItemHandler;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.INBT;
import net.minecraft.util.Direction;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.Capability.IStorage;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.common.util.NonNullSupplier;

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 {
		
		@Override
		public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
			
			return cap == CAPABILITY ? LazyOptional.of(() -> null) : LazyOptional.empty();
			
		}
		
	}
	
}

 

2 hours ago, diesieben07 said:

you need to check if the queried capability is yours and if so return the LazyOptional containing your capability instance. Otherwise return the empty LazyOptional.

what do I have to replace null with

Link to comment
Share on other sites

12 minutes ago, Luis_ST said:

then like this:

Sure.

 

12 minutes ago, Luis_ST said:

This checks whether the player's Enderchest inventory is already in use, as the player may add the mod later. If this is the case,

the existing inventory will be dropped and the new one will be opened with the next click.

Or... you could just make your inventory an extension of the ender chest inventory (just like how chests that are next to each other merge together). That way their existing inventory (if any) stays and if they uninstall the mod at least the "normal" part still stays.

Like I already suggested...

 

14 minutes ago, Luis_ST said:

i dont get a constructor

I have no idea what you mean by this.

 

14 minutes ago, Luis_ST said:

what do I have to replace null with

  1. Do not create a new LazyOptional every time.
  2. You have to replace it with the instance of your capability (i.e. your inventory).
Link to comment
Share on other sites

34 minutes ago, diesieben07 said:

Or... you could just make your inventory an extension of the ender chest inventory (just like how chests that are next to each other merge together). That way their existing inventory (if any) stays and if they uninstall the mod at least the "normal" part still stays.

Like I already suggested...

what do I have to change so that it works like a double chest inventory?

 

50 minutes ago, Luis_ST said:

This is a class that extends ItemStackHandler, just add the same constructors that that class has and call the super constructors. Your IDE should do this for you automatically.

36 minutes ago, diesieben07 said:

I have no idea what you mean by this.

which class did you mean?

 

39 minutes ago, diesieben07 said:

You have to replace it with the instance of your capability (i.e. your inventory).

like this? (this doesent work -> "Cannot make a static reference to the non-static method getInventory() from the type Container")

	public static class Provider implements ICapabilityProvider {
		
		@Override
		public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
			
			return cap == CAPABILITY ? LazyOptional.of(ModEnderChestContainer::getInventory) : LazyOptional.empty();
			
		}
		
	}

 

Link to comment
Share on other sites

7 minutes ago, Luis_ST said:

what do I have to change so that it works like a double chest inventory?

Use CombinedInvHandler to combine the two into one.

 

8 minutes ago, Luis_ST said:

which class did you mean?

What on earth are you talking about?

 

9 minutes ago, Luis_ST said:

ike this? (this doesent work -> "Cannot make a static reference to the non-static method getInventory() from the type Container")


	public static class Provider implements ICapabilityProvider {
		
		@Override
		public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
			
			return cap == CAPABILITY ? LazyOptional.of(ModEnderChestContainer::getInventory) : LazyOptional.empty();
			
		}
		
	}

 

This makes zero sense. Why would the container store the inventory. Your ICapabiltyProvider needs to store and save the capability.

Link to comment
Share on other sites

35 minutes ago, diesieben07 said:

Use CombinedInvHandler to combine the two into one.

where and when do I have to use this in the container class or when I interact with the block

 

31 minutes ago, diesieben07 said:

What on earth are you talking about?

i fixed it (it was a question about the error log)

 

32 minutes ago, diesieben07 said:

This makes zero sense. Why would the container store the inventory. Your ICapabiltyProvider needs to store and save the capability.

i don't understand what i have to set there, i tried a lot but every time i get an error

Link to comment
Share on other sites

14 minutes ago, Luis_ST said:

where and when do I have to use this in the container class or when I interact with the block

Neither. You return it from your capability provider.

 

15 minutes ago, Luis_ST said:

i don't understand what i have to set there, i tried a lot but every time i get an error

Your ICapabiltiyProvider needs a field that holds your capability instance (the inventory). It also needs a field that holds a LazyOptional to be returned from getCapability.

Link to comment
Share on other sites

12 hours ago, diesieben07 said:

Your ICapabiltiyProvider needs a field that holds your capability instance (the inventory). It also needs a field that holds a LazyOptional to be returned from getCapability.

like this?

	public static class Provider implements ICapabilityProvider {
		
		private static IModItemHandler inventory = new ModItemStackHandler();
		
		@Override
		public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
			
			return cap == CAPABILITY ? (LazyOptional<T>) LazyOptional.of(() -> inventory) : LazyOptional.empty();
			
		}
		
	}

 

Link to comment
Share on other sites

12 minutes ago, diesieben07 said:

Yes and yes.

this is now my ICapabilityProvider:

	public static class Provider implements ICapabilityProvider {
		
		private static IModItemHandler inventory = new ModItemStackHandler();
		private static LazyOptional<IModItemHandler> optional = LazyOptional.of(() -> inventory);
		
		@Override
		@SuppressWarnings("unchecked")
		public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
			
			return cap == CAPABILITY ? (LazyOptional<T>) optional : LazyOptional.empty();
			
		}
		
	}

 

and how do I add my extended enderchest inventory and that of the enderchest beacuse when i try this:

CombinedInvWrapper invWrapper = new CombinedInvWrapper(inventory);			

1. i got an error: "The constructor CombinedInvWrapper(IModItemHandler) is undefined"

2, how to get the ernderchest inventory?

Link to comment
Share on other sites

1 minute ago, Luis_ST said:

i got an error: "The constructor CombinedInvWrapper(IModItemHandler) is undefined"

Make IModItemHandler extends IItemHandlerModifiable instead.

 

2 minutes ago, Luis_ST said:

how to get the ernderchest inventory?

PlayerEntity#getInventoryEnderChest. And then use InvWrapper to wrap the IInventory into an IItemHandlerModifiable.

Link to comment
Share on other sites

1 hour ago, diesieben07 said:

PlayerEntity#getInventoryEnderChest

i know about this methode but what i mean how o get the InventoryEnderChest whitout a player or can i get beacuse i dont have a player inside the class:

or is there a way to get the player?

	public static class Provider implements ICapabilityProvider {
		
		private static IModItemHandler inventory = new ModItemStackHandler();
		private static LazyOptional<IModItemHandler> optional = LazyOptional.of(() -> inventory);
		
		@Override
		@SuppressWarnings("unchecked")
		public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
			
			CombinedInvWrapper invWrapper = new CombinedInvWrapper(inventory);			
			return cap == CAPABILITY ? (LazyOptional<T>) optional : LazyOptional.empty();
			
		}
		
	}

 

Link to comment
Share on other sites

How would you get the ender chest without a player? The ender chest inventory is tied to the player (they all have their own ender chest).

If you don't have the player in your provider, pass it in as a constructor parameter.

Also, you now create the CombinedInvWrapper, but you completely ignore it. You also only give it your internal inventory and you do it in getCapability instead of once in the constructor.

 

Also, it makes no sense for the inventory and LazyOptional to be static.

Link to comment
Share on other sites

47 minutes ago, diesieben07 said:

How would you get the ender chest without a player?

i add an constructor an remove the static of the LazyOptional so this is now my Provider:

but i can't combined the Inventories in this way.

	public static class Provider implements ICapabilityProvider {
		
		private static IModItemHandler inventory = new ModItemStackHandler();
		private LazyOptional<IModItemHandler> optional = LazyOptional.of(() -> inventory);
		
		public Provider(PlayerEntity player) {
			
			EnderChestInventory enderChestInventory = player.getInventoryEnderChest();
											/*Here is an Error*/
			CombinedInvWrapper invWrapper = new CombinedInvWrapper(inventory, enderChestInventory);
			IItemHandlerModifiable itemHandlerModifiable = invWrapper;
			
		}
		
		@Override
		@SuppressWarnings({ "unchecked", "unused" })
		public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
			
			return cap == CAPABILITY ? (LazyOptional<T>) optional : LazyOptional.empty();
			
		}
		
	}

 

Link to comment
Share on other sites

27 minutes ago, Luis_ST said:

an remove the static of the LazyOptional

Your inventory is still static. Do you know what static means? Apparently not, otherwise you would know that this makes zero sense.

 

27 minutes ago, Luis_ST said:

/*Here is an Error*/

3 hours ago, diesieben07 said:

PlayerEntity#getInventoryEnderChest. And then use InvWrapper to wrap the IInventory into an IItemHandlerModifiable.

 

Also: You still completely ignore the CombinedInvWrapper that you create.

Link to comment
Share on other sites

1 hour ago, diesieben07 said:

Do you know what static means?

I know what was meant by static i forgot it to remove

 

1 hour ago, diesieben07 said:

/*Here is an Error*/

i got an error: "The constructor CombinedInvWrapper(IModItemHandler, EnderChestInventory) is undefined".

 

1 hour ago, diesieben07 said:

Also: You still completely ignore the CombinedInvWrapper that you create.

1. What do I have to do with it or how do I create IItemHandlerModifiable
2. I have to add the container that I have created to my IModItemHandler.

because I have not yet passed anything to the IModItemHandler (it is empty) or I think that it is empty

Link to comment
Share on other sites

2 minutes ago, Luis_ST said:

i got an error: "The constructor CombinedInvWrapper(IModItemHandler, EnderChestInventory) is undefined".

Yes... I told you how to fix it right below. In a quote, because I already told you this previously.

 

2 minutes ago, Luis_ST said:

What do I have to do with it or how do I create IItemHandlerModifiable

You have to return it from getCapability... obviously. You want to use it in your container.

 

3 minutes ago, Luis_ST said:

I have to add the container that I have created to my IModItemHandler.

because I have not yet passed anything to the IModItemHandler (it is empty) or I think that it is empty

What?

Link to comment
Share on other sites

16 hours ago, diesieben07 said:

Yes... I told you how to fix it right below. In a quote, because I already told you this previously.

i dont understand when i only use my capility it work when i add the ender chest inventory i got this error

 

16 hours ago, diesieben07 said:

You have to return it from getCapability... obviously. You want to use it in your container.

then i have to creat a field?

I have to do the following:
1. Combination of inventories
2. Creat a IItemHandlerModifiable from the combination
3. Retrun the IItemHandlerModifiable in getCapability

Link to comment
Share on other sites

18 minutes ago, Luis_ST said:

i dont understand when i only use my capility it work when i add the ender chest inventory i got this error

... Which error?

 

19 minutes ago, Luis_ST said:

then i have to creat a field?

I have to do the following:
1. Combination of inventories
2. Creat a IItemHandlerModifiable from the combination
3. Retrun the IItemHandlerModifiable in getCapability

1. yes

2. yes

3. Create a LazyOptional for the inventory

4. Return the LazyOptional in getcapability.

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.