Sauvegarde de donnée avec WorldSavedData



  • Salut
    J'ai un petit problème de variable

    Ce n'est pas vraiment du Minecraft, mais ça y touche quand même un peu.

    J'ai déclarer une variable de type boolean dans ma classe principale, et j'aimerai la modifier quand j'emprunte le portail pour aller vers un autre monde. J'ai l'idée pour faire, mais c'est la pratique qui foire.

    Quand j'essaye de la modifier (ou de la lire, c'est pareil), ça me dit qu'il faut transformer la variable en statique. C'est là que je vois l'idiotie d'Eclipse (ou de moi) : si la variable est statique, elle ne pourra plus être changer.

    Savez-vous comment faire ?

    Merci d'avance

    PS : désolé si ce problème peut paraître évident, mais je ne trouve pas du tout, même après recherche.
           désolé aussi si je ne poste pas dans la bonne catégorie, mais comme dit au dessus, pour moi ça touche un peu à Minecraft, même si c'est plus un             problème éclipse et java.


  • Administrateurs

    Salut,
    Tu confonds avec final je pense.
    final = impossible de réinitialiser la variable.
    static = la variable ne peut avoir qu'une seule instance

    Pour accéder à une variable non static il te faut l'instance de la classe en question. Car la variable non static peut avoir plusieurs instances.


  • Rédacteurs

    Salut,
    Ta variable se trouve dans ta classe principale qui est instanciée par Minecraft, et tu ne pourra pas récupéré cette instance (je crois).
    Eclipse te propose de déclarer ta variable en static, ce qui veux dire que sa valeur sera la même pour toute les instance de ta classe principale, et tu pourra donc y accéder en faisant ClassePrincipale.taVariable. Mais tu pourra modifier cette variable contrairement à ce que tu à l'air de penser. Tu doit confondre avec l'attribut final qui t'oblige à initialisé ta variable lors de son instanciation et qui t'empêche de changer la valeur de la variable.

    En gros, tu pourra toujours changer la valeur de ta variable si tu la passe en static.


  • Administrateurs

    Si on peut récupérer l'instance de la classe principale avec l'annotation @Instance de FML qui est prévu pour 😉
    C'est même nécessaire pour les gui handler.


  • Rédacteurs

    Bah oui, c'est vrai je suis bête … xD



  • Merci, j'ai mis la variable en static. Mais je pensais que statique voulait dire qu'il ne pourra pas être changer.

    J'ai eu peur d'une chose pour la sauvegarde de la variable, et bah ça se produisit : elle n'est pas "sauvegarder".

    J'ai créé un monde j'ai regarder la variable : false. J'ai pris le portail, j'ai regardé la variable : true. Je repris le portail en chemin inverse, j'ai regardé la variable: true (jusque là, normal). J'ai essayé de quitter le monde et de le rejoindre à nouveau, variable true (jusque là, j'étais content). J'ai éteint et rallumer le jeu, variable false (nettement moins content là 😢 )

    Il faudrait la stocker dans les données du monde, pour ce faire, il faut créer des tags NBT. C'est bien ça ?


  • Rédacteurs

    Je sais qu'il y a ça : https://www.minecraftforgefrance.fr/showthread.php?tid=2444
    Après il y a d'autres façon mais bon, essai de cette façon là



  • Ok, merci
    Je teste ça et je te redis après



  • J'ai testé et ça marche.
    Je suis aller dans ma dimension. Les logs buguent un peu en m'affichant pas toujours la vérité, mais j'ai été voir les data du monde (grâce à NBTExplorer, un logiciel) et le data vaut bien 1 (donc true). J'ai essayé de créer un nouveau monde et de sauvegarder : la data n'existe pas (donc false logiquement). Je suis retourner dans le 1er monde et je suis aller dans le Nether ça m'a remis la data à false (ce que j'ai voulu uniquement pour tester la sauvegarde et la lecture). Tout marche bien
    Merci à vous tous

    Voilà les codes si ça peut servir à certains :
    CommonEventHandler (ma classe avec tout les events commun server-client. Pas obligé d'avoir ce nom)

    
    @EventHandler
    public void ReadWorldData(FMLServerStartedEvent event)
    {
    WorldDataToSave.load();
    }
    

    WorldDataToSave (pareil, pas obligé le même nom)

    
    package This_is_Halloween;
    
    import net.minecraft.nbt.NBTTagCompound;
    import net.minecraft.world.WorldSavedData;
    import net.minecraft.world.storage.MapStorage;
    import net.minecraftforge.common.DimensionManager;
    
    public class WorldDataToSave extends WorldSavedData{
    
    private static This_is_Halloween TiH;
    private static final String KEY = TiH.MODID;
    
    public WorldDataToSave(String key)
    {
    super(key);
    }
    
    @Override
    public void readFromNBT(NBTTagCompound NBTTag)
    {
    TiH.apocalypse = NBTTag.getBoolean("apocalypse");
    TiH.apocalypseBoss = NBTTag.getBoolean("apocalypseBoss");
    }
    
    @Override
    public void writeToNBT(NBTTagCompound NBTTag)
    {
    NBTTag.setBoolean("apocalypse", TiH.apocalypse);
    NBTTag.setBoolean("apocalypseBoss", TiH.apocalypseBoss);
    }
    
    public static WorldDataToSave load ()
    {
    if(DimensionManager.getWorlds().length < 1)
    {
    return null;
    }
    
    MapStorage storage = DimensionManager.getWorlds()[0].mapStorage;
    final String KEY = getDataKey();
    WorldDataToSave result = (WorldDataToSave) storage.loadData(WorldDataToSave.class, KEY);
    if(result == null)
    {
    result = new WorldDataToSave(KEY);
    storage.setData(KEY, result);
    }
    return result;
    }
    
    public static String getDataKey()
    {
    return KEY;
    }
    
    }
    
    

    La modification de la variable à sauvegarder :

    
    WorldDataToSave.load().markDirty();
    This_is_Halloween.apocalypse = true;
    
    

    (ne surtout PAS oublié le markDirty. Sans ça, ça ne marchera pas. Je peux vous le confirmer 😉 )
    PS : faudrait peut-être que je modifie le titre, ça n'a plus vraiment à voir avec les variables, mais je sais pas quoi mettre. Une idée ?


  • Rédacteurs

    Sauvegarde de donnée avec WorldSavedData + balise résolue