Jump to content

help adding NBT data to the player


endershadow

Recommended Posts

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.

Link to comment
Share on other sites

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.

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

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?

BEWARE OF GOD

---

Co-author of Pentachoron Labs' SBFP Tech.

Link to comment
Share on other sites

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 ;)

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

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 xD

Link to comment
Share on other sites

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 xD

 

[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  :)

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 xD

Link to comment
Share on other sites

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 xD

 

[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.

Link to comment
Share on other sites

  • 7 months later...

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



  • Recently Browsing

    • No registered users viewing this page.
  • Posts

    • They were already updated, and just to double check I even did a cleanup and fresh update from that same page. I'm quite sure drivers are not the problem here. 
    • i tried downloading the drivers but it says no AMD graphics hardware has been detected    
    • Update your AMD/ATI drivers - get the drivers from their website - do not update via system  
    • As the title says i keep on crashing on forge 1.20.1 even without any mods downloaded, i have the latest drivers (nvidia) and vanilla minecraft works perfectly fine for me logs: https://pastebin.com/5UR01yG9
    • Hello everyone, I'm making this post to seek help for my modded block, It's a special block called FrozenBlock supposed to take the place of an old block, then after a set amount of ticks, it's supposed to revert its Block State, Entity, data... to the old block like this :  The problem I have is that the system breaks when handling multi blocks (I tried some fix but none of them worked) :  The bug I have identified is that the function "setOldBlockFields" in the item's "setFrozenBlock" function gets called once for the 1st block of multiblock getting frozen (as it should), but gets called a second time BEFORE creating the first FrozenBlock with the data of the 1st block, hence giving the same data to the two FrozenBlock :   Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=head] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@73681674 BlockEntityData : id:"minecraft:bed",x:3,y:-60,z:-6} Old Block Fields set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=3, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} Frozen Block Entity set BlockState : Block{minecraft:black_bed}[facing=east,occupied=false,part=foot] BlockPos{x=2, y=-60, z=-6} BlockEntity : net.minecraft.world.level.block.entity.BedBlockEntity@6d1aa3da BlockEntityData : {id:"minecraft:bed",x:2,y:-60,z:-6} here is the code inside my custom "freeze" item :    @Override     public @NotNull InteractionResult useOn(@NotNull UseOnContext pContext) {         if (!pContext.getLevel().isClientSide() && pContext.getHand() == InteractionHand.MAIN_HAND) {             BlockPos blockPos = pContext.getClickedPos();             BlockPos secondBlockPos = getMultiblockPos(blockPos, pContext.getLevel().getBlockState(blockPos));             if (secondBlockPos != null) {                 createFrozenBlock(pContext, secondBlockPos);             }             createFrozenBlock(pContext, blockPos);             return InteractionResult.SUCCESS;         }         return super.useOn(pContext);     }     public static void createFrozenBlock(UseOnContext pContext, BlockPos blockPos) {         BlockState oldState = pContext.getLevel().getBlockState(blockPos);         BlockEntity oldBlockEntity = oldState.hasBlockEntity() ? pContext.getLevel().getBlockEntity(blockPos) : null;         CompoundTag oldBlockEntityData = oldState.hasBlockEntity() ? oldBlockEntity.serializeNBT() : null;         if (oldBlockEntity != null) {             pContext.getLevel().removeBlockEntity(blockPos);         }         BlockState FrozenBlock = setFrozenBlock(oldState, oldBlockEntity, oldBlockEntityData);         pContext.getLevel().setBlockAndUpdate(blockPos, FrozenBlock);     }     public static BlockState setFrozenBlock(BlockState blockState, @Nullable BlockEntity blockEntity, @Nullable CompoundTag blockEntityData) {         BlockState FrozenBlock = BlockRegister.FROZEN_BLOCK.get().defaultBlockState();         ((FrozenBlock) FrozenBlock.getBlock()).setOldBlockFields(blockState, blockEntity, blockEntityData);         return FrozenBlock;     }  
  • Topics

×
×
  • Create New...

Important Information

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