Jump to content

[1.10.2] I have a class that is an inventory, how do I implement its capability?


Starless

Recommended Posts

I have an Item that implements

IItemHandler, IItemHandlerModifiable, INBTSerializable<NBTTagList>

 

It's not a TileEntity or an actual object in the game. It's an inventory that a TileEntity could use as its internal inventory. Should I implement a capability for it? how?

 

I'm still completely lost in this capability thing (even after reading the documentation), so, please, if possible, explain it to me like I'm retarded.

Link to comment
Share on other sites

There is capability for Item which is saved on its ItemStack. See Item#initCapabilities.

I. Stellarium for Minecraft: Configurable Universe for Minecraft! (WIP)

II. Stellar Sky, Better Star Rendering&Sky Utility mod, had separated from Stellarium.

Link to comment
Share on other sites

You dont implement any of those on the Item itself.

 

My object is like an abstraction of an inventory, much similar to ItemStackHandler, but it adds fuctionality like it always knows where to find an Item stack of a certain type, and etc. It implements an interface I created called IAccountableInventory. This object will play the role of the internal invetory for every Tile Entity that requires the extra functionalities it adds, The tile entity will expose this inventory by implementing the Interface and delegating all the method invocations to the underlying object. So should I create a capability to mirror IAcountableInventory? Who should expose the capability: the object that implements it? the Entity/TileEntity/ItemStack wrapping the object? And how would that be done?

Link to comment
Share on other sites

Just make normal capability where IAcountableInventory will be your cap's interface.

Assign it to TileEntity via @SubscribeEvent to AttachCapabilitiesEvent.TileEntity.

 

Accessing of inventory will happen via capabilities system and be possible for anyone asking.

 

EDIT

 

I kinda don't see your design because 1st you say:

I have an Item that implements

IItemHandler, IItemHandlerModifiable, INBTSerializable<NBTTagList>

Then you mention TileEntities - how does that have anything to do with 1st mentioned Item?

Then you go ahead saying it is not a TE, but then you say it is an inventory that belongs to TE.

In next post you again say it IS an inventory of TE, so what is it?

 

My answer before edit is regarding assigning capability to TE. In your case - inventory is the capability.

Might be of help:

https://github.com/MinecraftForge/MinecraftForge/blob/1.9/src/test/java/net/minecraftforge/test/NoBedSleepingTest.java

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

I'm sorry, I thought I edited the word "Item" out of the original post. It's just a class. It's an abstraction of an inventory, and plays a similar role to ItemStackHandler, I think.

 

If you want to have an inventory with the extra functions of an IAccountableInventory you can simply put an object of my class that implements it and expose the methods by delegating them. Like This:

 

public class AGameObject extends [TileEntity or Entity, or whatever] implements IAccountableInventory
{
    IAccountableInventory interntalInvetory = new InventoryMapped()

    @Override
    public ItemStack implementationOfInterfaceMethod()
    {
        return interntalInvetory.implementationOfInterfaceMethod()
    }
}

Link to comment
Share on other sites

Unless you totally misunderstood the point of caps - my argument stands.

 

You can use Attach event to attach capability to some object (TE, Entity, ItemStack) and then get instance of your interface using capability system (or return null if such wasn't attached). Lookup link I gave you. And maybe look into other open sources.

 

EDIT:

 

Note: What will be actually done by methods inside your interface will be decided by implementor!

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

Ok...

 

Is this necessary for TileEntities or can I just

 

worldIn.getTileEntityAt(pos) instanceof IAccountableInventory

 

What I mean is, is this the de facto pattern for everything? Will other mods look for Capabilities instead of interfaces? or is the capability system more like a replacement for IEEP? I really mean it when I say I'm completely lost. I couldn't totally misunderstand the point of Capabilities, because I have not formed an understanding of them yet.

Link to comment
Share on other sites

1st lets say there is a difference between exposing things via capability and implementing interface directly onto object.

 

Sure you can implement interface directly onto TE and sure - it is 100% valid thing to do. Modding is still Java and interfaces are like core of well designed stuff. So yeah - if you don't care about OTHERS - go ahead and apply your inventory directly on TE.

 

Now - let's look at above approach from other perspectives:

 

* Can someone else go ahead and make this?

worldIn.getTileEntityAt(pos) instanceof IAccountableInventory

SURE - they can, why not (considering they are dependent to your mod and have it as lib obviously).

Well then - can they do something else than blindlessly calling interface's methods? Woops! They can't!

 

* Can you implement interface on ALREADY defined class (vanilla or other mod's)? Hell naw! Unless you would do some ASM magic you are lost like baby in the woods.

 

And finally - then how one can achieve above without ASM or tons on API hooks from milion of sources and shit?

BOOM! Capabilities!

 

So now the essence:

 

1st of all - Capability can be attached to any objects - your own, vanilla, other mod's or even goddamn who-knows what (we are talking shit out of this world)! Well, that is a big plus - ain't it?

 

 

whats-the-best-thing-about-living-in-switzerland-well-the-flag-is-a-big-plus.jpg

 

 

Feeling pluses yet?

 

Ok, well, now to more important thing:

 

Capability is NOT something predefined. You only make some interface and let OTHERS implement it. Wait what?

Well yeah - what you actually do with capability is declare that someone can attach instance of your interface to some object. Feeling it yet? So basically you provide skeleton for some "thing" (in your case inventory) assigned to object and someone else (or you for that matter) implements that shit and actually assigns instance of that interface to object.

Now where is the magic? Well - anyone can do anything - and even better - while they do what they want to do - you can still KNOW when they do it.

 

AND THY LIGHT SHONE FROMTH THY SKIES ONTO MINDTHS OF PEASANTS ON WAST FIELDS OF BANETH! (what the fuck am I writing?!)

P.S: I know this is totally not old english!

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

I believe now I have a much better understanding of it. So I can basically attach capabilities to whatever I want, this is what they are good for. Under normal circumstances we stick to Java, unless it is something that feels like it is "attachable" to anything.

 

So if I had an interface like this:

 

public interface IFireExtinguisher
{
    //looks around in a 5x5x5 cube around it for fire and extiguishes all it finds.
    public void extinguish();
}

 

That could be attached to an Item or a TileEntity or an EntityLiving, for example, in an ItemStack it could be the onRightClick effect. On a Block it could be invoked during a the random tick, and so on. Is this correct?

 

Edit:

 

How would I create the Capability for that?

Link to comment
Share on other sites

That could be attached to an Item or a TileEntity or an EntityLiving, for example, in an ItemStack it could be the onRightClick effect. On a Block it could be invoked during a the random tick, and so on. Is this correct?

Yes.

 

 

How would I create the Capability for that?

 

Look at the capability examples in Forge itself (

CapabilityItemHandler

,

CapabilityFluidHandler

,

CapabilityAnimation

), the Forge test mod that Ernio linked earlier or my own mod (API, implementation).

 

You can also read the official documentation here.

Please don't PM me to ask for help. Asking your question in a public thread preserves it for people who are having the same problem in the future.

Link to comment
Share on other sites

Official documentation seems to be outdated. The mod that Ernio linked is poorly documented (as in not a single comment in the entire file, let alone a javadoc comment). I will check what you linked.

 

EDIT: I still cannot make sense of this. Capabilities are the most unintuitive and esoteric programming constructs I've ever came across in my life. I know "what" they are, but the code just looks like random memory dump turned to Java. Nevermind this. I can live without it. Until someone writes a tutorial about it, I'm staying as far away from this thing as possible.

Link to comment
Share on other sites

Wow this is fucking retarded, We have several example mods in Forge.

We have capabilities implemented in all the vanilla objects.

The code is straight forward.

The ENTIRE FREAKING POINT of this is that TEs/Items/Entites DO NOT HAVE TO IMPLEMENT THE INTERFACE ON ITSELF.

Which is the entire point because it prevents having hard references to the classes.

 

Now lets make this clear for you.

Your example:

public class AGameObject extends [TileEntity or Entity, or whatever] implements IAccountableInventory
{
    IAccountableInventory interntalInvetory = new InventoryMapped()

    @Override
    public ItemStack implementationOfInterfaceMethod()
    {
        return interntalInvetory.implementationOfInterfaceMethod()
    }
}

Want to know how to do this?

public class AGameObject implements ICapabilityProvider
{
    IAccountableInventory interntalInvetory; //Doing this in the static constructor is BAD because it makes a HARD reference to the class which will crash if you dont have the dependancy = new InventoryMapped()

  getCapability(cap){
    if (cap == YOUR_SUPER_AWESOME_CAP_OBJECT)
       return internalInventory;
  }
}

 

Its fairly straight forward, the 'documented' example of it is here: https://github.com/MinecraftForge/MinecraftForge/blob/1.10.x/src/test/java/net/minecraftforge/test/TestCapabilityMod.java

Here is how chests work:

https://github.com/MinecraftForge/MinecraftForge/blob/1.10.x/patches/minecraft/net/minecraft/tileentity/TileEntityChest.java.patch

 

Furnaces, with multiple sides: https://github.com/MinecraftForge/MinecraftForge/blob/1.10.x/patches/minecraft/net/minecraft/tileentity/TileEntityFurnace.java.patch#L83

 

See how its a simple implementation of getCapability and returns an instance of the interface that capability specifies.

How are you confused about this?

 

I do Forge for free, however the servers to run it arn't free, so anything is appreciated.
Consider supporting the team on Patreon

Link to comment
Share on other sites

Wow this is fucking retarded, We have several example mods in Forge.

We have capabilities implemented in all the vanilla objects.

The code is straight forward.

The ENTIRE FREAKING POINT of this is that TEs/Items/Entites DO NOT HAVE TO IMPLEMENT THE INTERFACE ON ITSELF.

Which is the entire point because it prevents having hard references to the classes.

 

Now lets make this clear for you.

Your example:

public class AGameObject extends [TileEntity or Entity, or whatever] implements IAccountableInventory
{
    IAccountableInventory interntalInvetory = new InventoryMapped()

    @Override
    public ItemStack implementationOfInterfaceMethod()
    {
        return interntalInvetory.implementationOfInterfaceMethod()
    }
}

Want to know how to do this?

public class AGameObject implements ICapabilityProvider
{
    IAccountableInventory interntalInvetory; //Doing this in the static constructor is BAD because it makes a HARD reference to the class which will crash if you dont have the dependancy = new InventoryMapped()

  getCapability(cap){
    if (cap == YOUR_SUPER_AWESOME_CAP_OBJECT)
       return internalInventory;
  }
}

 

Its fairly straight forward, the 'documented' example of it is here: https://github.com/MinecraftForge/MinecraftForge/blob/1.10.x/src/test/java/net/minecraftforge/test/TestCapabilityMod.java

Here is how chests work:

https://github.com/MinecraftForge/MinecraftForge/blob/1.10.x/patches/minecraft/net/minecraft/tileentity/TileEntityChest.java.patch

 

Furnaces, with multiple sides: https://github.com/MinecraftForge/MinecraftForge/blob/1.10.x/patches/minecraft/net/minecraft/tileentity/TileEntityFurnace.java.patch#L83

 

See how its a simple implementation of getCapability and returns an instance of the interface that capability specifies.

How are you confused about this?

 

because I think it has such an awful design it hurts to look at it. Compared to everything else, capabilities are an aberration that fit nowhere in the framework in terms of design

Link to comment
Share on other sites

I tried to keep it fun and shit, but hell...

because I think it has such an awful design it hurts to look at it. Compared to everything else, capabilities are an aberration that fit nowhere in the framework in terms of design

...we are not friends anymore :(  (Haha! Jokes on you, we were never friends! I don't have friends...)

 

But seriously - Forge API is pretty advanced tool and if you expect to gain more compatibility/power with less not-your-everyday-simple-java-hello-word-programs then you are in wrong place. Besides - this shit it pretty simple compared to what forge does behind the scenes.

 

You got more explanations than I could wish for and you know how I (mostly) learned how to use caps properly? By looking at damn source!

 

I need to get some sleep.

1.7.10 is no longer supported by forge, you are on your own.

Link to comment
Share on other sites

because I think it has such an awful design it hurts to look at it. Compared to everything else, capabilities are an aberration that fit nowhere in the framework in terms of design
So you are to lazy/stupid to put in the effort to understand a simple thing and so are going to argue about it. Ya no...

I do Forge for free, however the servers to run it arn't free, so anything is appreciated.
Consider supporting the team on Patreon

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • Here's a simple example to solve this particular issue: public class ModArmorMaterials { public static final DeferredRegister<ArmorMaterial> ARMORS = DeferredRegister.create(Registries.ARMOR_MATERIAL, MyModName.MOD_ID); public static final RegistryObject<ArmorMaterial> COPPER = registerArmor("copper", Util.make(new EnumMap<>(ArmorItem.Type.class), enumMap -> { enumMap.put(ArmorItem.Type.BOOTS, 1); enumMap.put(ArmorItem.Type.LEGGINGS, 4); enumMap.put(ArmorItem.Type.CHESTPLATE, 5); enumMap.put(ArmorItem.Type.HELMET, 2); enumMap.put(ArmorItem.Type.BODY, 4); }), 12, SoundEvents.ARMOR_EQUIP_IRON, 0.0F, 0.0F, () -> Ingredient.of(Items.COPPER_INGOT)); private static RegistryObject<ArmorMaterial> registerArmor(String pGroup, EnumMap<ArmorItem.Type, Integer> pEnumMap, int pEnchantmentValue, Holder<SoundEvent> pEquipSound, float pToughness, float pKnockbackResistance, Supplier<Ingredient> pRepairIngredient) { List<ArmorMaterial.Layer> pLayerList = List.of(new ArmorMaterial.Layer(new ResourceLocation(pGroup))); return registerArmor(pGroup, pEnumMap, pEnchantmentValue, pEquipSound, pToughness, pKnockbackResistance, pRepairIngredient, pLayerList); } private static RegistryObject<ArmorMaterial> registerArmor( String pGroup, EnumMap<ArmorItem.Type, Integer> pEnumMap, int pEnchantmentValue, Holder<SoundEvent> pEquipSound, float pToughness, float pKnockbackResistance, Supplier<Ingredient> pRepairIngredient, List<ArmorMaterial.Layer> pLayerList) { return ARMORS.register(pGroup, () -> new ArmorMaterial(pEnumMap, pEnchantmentValue, pEquipSound, pRepairIngredient, pLayerList, pToughness, pKnockbackResistance)); } public static void register(IEventBus eventBus) { ARMORS.register(eventBus); } } Essentially, the TierSortingRegistry has been removed and so you now need to set up your own DeferredRegister. Please see the minecraftforge GitHub for more information; I found this solution through their issues (https://github.com/MinecraftForge/MinecraftForge/issues/9961)
    • How did I even leave that in there? I’ll try it in a bit, that very well could be it.
    • Greetings, I met a problem with my Forge server (47.2.0-1.20.1) that I can't join with the following line. (singleplayer world working fine) [net.minecraft.server.network.ServerGamePacketListenerImpl/]: Sharyna lost connection: Internal Exception: io.netty.handler.codec.EncoderException: java.lang.NullPointerException: Cannot invoke "net.minecraft.resources.ResourceLocation.toString()" because "p_130086_" is null   At first it was errored with packet size error, but I fixed that with the Connectivity mod, however, after that this popped up and can't find the source of it. Since the logs are big, I couldn't upload on paste.gg or other site ... so here it is (if the files are deleted, please notice me and I'll upload again. Debug and Latest log
    • Дерево тис
  • Topics

×
×
  • Create New...

Important Information

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