endershadow Posted June 17, 2013 Share Posted June 17, 2013 I've tried to add NBT data to the player, but to no avail. I have a method that should work (I think) but it doesn't here's my code. https://github.com/code-lyoko-modding/CodeLyokoMod/blob/master/matt/lyoko/network/PlayerTracker.java and here is what I tried before what is currently on GitHub. player.getEntityData().newTag((byte)1, "lifePoints"); player.getEntityData().setByte("lifePoints", (byte)100); I also tried player.getEntityData().newTag((byte)1, "lifePoints"); player.getEntityData().setByte("lifePoints", (byte)100); player.writeToNBT(player.getEntityData()); any help would be appreciated. Quote Link to comment Share on other sites More sharing options...
atrain99 Posted June 17, 2013 Share Posted June 17, 2013 If you can add a listener to when the player is saved, you can use reflection to extract the NBT tag, and add to it. Same for loading the player. Or, if the field is not a new thing on the player, just use reflection to set it if it is private, or just set it if it has a setter or is public. Quote So, what would happen if I did push that shiny red button over there? ... Really? ... Can I try it? ... Damn. Link to comment Share on other sites More sharing options...
endershadow Posted June 17, 2013 Author Share Posted June 17, 2013 what kind of listener? this is done when the player logs in. Quote Link to comment Share on other sites More sharing options...
ObsequiousNewt Posted June 17, 2013 Share Posted June 17, 2013 what kind of listener? this is done when the player logs in. EntityJoinWorldEvent, I think... but I also think that you rather want IAdditionalEntityData. Quote BEWARE OF GOD --- Co-author of Pentachoron Labs' SBFP Tech. Link to comment Share on other sites More sharing options...
endershadow Posted June 17, 2013 Author Share Posted June 17, 2013 How would i go about registering IAdditionalEntityData? Quote Link to comment Share on other sites More sharing options...
ObsequiousNewt Posted June 17, 2013 Share Posted June 17, 2013 How would i go about registering IAdditionalEntityData? Um, someone had this same problem... half a minute... ...oh wait, they never solved it. Oh wait, that was you. Um, the code you have should work. newTag() is a static method that creates a new tag, and you don't need it. But setByte() should work just fine. Does it not save? If you set it and then read it, does it work? Quote BEWARE OF GOD --- Co-author of Pentachoron Labs' SBFP Tech. Link to comment Share on other sites More sharing options...
WorldsEnder Posted June 17, 2013 Share Posted June 17, 2013 If you want just additional data to your player I would suppose to write an IPlayerTracker or add something if you have one yet. This is a convenient method to get the method onPlayerLogin(EntityPlayer player) called every time a player logs in. Then you get the NBTString (getEntityData()) and read from there. You store your read values in some sort of static Helper-Class (e.g. class HelperHelper implements IPlayerTracker{ public static final instance = new HelperHelper(); private static HashMap<EntityPlayer, a_class_that_can_store_your_values> playerData = new HashMap<EntityPlayer, a_class_that_can_store_your_values>(); public static a_class_that_can_store_your_values getValuesFor(EntityPlayer player) { return playerData.get(player); } @Override public void onPlayerLogin(EntityPlayer player) { if(player.getEntityData().hasKey("what_so_ever") { playerData.put(player, readFromNBTStream(player.getEntityData().getCompoundTag("what_so_ever"); }else{ playerData.put(player, new a_class_that_can_store_your_values()); } @Override public void onPlayerLogout(EntityPlayer player) { NBTTagCompound toWriteTo = new NBTTagCompound(); playerData.get(player).writeToNBTTagCompound(toWriteTo); player.getEntityData().setCompoundTag("what_so_ever", toWriteTo); } private a_class_that_can_store_your_values readFromNBTStream(NBTTagCompound playerCompound) { a_class_that_can_store_your_values toReturn = new a_class_that_can_store_your_values(); toReturn.readFromNBTTagCompound(playerCompound); return toReturn; } ... include additional methods from IPlayerTracker } Please note that this is only what I would suppose, maybe you have to edit it slightly. Please note: your a_class_that_can_store_your_values has to feature the two public methods readFromNBTTagCompound(NBTTagCompound someName) and writeToNBTTagCompound(NBTTagCompound someOtherName). I hope you know how to read and write from/to NBTTagCompounds correctly. Maybe you also want to edit the method onPlayerLogin slightly cause it will always give you the default values of the NBTTagCompounds. You can check if the player has data already by calling player.getEntityData().hasKey("what_so_ever") and deciding what default values you put in. Please note.3: you have to register your IPlayerTracker in your @Mod file preferably by typing GameRegistry.registerPlayerTracker(HelperHelper.instance); Please note.4: also, all text with "_" has to be replaced with any name you choose as far as it is the same you use for the same placeholder. Please note.5: if I have any typos please be kind and don't mention them if they are not really, really, really, really, really stuhpid Quote Link to comment Share on other sites More sharing options...
endershadow Posted June 18, 2013 Author Share Posted June 18, 2013 I'm sorry WorldsEnder, I can't figure out what your code is telling me to do. It's so confusing and error ridden. How would i go about registering IAdditionalEntityData? Um, someone had this same problem... half a minute... ...oh wait, they never solved it. Oh wait, that was you. Um, the code you have should work. newTag() is a static method that creates a new tag, and you don't need it. But setByte() should work just fine. Does it not save? If you set it and then read it, does it work? I've tried that, but it doesn't work. Quote Link to comment Share on other sites More sharing options...
Mew Posted June 18, 2013 Share Posted June 18, 2013 Try something like IExtendedEntityProperties. Here are some examples: Class that implements IExtendedEntityProperties: https://github.com/ModderPenguin/MinePG/blob/master/source/minepg/rpg_common/rpg/playerinfo/PlayerInformation.java How to register it: https://github.com/ModderPenguin/MinePG/blob/master/source/minepg/rpg_common/rpg/handlers/events/GenericEventHandler.java* Register it like any normal forge event handler. * The first method is the one you want Quote I am Mew. The Legendary Psychic. I behave oddly and am always playing practical jokes. I have also found that I really love making extremely long and extremely but sometimes not so descriptive variables. Sort of like what I just did there Link to comment Share on other sites More sharing options...
endershadow Posted June 18, 2013 Author Share Posted June 18, 2013 well, it works, but I can't change the value of the variable. Anyone know why? here's the latest commit, which is basically everything. https://github.com/code-lyoko-modding/CodeLyokoMod/commit/1a441905065cff516af494cca85aad796f16e93c Quote Link to comment Share on other sites More sharing options...
Mew Posted June 18, 2013 Share Posted June 18, 2013 Try something like this: package matt.lyoko.lib; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.world.World; import net.minecraftforge.common.IExtendedEntityProperties; public final class PlayerInformation implements IExtendedEntityProperties { public static final String IDENTIFIER = "lyoko_data"; public static PlayerInformation forPlayer(Entity player) { return (PlayerInformation)player.getExtendedProperties(IDENTIFIER); } public boolean dirty = true; /** The current amount of life points the player has in their mana bar */ private int lifePoints = 100; private final EntityPlayer player; public PlayerInformation(EntityPlayer player) { this.player = player; } @Override public void init(Entity entity, World world) { } @Override public void saveNBTData(NBTTagCompound compound) { NBTTagCompound nbt = new NBTTagCompound(); nbt.setInteger("lifePoints", lifePoints); compound.setCompoundTag(IDENTIFIER, nbt); } @Override public void loadNBTData(NBTTagCompound playerNbt) { NBTTagCompound nbt = playerNbt.getCompoundTag(IDENTIFIER); lifePoints = nbt.getInteger("lifePoints"); } public int getLifePoints() { return lifePoints; } public int setLifePoints(int lifePoints) { if(this.lifePoints != lifePoints) { this.lifePoints = lifePoints; setDirty(); } return this.lifePoints; } public int getMaxLifePoints() { return 100; } public int decreaseLifePoints(int decrement) { lifePoints -= decrement; setDirty(); if (lifePoints < 0) { lifePoints = 0; setDirty(); } return lifePoints; } public int increaseLifePoints(int increment) { lifePoints += increment; setDirty(); if (lifePoints > 100) { lifePoints = 100; setDirty(); } return lifePoints; } /* * marks that this needs to be resend to the client */ public void setDirty() { dirty = true; } } And if you are wanting to change the life points, you just have to call pi.increaseLifePoints(amountToIncrease) or pi.decreaseLifePoints(amountToDecrease) or pi.setLifePoints(amountToSetTo) (the variable pi was taken from your event handler variable of it [Edit] Also in your main class, you register your event handler twice... So I think if you are wanting to keep with my code, delete that first registry of it then keep the last two Quote I am Mew. The Legendary Psychic. I behave oddly and am always playing practical jokes. I have also found that I really love making extremely long and extremely but sometimes not so descriptive variables. Sort of like what I just did there Link to comment Share on other sites More sharing options...
WorldsEnder Posted June 18, 2013 Share Posted June 18, 2013 Okay, like I pointed out a_class_that_can_store_your_values must be a real class. Maybe I just post the code on some external page. http://pastebin.com/XH8FuGNe This should work fine if you replace the Strings I marked to be replaced. Quote Link to comment Share on other sites More sharing options...
WorldsEnder Posted June 18, 2013 Share Posted June 18, 2013 Just another thing I wanted to mention: Download this little progam: http://www.minecraftforum.net/topic/840677-nbtexplorer-nbt-editor-for-windows-and-mac/. It's a great tool to check if your NBTData has been saved or not. Just don't forget to reload. Quote Link to comment Share on other sites More sharing options...
endershadow Posted June 18, 2013 Author Share Posted June 18, 2013 Try something like this: package matt.lyoko.lib; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.world.World; import net.minecraftforge.common.IExtendedEntityProperties; public final class PlayerInformation implements IExtendedEntityProperties { public static final String IDENTIFIER = "lyoko_data"; public static PlayerInformation forPlayer(Entity player) { return (PlayerInformation)player.getExtendedProperties(IDENTIFIER); } public boolean dirty = true; /** The current amount of life points the player has in their mana bar */ private int lifePoints = 100; private final EntityPlayer player; public PlayerInformation(EntityPlayer player) { this.player = player; } @Override public void init(Entity entity, World world) { } @Override public void saveNBTData(NBTTagCompound compound) { NBTTagCompound nbt = new NBTTagCompound(); nbt.setInteger("lifePoints", lifePoints); compound.setCompoundTag(IDENTIFIER, nbt); } @Override public void loadNBTData(NBTTagCompound playerNbt) { NBTTagCompound nbt = playerNbt.getCompoundTag(IDENTIFIER); lifePoints = nbt.getInteger("lifePoints"); } public int getLifePoints() { return lifePoints; } public int setLifePoints(int lifePoints) { if(this.lifePoints != lifePoints) { this.lifePoints = lifePoints; setDirty(); } return this.lifePoints; } public int getMaxLifePoints() { return 100; } public int decreaseLifePoints(int decrement) { lifePoints -= decrement; setDirty(); if (lifePoints < 0) { lifePoints = 0; setDirty(); } return lifePoints; } public int increaseLifePoints(int increment) { lifePoints += increment; setDirty(); if (lifePoints > 100) { lifePoints = 100; setDirty(); } return lifePoints; } /* * marks that this needs to be resend to the client */ public void setDirty() { dirty = true; } } And if you are wanting to change the life points, you just have to call pi.increaseLifePoints(amountToIncrease) or pi.decreaseLifePoints(amountToDecrease) or pi.setLifePoints(amountToSetTo) (the variable pi was taken from your event handler variable of it [Edit] Also in your main class, you register your event handler twice... So I think if you are wanting to keep with my code, delete that first registry of it then keep the last two isn't that what I did? and you're supposed to register it twice. if you look at the mod that did it, they did it the same way I did it. Quote Link to comment Share on other sites More sharing options...
endershadow Posted June 21, 2013 Author Share Posted June 21, 2013 bump Quote Link to comment Share on other sites More sharing options...
Mrift Posted February 10, 2014 Share Posted February 10, 2014 how would I register it. to begin with I think i derped and I used the load(FMLInitializationEvent! not sure what I should do ty in advanced Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.