Problème Sauvegarde Boolean ExtendedEntityProperties



  • Bonjour tout le monde
    J'ai créer une ExtendedEntityProperties pour mon joueur dans l'espoir de pouvoir lui faire sauvegarder plusieurs boolean. Cependant lors de ma première tentative, l'information ne semblait pas se sauvegarder si me déconnectai - reconnectai du monde. Je partais avec une valeur égale à true, je revenais, c'était false…J'avais essayé avec les packets. Lors de ma seconde tentative, je me suis donc orienté vers les dataWatcher qui me semblait être aussi une bonne idée du fait qu'il n'y ait pas de synchro client - serveur manuelle à faire sois même. Pourtant j'ai revérifié mon code, mais encore une fois le problème de sauvegarde se pose; le même que la première fois lors des packet. Je ne comprends pas...
    Autre information à prendre en compte: lors de ma première tentative d'EEP, les packet fonctionnaient très bien si ma valeur primitive était tout (byte - short - long, float...) sauf des boolean. Encore quelque chose de très bizarre, me diriez vous x)
    Bref, voici mes 2 classes

    
    public class ExtendedEntityPropertiesPlayer implements IExtendedEntityProperties 
    {
    
    public final static String EXT_PROP_NAME = "ExtPropPlayer";
    
    private final EntityPlayer player;
    
    public ExtendedEntityPropertiesPlayer(EntityPlayer player) 
    {
    this.player = player;
    }
    
    @Override
    public void init(Entity entity, World world) 
    {
    player.getDataWatcher().addObject(3, Byte.valueOf(((byte)0)));
    }
    
    public static final void register(EntityPlayer player) 
    {
    player.registerExtendedProperties(ExtendedEntityPropertiesPlayer.EXT_PROP_NAME, new ExtendedEntityPropertiesPlayer(player));
    }
    
    public static final ExtendedEntityPropertiesPlayer get(EntityPlayer player) 
    {
    return (ExtendedEntityPropertiesPlayer) player.getExtendedProperties(EXT_PROP_NAME);
    }
    
    @Override
    public void saveNBTData(NBTTagCompound compound) 
    {
    NBTTagCompound properties = new NBTTagCompound();
    compound.setTag(EXT_PROP_NAME, properties);
    compound.setBoolean("hasKitSecour", hasKitSecour());
    }
    
    @Override
    public void loadNBTData(NBTTagCompound compound) 
    {
    NBTTagCompound properties = (NBTTagCompound) compound.getTag(EXT_PROP_NAME);
    //this.hasKitSecour = properties.getBoolean("hasKitSecour");
    compound.getBoolean("hasKitSecour");
    }
    
    private String getSaveKey(EntityPlayer player) 
    {
    return player.getDisplayName() + ":" + EXT_PROP_NAME;
    }
    
    public void saveProxyData(EntityPlayer player) 
    {
    ExtendedEntityPropertiesPlayer playerData = ExtendedEntityPropertiesPlayer.get(player);
    NBTTagCompound savedData = new NBTTagCompound();
    
    playerData.saveNBTData(savedData);
    CommonProxy.storeEntityData(getSaveKey(player), savedData);
    }
    
    public void loadProxyData(EntityPlayer player) 
    {
    ExtendedEntityPropertiesPlayer playerData = ExtendedEntityPropertiesPlayer.get(player);
    NBTTagCompound savedData = CommonProxy.getEntityData(getSaveKey(player));
    
    if (savedData != null) 
    {
    playerData.loadNBTData(savedData);
    }
    //playerData.sync();
    }
    
    public boolean hasKitSecour() 
    {
    return player.getDataWatcher().getWatchableObjectByte(3) == 1;
    }
    
    public void setHasKitSecour(boolean flag) 
    {
    byte b0 = player.getDataWatcher().getWatchableObjectByte(3);
    
    if(flag)
    {
    player.getDataWatcher().updateObject(3, Byte.valueOf(((byte)1)));
    }
    else
    {
    player.getDataWatcher().updateObject(3, Byte.valueOf(((byte)0)));
    }
    }
    }
    
    
    
    package fr.mrplaigon.dyingcraft.common.handler.event;
    
    import cpw.mods.fml.common.eventhandler.SubscribeEvent;
    import fr.mrplaigon.dyingcraft.common.core.CommonProxy;
    import fr.mrplaigon.dyingcraft.common.extprop.ExtendedEntityPropertiesPlayer;
    import net.minecraft.entity.monster.EntityCaveSpider;
    import net.minecraft.entity.monster.EntityCreeper;
    import net.minecraft.entity.monster.EntityEnderman;
    import net.minecraft.entity.monster.EntitySilverfish;
    import net.minecraft.entity.monster.EntitySkeleton;
    import net.minecraft.entity.monster.EntitySlime;
    import net.minecraft.entity.monster.EntitySpider;
    import net.minecraft.entity.monster.EntityWitch;
    import net.minecraft.entity.monster.EntityZombie;
    import net.minecraft.entity.passive.EntityBat;
    import net.minecraft.entity.passive.EntityHorse;
    import net.minecraft.entity.passive.EntityOcelot;
    import net.minecraft.entity.passive.EntitySheep;
    import net.minecraft.entity.passive.EntitySquid;
    import net.minecraft.entity.passive.EntityWolf;
    import net.minecraft.entity.player.EntityPlayer;
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraftforge.event.entity.EntityEvent.EntityConstructing;
    import net.minecraftforge.event.entity.EntityJoinWorldEvent;
    import net.minecraftforge.event.entity.living.LivingDeathEvent;
    
    public class ExtPropEventHandler
    {
    
    private CommonProxy commonProxy = new CommonProxy();
    
    @SubscribeEvent
    public void onEntityConstructing(EntityConstructing event) 
    {
    if (event.entity instanceof EntityPlayer && ExtendedEntityPropertiesPlayer.get((EntityPlayer) event.entity) == null)
    {
    ExtendedEntityPropertiesPlayer.register((EntityPlayer) event.entity);
    }
    }
    
    @SubscribeEvent
    public void onLivingDeathEvent(LivingDeathEvent event) 
    {
    if (!event.entity.worldObj.isRemote&& event.entity instanceof EntityPlayer) 
    {
    NBTTagCompound playerData = new NBTTagCompound();
    ((ExtendedEntityPropertiesPlayer) (event.entity.getExtendedProperties(ExtendedEntityPropertiesPlayer.EXT_PROP_NAME))).saveNBTData(playerData);
    commonProxy.storeEntityData(((EntityPlayer) event.entity).getDisplayName(), playerData);
    //ExtendedEntityPropertiesPlayer.saveProxyData((EntityPlayer) event.entity);
    ((ExtendedEntityPropertiesPlayer) (event.entity.getExtendedProperties(ExtendedEntityPropertiesPlayer.EXT_PROP_NAME))).saveProxyData((EntityPlayer) event.entity);
    } 
    }
    
    @SubscribeEvent
    public void onEntityJoinWorld(EntityJoinWorldEvent event) 
    {
    if (!event.entity.worldObj.isRemote && event.entity instanceof EntityPlayer) 
    {
    NBTTagCompound playerData = commonProxy.getEntityData(((EntityPlayer) event.entity).getDisplayName());
    if (playerData != null) 
    {
    ((ExtendedEntityPropertiesPlayer) (event.entity.getExtendedProperties(ExtendedEntityPropertiesPlayer.EXT_PROP_NAME))).loadNBTData(playerData);
    }
    //((ExtendedEntityPropertiesPlayer) (event.entity.getExtendedProperties(ExtendedEntityPropertiesPlayer.EXT_PROP_NAME))).sync();
    }
    }
    }
    
    

    Je vous remercie d'avance

    PS = Si vous pensez que les packet sont mieux sur certain points (notamment sur la limite de DataWatcher dispos, ce que je ne contredirai surtout pas ^^'), et que vous préferrez que je revienne sur des packets, dites le moi. Je ferai alors les modifs nécessaires 😉


  • Administrateurs

    Salut,
    Si c'est pour un mod privé tu peux rester sur les DataWatcher.
    Si c'est pour un mod public utilises les DataWatcher uniquement sur tes propres entités. Pas sur un extended entity properties il y a trop de risque de conflit.

    Pour ton code : tu get la valeur de hasKitSecour dans la fonction loadNBTData mais tu ne fais rien avec cette valeur … Il faudrait peut-être update le datawatcher avec cette valeur non ?



  • En fait je la get mais elle est modifiée, puisque dans une classe d item à part, dans le onItemRightClick, je me sers de ma méthode setHasKitSecour


  • Administrateurs

    Heu non.
    Là tu as ça :

    @Override
    public void loadNBTData(NBTTagCompound compound)
    {
        NBTTagCompound properties = (NBTTagCompound) compound.getTag(EXT_PROP_NAME);
        //this.hasKitSecour = properties.getBoolean("hasKitSecour");
        compound.getBoolean("hasKitSecour");
    }
    

    Tu ne fais absolument rien avec compound.getBoolean("hasKitSecour") …


  • Correcteurs

    C'est ce que je t'avais dit dans la shoutbox, il faut ensuite que tu update ton datawatcher.



  • J'utilise le même code dans la classe d'un mob que j'ai fait et tout marche nikel. Voilà de quoi je parlais tout à l'heure

    
           public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player)
           {
    ExtendedEntityPropertiesPlayer props = ExtendedEntityPropertiesPlayer.get(player);
    if(props.hasKitSecour())
    props.setHasKitSecour(false);
    else
    props.setHasKitSecour(true);
                   return stack;
           }
    
    

    Pour moi vu que c'est la méthode qui load le boolean stocké dans le tag du joueur, y'a pas besoin de set une valeur ou quoique ce soit d'autre. Je ne sais pas si c'est comparable mais j'ai exactement les mêmes méthodes et j'ai donc procédé de la même manière pour un mob que j'ai fait : tag + dataWatcher. Tout marchait et marche encore où moment je vous parle ^^'


  • Correcteurs

    Ouais mais ta méthode load est complètement inutile dans ce cas car tu récupère seulement, il faudrait que tu update. c'est logique si tu fais seulement le récup et que tu le jete, ça sert a rien.



  • Mais mes data watcher sont censés se mettre à jour automatiquement. J'ai trouvé ce tuto où l'auteur ne se sert même pas des NBT, pensez vous que ce soit une bonne idée ?


  • Correcteurs

    En fait les NBT c'est pour sauvegarder et dans tout code actuel ils ne servent à rien puisque tu ne les update pas donc si ça fonctionne comma ça, oui tu peux les retirer



  • Mais je ne comprends pas ce que tu racontes. Les NBTTagCompound n'ont pas à être mis à jour.
    Regarde cette entity, tu comprendras mieux

    
    public class Assassin extends EntityMob
    {
    
    public Assassin(World world)
    {
    super(world);
    this.setSize(1.25f, 2.85f);
    //this.experienceValue = 30;
    }
    
    protected void applyEntityAttributes()
    {
    super.applyEntityAttributes();
    this.getEntityAttribute(SharedMonsterAttributes.followRange).setBaseValue(16.0D);
    this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue(80.0D);
    this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.0D);
    this.getEntityAttribute(SharedMonsterAttributes.attackDamage).setBaseValue(10.0D);//En hard, toujours mettre la valeur souhaitée - 2 pour que le mob et son attaque puissent bien fonctionner !
    this.getEntityAttribute(SharedMonsterAttributes.knockbackResistance).setBaseValue(2.0D);
    }
    
    protected void entityInit()
    {
    super.entityInit();
    this.dataWatcher.addObject(2, Byte.valueOf(((byte)0)));
    }
    
    public void writeEntityToNBT(NBTTagCompound compound)
    {
    super.writeEntityToNBT(compound);
    compound.setBoolean("isCrying", this.isCrying());
    }
    
    public void readFromEntityToNBT(NBTTagCompound compound)
    {
    super.readFromNBT(compound);
    compound.getBoolean("isCrying");
    }
    
    public void onLivingUpdate()
    {
    if(isCrying() && this.getHealth() > 0.0F && this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).getBaseValue() != 0.0D)
    {
    worldObj.playSoundAtEntity(this, DyingCraftMod.MODID + ":assassinCry", 5.0F, 1.0F);
    this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.0D);
    }
    if(isCrying() && this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).getBaseValue() == 0.0D)
    {
    if(worldObj.getTotalWorldTime() % 80 == 0)
    {
    this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).setBaseValue(0.23D);
    this.setCrying(false);
    }
    }
    super.onLivingUpdate();
    }
    
    public boolean attackEntityFrom(DamageSource damagesource, float amount)
    {
    if(!worldObj.isRemote && attackingPlayer != null)
    {
    if(attackingPlayer.getHeldItem() != null)
    {
    if(worldObj.rand.nextInt(3) + 1 == 3)
    {
    this.setCrying(true);
    }
    }
    }
    return super.attackEntityFrom(damagesource, amount);
    }
    
    public boolean isCrying()
    {
    return this.dataWatcher.getWatchableObjectByte(2) != 0;
    }
    
    public void setCrying(boolean flag)
    {
    byte b0 = this.dataWatcher.getWatchableObjectByte(2);
    
    if(flag)
    {
    this.dataWatcher.updateObject(2, Byte.valueOf(((byte)1)));
    }
    else
    {
    this.dataWatcher.updateObject(2, Byte.valueOf(((byte)0)));
    }
    }
    }
    
    

    Je réfléchis encore mais je pense retourner à l'utilisation des packets.
    Je refais le code le plus proprement possible et je vous le renvoie si ça coince 😉



  • C'est bon prob réglé. Je suis passé par les packets, la première fois j'avais dû faire des bêtises avec les conditions du genre isRemote…
    Merci à vous tous ! 😃


  • Correcteurs

    Je ne parle pas du compound, je parle du datawatcher: this.datawatcher.updateObject(1, compound.getBoolean("isCrying"));