I want to attach a Capability to the player in order to store some extended information, but I get into trouble, my code is as follows:
(My English is poor....if my expression is strange I'm sorry )
CapabilityPlayerData:
public class CapabilityPlayerData{
@CapabilityInject(ICapabilityPlayerData.class)
public static final Capability<ICapabilityPlayerData> INSTANCE = null;
public interface ICapabilityPlayerData {
public String getType();
public void setType(String type);
public int getLevel();
public void setLevel(int lv);
public String getProfession();
public void setProfession(String profession);
}
}
CapabilityPlayerDataDefault:
public class CapabilityPlayerDataDefault implements ICapabilityPlayerData{
private String type = "Human"
private String profession = "none"
private int level=0;
@Override
public String getType() {
return type;
}
@Override
public void setType(String type) {
this.type = type;
}
@Override
public int getLevel() {
return level;
}
@Override
public void setLevel(int lv) {
this.level = lv;
}
@Override
public String getProfession() {
return profession;
}
@Override
public void setProfession(String profession) {
this.profession = profession;
}
}
CapabilityPlayerDataHandler:
public class CapabilityPlayerDataHandler implements IStorage<ICapabilityPlayerData>{
public final static CapabilityPlayerDataHandler capabilityPlayerDataHandler = new CapabilityPlayerDataHandler();
public CapabilityPlayerDataHandler(){}
@Override
public NBTBase writeNBT(Capability<ICapabilityPlayerData> capability, ICapabilityPlayerData instance,EnumFacing side) {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("level", instance.getLevel());
nbt.setString("profession", instance.getProfession());
nbt.setString("type", instance.getType());
return nbt;
}
@Override
public void readNBT(Capability<ICapabilityPlayerData> capability, ICapabilityPlayerData instance, EnumFacing side,NBTBase nbt) {
if (((NBTTagCompound) nbt).hasKey("type", )
instance.setType(((NBTTagCompound) nbt).getString("type"));
if (((NBTTagCompound) nbt).hasKey("profession", )
instance.setProfession(((NBTTagCompound) nbt).getString("profession"));
if (((NBTTagCompound) nbt).hasKey("level", 3))
instance.setLevel(((NBTTagCompound) nbt).getInteger("level"));
}
}
CapabilityPlayerDataProvider:
public class CapabilityPlayerDataProvider implements ICapabilitySerializable<NBTTagCompound>{
private Entity player;
private ICapabilityPlayerData playerCapability = CapabilityPlayerData.INSTANCE.getDefaultInstance();
public CapabilityPlayerDataProvider(Entity player){
this.player = player;
}
@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
return CapabilityPlayerData.INSTANCE != null && capability == CapabilityPlayerData.INSTANCE;
}
@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
if (CapabilityPlayerData.INSTANCE != null && capability == CapabilityPlayerData.INSTANCE)
return (T) new CapabilityPlayerDataDefault();
return null;
}
@Override
public NBTTagCompound serializeNBT() {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setTag("playerData", CapabilityPlayerData.INSTANCE.getStorage().writeNBT(CapabilityPlayerData.INSTANCE, playerCapability, null));
return nbt;
}
@Override
public void deserializeNBT(NBTTagCompound nbt) {
NBTBase list = nbt.getTag("playerData");
CapabilityPlayerData.INSTANCE.getStorage().readNBT(CapabilityPlayerData.INSTANCE, playerCapability, null, list);
}
}
CapabilityPlayerDataProvider
public class CapabilityPlayerDataProvider implements ICapabilitySerializable<NBTTagCompound>{
private Entity player;
private ICapabilityPlayerData playerCapability = CapabilityPlayerData.INSTANCE.getDefaultInstance();
public CapabilityPlayerDataProvider(Entity player){
this.player = player;
}
@Override
public boolean hasCapability(Capability<?> capability, EnumFacing facing) {
return CapabilityPlayerData.INSTANCE != null && capability == CapabilityPlayerData.INSTANCE;
}
@Override
public <T> T getCapability(Capability<T> capability, EnumFacing facing) {
if (CapabilityPlayerData.INSTANCE != null && capability == CapabilityPlayerData.INSTANCE)
return (T) new CapabilityPlayerDataDefault();
return null;
}
@Override
public NBTTagCompound serializeNBT() {
NBTTagCompound nbt = new NBTTagCompound();
nbt.setTag("playerData", CapabilityPlayerData.INSTANCE.getStorage().writeNBT(CapabilityPlayerData.INSTANCE, playerCapability, null));
return nbt;
}
@Override
public void deserializeNBT(NBTTagCompound nbt) {
NBTBase list = nbt.getTag("playerData");
CapabilityPlayerData.INSTANCE.getStorage().readNBT(CapabilityPlayerData.INSTANCE, playerCapability, null, list);
}
}
CapabilityPlayerDataEvent:
public class CapabilityPlayerDataEvent {
@SubscribeEvent
public void onTELoad(AttachCapabilitiesEvent.Entity event)
{
if(!event.getEntity().hasCapability(CapabilityPlayerData.INSTANCE, null) && event.getEntity() instanceof EntityPlayer)
event.addCapability(new ResourceLocation(SOR.MODID+".PlayerData"), new CapabilityPlayerDataProvider(event.getEntity()));
}
}
I got two Items for using the Capability . The UserBook is used to show the player's information , and the ChangeLevel is used to change the Level.
UserBook:
@Override
public ActionResult<ItemStack> onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, EnumHand hand)
{
if(!worldIn.isRemote){
if(playerIn.hasCapability(CapabilityPlayerData.INSTANCE, playerIn.getHorizontalFacing())){
ICapabilityPlayerData inv = playerIn.getCapability(CapabilityPlayerData.INSTANCE, null);
playerIn.addChatMessage(new TextComponentTranslation("sor.chat.level.name",inv.getLevel()));
playerIn.addChatMessage(new TextComponentTranslation("sor.chat.profession.name",new TextComponentTranslation("sor.profession."+inv.getProfession()+".name")));
playerIn.addChatMessage(new TextComponentTranslation("sor.chat.type.name",new TextComponentTranslation("sor.type."+inv.getType()+".name")));
}
}
return new ActionResult(EnumActionResult.SUCCESS, itemStackIn);
}
ChangeLevel:
@Override
public ActionResult<ItemStack> onItemRightClick(ItemStack itemStackIn, World worldIn, EntityPlayer playerIn, EnumHand hand)
{
if(!worldIn.isRemote){
if(playerIn.hasCapability(CapabilityPlayerData.INSTANCE, playerIn.getHorizontalFacing())){
ICapabilityPlayerData inv = playerIn.getCapability(CapabilityPlayerData.INSTANCE, playerIn.getHorizontalFacing());
int level = inv.getLevel();
inv.setLevel(level+1);
playerIn.addChatMessage(new TextComponentTranslation("sor.chat.change.level.name",inv.getLevel()));
}
}
return new ActionResult(EnumActionResult.SUCCESS, itemStackIn);
}
I rightclick the UserBook and it said the Player's Level is 1 , and I rightclick the ChangeLevel it said the Level has been changed to 2, but then I rightclick the UserBook again it still said the Level is 1......so what's wrong with it? Thanks