Posted September 17, 20169 yr I am trying to attach a capability to the player allowing for there to be a point counter listed as destruction points. The capability system I created doesn't seem to work. I made an item called Point Reader that attempts to read the current points the player has, but it keeps returning that the player doesnt have the capability. Here is my code: IDestruction.java package pureunstable.test.tileentity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilityProvider; public interface IDestruction { double destructionPoints = 0; double getDestructionPoints(); void setDestructionPoints(double points); void addDestructionPoints(double points); void subDestructionPoints(double points); } DefaultImpl.java package pureunstable.test.tileentity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.util.INBTSerializable; import pureunstable.test.TestMod; import pureunstable.test.tileentity.IDestruction; /* * This class is the implementation of IDestruction */ public class DefaultImpl implements IDestruction{ private static double points = 0; public DefaultImpl() { this.points = this.getDestructionPoints(); } public DefaultImpl(long points) { this.points = points; } @Override public double getDestructionPoints() { return points; } @Override public void setDestructionPoints(double points) { this.points = points; } @Override public void addDestructionPoints(double points) { if(this.points != getDestructionPoints()) { this.points = getDestructionPoints(); System.out.println("Slight malfunction..."); } this.points += points; } @Override public void subDestructionPoints(double points) { if(this.points != getDestructionPoints()) { this.points = getDestructionPoints(); System.out.println("Slight malfunction..."); } this.points -= points; } } Storage.java package pureunstable.test.tileentity; import net.minecraft.nbt.NBTBase; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.Capability.IStorage; public class Storage implements IStorage<IDestruction> { public static final Storage destructionPoints = new Storage(); @Override public NBTBase writeNBT(Capability<IDestruction> capability, IDestruction instance, EnumFacing side) { NBTTagCompound nbt = new NBTTagCompound(); nbt.setDouble("dest", instance.getDestructionPoints()); System.out.println("Writing dest points: " + instance.getDestructionPoints()); return nbt; } @Override public void readNBT(Capability<IDestruction> capability, IDestruction instance, EnumFacing side, NBTBase nbt) { instance.setDestructionPoints(((NBTTagCompound)nbt).getDouble("dest")); System.out.println("Reading destruction points: " + ((NBTTagCompound)nbt).getDouble("dest")); } } EventHandlerCommon.java package pureunstable.test; import net.minecraft.nbt.NBTBase.NBTPrimitive; import net.minecraft.util.EnumFacing; import net.minecraft.util.ResourceLocation; import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.common.capabilities.ICapabilitySerializable; import net.minecraftforge.event.AttachCapabilitiesEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import pureunstable.test.TestMod; import pureunstable.test.tileentity.IDestruction; public class EventHandlerCommon { @SubscribeEvent public void onEntityConstruct(AttachCapabilitiesEvent.Entity evt) { evt.addCapability(new ResourceLocation(Reference.MODID, "IDestruction"), new ICapabilitySerializable<NBTPrimitive>() { IDestruction inst = TestMod.DESTRUCTION_CAP.getDefaultInstance(); @Override public boolean hasCapability(Capability<?> capability, EnumFacing facing) { return capability == TestMod.DESTRUCTION_CAP; } @Override public <T> T getCapability(Capability<T> capability, EnumFacing facing) { return capability == TestMod.DESTRUCTION_CAP ? TestMod.DESTRUCTION_CAP.<T>cast(inst) : null; } @Override public NBTPrimitive serializeNBT() { return (NBTPrimitive)TestMod.DESTRUCTION_CAP.getStorage().writeNBT(TestMod.DESTRUCTION_CAP, inst, null); } @Override public void deserializeNBT(NBTPrimitive nbt) { TestMod.DESTRUCTION_CAP.getStorage().readNBT(TestMod.DESTRUCTION_CAP, inst, null, nbt); } }); } } CommonProxy.java package pureunstable.test.proxy; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.capabilities.CapabilityManager; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import pureunstable.test.tileentity.IDestruction; import pureunstable.test.EventHandlerCommon; import pureunstable.test.tileentity.DefaultImpl; import pureunstable.test.tileentity.Storage; public class CommonProxy { public void registerRenders() { } @Mod.EventHandler public void preInit(FMLPreInitializationEvent event){ CapabilityManager.INSTANCE.register(IDestruction.class, new Storage(), DefaultImpl.class); MinecraftForge.EVENT_BUS.register(new EventHandlerCommon()); } } And I have this in my main mod class: @CapabilityInject(IDestruction.class) public static final Capability<IDestruction> DESTRUCTION_CAP = null;
September 17, 20169 yr public static final Capability<IDestruction> DESTRUCTION_CAP = null; Do you ever make this field not-null? Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
September 17, 20169 yr Gotcha. I haven't quite figured out all the things with capabilities yet. Definitely haven't done any based on entityConstructing (that is, I've done a custom Cap on a TE of my own design and used the ItemHandler one). Apparently I'm a complete and utter jerk and come to this forum just like to make fun of people, be confrontational, and make your personal life miserable. If you think this is the case, JUST REPORT ME. Otherwise you're just going to get reported when you reply to my posts and point it out, because odds are, I was trying to be nice. Exception: If you do not understand Java, I WILL NOT HELP YOU and your thread will get locked. DO NOT PM ME WITH PROBLEMS. No help will be given.
September 18, 20169 yr I'm not entirely sure why it's not working, but I did notice some errors: The IDestruction#destructionPoints field doesn't need to exist. The DefaultImpl.points field shouldn't be static. Your IStorage expects to work with NBTTagCompound s, but your ICapabilitySerializable uses NBTPrimitive . 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.
September 18, 20169 yr Author I just finished fixing those errors. Thank you for pointing them out. I moved my @CapabilityInject to my EventHandlerCommon.java to see if that may solve anything, but it does not seem like it has. The way I am attempting to check if my player has the capability is by right clicking with an item with the following code: package pureunstable.test.items; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.ActionResult; import net.minecraft.util.EnumHand; import net.minecraft.util.text.TextComponentString; import net.minecraft.world.World; import pureunstable.test.EventHandlerCommon; import pureunstable.test.TestMod; import pureunstable.test.tileentity.IDestruction; public class ItemPointReader extends Item { @Override public ActionResult<ItemStack> onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, EnumHand hand) { if(!worldIn.isRemote) { playerIn.addChatComponentMessage(new TextComponentString(playerIn.getCapability(EventHandlerCommon.DESTRUCTION_CAP, null).getDestructionPoints() + " points")); } return super.onItemRightClick(itemStackIn, worldIn, playerIn, hand); } } The way I see it, if the player has the DESTRUCTION_CAP capability, then there will be a chat message that shows the points, which is starting at 0 points. I'm instead getting a null pointer exception whenever I right click with this item. Is this a bad way to go about checking if I have the capability?
September 18, 20169 yr The way I am attempting to check if my player has the capability is by right clicking with an item with the following code: package pureunstable.test.items; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.ActionResult; import net.minecraft.util.EnumHand; import net.minecraft.util.text.TextComponentString; import net.minecraft.world.World; import pureunstable.test.EventHandlerCommon; import pureunstable.test.TestMod; import pureunstable.test.tileentity.IDestruction; public class ItemPointReader extends Item { @Override public ActionResult<ItemStack> onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, EnumHand hand) { if(!worldIn.isRemote) { playerIn.addChatComponentMessage(new TextComponentString(playerIn.getCapability(EventHandlerCommon.DESTRUCTION_CAP, null).getDestructionPoints() + " points")); } return super.onItemRightClick(itemStackIn, worldIn, playerIn, hand); } } The way I see it, if the player has the DESTRUCTION_CAP capability, then there will be a chat message that shows the points, which is starting at 0 points. I'm instead getting a null pointer exception whenever I right click with this item. Is this a bad way to go about checking if I have the capability? Yes. If the player does not have the capability, getCapability() will return null; since you call a method on the return value, if the player does not have the capability an NPE is thrown. Use hasCapability() to check if the player has a capability.
September 18, 20169 yr Author I originally had a check in an if statement to see if the player had the capability but it was coming back as false, so i just did a shortcut through the code last night before I went to bed. I just took a look through my code again and realized I had my client proxy class referenced within my main mod class, but not the common proxy class. After fixing that, my capability now works. Thanks everyone for helping me work through it!
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.