Ok, np. Here is my Item class, keys and locks are instances of it.
public class McfrCodedItem extends McfrItem {
public McfrCodedItem(String name, CreativeTabs tab) {
super(name, 1, tab);
setHasSubtypes(true);
}
@Override
public String getUnlocalizedName(ItemStack stack) {
return getUnlocalizedName() + "." + (stack.getMetadata() == 0 ? "blank" : "coded");
}
@Override
@SideOnly(Side.CLIENT)
public void getSubItems(Item itemIn, CreativeTabs tab, List<ItemStack> subItems) {
subItems.add(new ItemStack(itemIn, 1, 0)); // metadata = 0 --> Blank key/lock, unusable
subItems.add(new ItemStack(itemIn, 1, 1)); // metadata = 1 --> Coded key/lock, usable
}
public void setCode(EntityPlayer player, int code) {
ItemStack stack = new ItemStack(player.getHeldItemMainhand().getItem(), 1, 1); // replace item in hand with coded item
if (stack.hasCapability(KeyCode.Provider.KEY_CODE_CAP, null)) {
IKeyCode keyCode = stack.getCapability(KeyCode.Provider.KEY_CODE_CAP, null);
keyCode.set(code);
}
player.setHeldItem(EnumHand.MAIN_HAND, stack);
}
@SideOnly(Side.SERVER)
public Optional<Integer> getCode(EntityPlayer player) {
ItemStack stack = player.getHeldItemMainhand();
if (stack.getMetadata() == 1 && stack.hasCapability(KeyCode.Provider.KEY_CODE_CAP, null)) // Check if item is coded
return Optional.of(stack.getCapability(KeyCode.Provider.KEY_CODE_CAP, null).get()); //Optional.of(code) if coded
else
return Optional.empty(); //Optional.empty() if blank
}
}
The setCode(player, code) and getCode(player) methods are called from my Sponge plugin. I would like to sync client-item-capabilities with server-item-capabilities whenever setCode is called.
Here is my capability class. Provider and Storage are static classes inside it.
public class KeyCode implements IKeyCode {
private int code = 0;
@Override
public int get() {
return this.code;
}
@Override
public void set(int code) {
this.code = code;
}
public static class Storage implements IStorage<IKeyCode> {
@Override
public NBTBase writeNBT(Capability<IKeyCode> capability, IKeyCode instance, EnumFacing side) {
NBTTagCompound tag = new NBTTagCompound();
tag.setInteger("keyCode", instance.get());
return tag;
}
@Override
public void readNBT(Capability<IKeyCode> capability, IKeyCode instance, EnumFacing side, NBTBase nbt) {
NBTTagCompound tag = (NBTTagCompound) nbt;
instance.set(tag.getInteger("keyCode"));
}
}
public static class Provider implements ICapabilitySerializable<NBTBase> {
@CapabilityInject(IKeyCode.class)
public static final Capability<IKeyCode> KEY_CODE_CAP = null;
private IKeyCode instance = KEY_CODE_CAP.getDefaultInstance();
@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
return capability == KEY_CODE_CAP;
}
@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
return capability == KEY_CODE_CAP ? KEY_CODE_CAP.<T>cast(this.instance) : null;
}
@Override
public NBTBase serializeNBT() {
return KEY_CODE_CAP.getStorage().writeNBT(KEY_CODE_CAP, this.instance, null);
}
@Override
public void deserializeNBT(NBTBase nbt) {
KEY_CODE_CAP.getStorage().readNBT(KEY_CODE_CAP, this.instance, null, nbt);
}
}
}
Handling of the attachCapabilities event :
public class ItemEventsHandler {
public static final ResourceLocation KEY_CODE_CAP = new ResourceLocation(Constants.MOD_ID, "keyCode");
@SubscribeEvent
public void onAttachEntityCapabilities(AttachCapabilitiesEvent<Item> event) {
if (event.getObject() instanceof McfrCodedItem) {
event.addCapability(KEY_CODE_CAP, new KeyCode.Provider());
}
}
}
And finally, the line in my Init method, in main class :
CapabilityManager.INSTANCE.register(IKeyCode.class, new KeyCode.Storage(), KeyCode.class);
Hope this helps