World Saved Data или NBT требуется помощь с пониманием принципа чтения и записи

Версия Minecraft
1.12.2
10
2
уже 3 день стараюсь разобраться в принципе работы с NBT и не как не получается существуют ли рабочие примеры на 1.12.2 с подробным описанием принципам работы на русском языке ?
 

tox1cozZ

aka Agravaine
8,454
598
2,890
А что там сложного? NBTTagCompount - это обычная мапа, в которой ключ - строка(название тэга), а значение - собственно значение.
Java:
NBTTagCompond nbt = ...
int value = 10;
nbt.setInteger("название_тэга", value);
Java:
int getValue = nbt.getInteger("название_тэга");
 
10
2
Что я делаю не так?
скрипт почему то не работает save() не сохраняет

Код:
package com.example.FileNBT;


import org.apache.logging.log4j.Logger;

import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTUtil;
import net.minecraft.world.storage.WorldSavedData;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.living.LivingEntityUseItemEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;

public abstract class FileNBT extends WorldSavedData {


    public static Logger logger;
  
    public static int skill_exp =  0;
    public static String skill_name =  "no name";
    public static int test_tag;
  
  
  

    public static void load()
    {
        NBTTagCompound nbt = new NBTTagCompound();
        int test_tag = nbt.getInteger("test_tag");
    }
  
    public static void save()
    {
        NBTTagCompound nbt = new NBTTagCompound();
        nbt.setInteger("test_tag", test_tag);
    }
  


  
    public FileNBT(String name) {
        super(name);
        // TODO Auto-generated constructor stub
    }
  

  
  
}

События
Код:
package com.example.examplemod;

import org.apache.logging.log4j.Logger;


import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.World;
import net.minecraft.world.storage.MapStorage;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
import net.minecraftforge.event.entity.living.LivingDeathEvent;
import net.minecraftforge.event.entity.player.ItemFishedEvent;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.relauncher.Side;

import com.example.FileNBT.FileNBT;

@Mod.EventBusSubscriber(Side.CLIENT)
public class EventsHandler
{
/*
    @SubscribeEvent
    public static void onBlockharvested(BlockEvent.HarvestDropsEvent event) {
        // do your stuff
        System.out.println("onBlockharvested");
    }
   //*/
    @SubscribeEvent
    public static void onBlockDestroyed(BlockEvent.BreakEvent event) {
        /** do your stuff **/
      
        System.out.println("onBlockDestroyed - " + event.getPlayer().getName() + " - " + event.getState().getBlock().getRegistryName()  + " - " + event.getPlayer().inventory.getCurrentItem().getItem().getUnlocalizedName());
        event.getPlayer().sendMessage(new TextComponentString("onBlockDestroyed - " + event.getPlayer().getName() + " - " + event.getState().getBlock().getRegistryName()  + " - " + event.getPlayer().inventory.getCurrentItem().getItem().getUnlocalizedName()));
    }


    @SubscribeEvent
    public static void onJoin(EntityJoinWorldEvent e)
    {
        if (e.getEntity() instanceof EntityPlayer)
        {
            EntityPlayer player = (EntityPlayer) e.getEntity();
            player.sendMessage(new TextComponentString("Привет, %p!".replace("%p", player.getName())));
        }
    }
  
    @SubscribeEvent
    public static void onfishg(ItemFishedEvent event)
    {
        FileNBT.test_tag += 1;
        event.getEntityPlayer().sendMessage(new TextComponentString("Сохронение >> " + FileNBT.test_tag + " элементов Поймал, " +  event.getDrops()));
        FileNBT.save();

    }
  
}


Код:
package com.example.examplemod;

import java.io.File;
import java.io.IOException;

import org.apache.logging.log4j.Logger;

import net.minecraft.client.Minecraft;
import net.minecraft.init.Blocks;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;

import com.example.FileNBT.FileNBT;
import com.example.examplemod.Configs;



@Mod(modid = ExampleMod.MODID, name = ExampleMod.NAME, version = ExampleMod.VERSION)
public class ExampleMod
{

    public static final String MODID = "examplemod";
    public static final String NAME = "Example Mod";
    public static final String VERSION = "1.0";

    private static Logger logger;
  
  

    @EventHandler
    public void preInit(FMLPreInitializationEvent event)
    {
        logger = event.getModLog();
    }
  
    @EventHandler
    public void init(FMLInitializationEvent event) throws IOException
    {
        // some example code Minecraft.getMinecraftDir().getCanonicalPath()
        logger.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName());
        FileNBT.load();
        logger.info("Загрузка прогресса...");
        logger.info("Загруженно >> {}" , FileNBT.skill_exp);
    }


}


Код:
[23:11:35] [main/INFO] [examplemod]: Загрузка прогресса...
[23:11:35] [main/INFO] [examplemod]: Загруженно >> 0
[23:23:23] [main/INFO] [minecraft/GuiNewChat]: [CHAT] Сохронение >> 1 элементов Поймал, [1xitem.fish@0]
[23:23:46] [main/INFO] [minecraft/GuiNewChat]: [CHAT] Сохронение >> 2 элементов Поймал, [1xitem.bone@0]
[23:24:01] [main/INFO] [minecraft/GuiNewChat]: [CHAT] Сохронение >> 3 элементов Поймал, [1xitem.fish@1]
[23:24:36] [main/INFO] [minecraft/GuiNewChat]: [CHAT] Сохронение >> 4 элементов Поймал, [1xitem.fish@2]
[23:24:36] [main/INFO] [minecraft/AdvancementList]: Loaded 11 advancements
[23:24:50] [main/INFO] [minecraft/GuiNewChat]: [CHAT] Сохронение >> 5 элементов Поймал, [1xitem.fish@0]
[23:25:18] [main/INFO] [minecraft/GuiNewChat]: [CHAT] Сохронение >> 6 элементов Поймал, [1xitem.fish@0]
[23:25:41] [main/INFO] [minecraft/GuiNewChat]: [CHAT] Сохронение >> 7 элементов Поймал, [1xitem.fish@3]
[23:25:55] [main/INFO] [minecraft/GuiNewChat]: [CHAT] Сохронение >> 8 элементов Поймал, [1xitem.fish@3]
[23:26:09] [main/INFO] [minecraft/GuiNewChat]: [CHAT] Сохронение >> 9 элементов Поймал, [1xitem.fish@0]
[23:26:18] [main/INFO] [minecraft/GuiNewChat]: [CHAT] Сохронение >> 10 элементов Поймал, [1xitem.fish@3]
[23:38:34] [main/INFO] [examplemod]: Загрузка прогресса...
[23:38:34] [main/INFO] [examplemod]: Загруженно >> 0
 
Последнее редактирование:

tox1cozZ

aka Agravaine
8,454
598
2,890
Полнейшую дичь пишешь.
Во-первых, не называй код скриптами.
Во-вторых, зачем ты все поля сделал статическими? Иди почитай что такое ООП и в частности static.
Тебе нужно создать класс, который наследует от WorldSavedData и переопределить методы. Свои данные сохранять и читать в writeToNBT и readFromNBT соответственно.
Достать данные из мира можно через world.loadItemData(ТвойКласс.class). Конечно же добавить проверку, что если нет таких данных - делать world.setItemData(new ТвойКласс()).
-
Как я понял, ты хочешь хранить количество выловленных рыб игроком. Для этого лучше использовать капу, так как нужно различать игроков(один игрок словил три рыбы, второй пять и т.д). Ищи тутор на форуме, был где-то.
 
10
2
Полнейшую дичь пишешь. ( верно пока пытаюсь понять принцип работы NBT )
Во-первых, не называй код скриптами. (хорошо)
Во-вторых, зачем ты все поля сделал статическими? Иди почитай что такое ООП и в частности static. (я давно изучал язык и по этому много забыл )
Тебе нужно создать класс, который наследует от WorldSavedData и переопределить методы. Свои данные сохранять и читать в writeToNBT и readFromNBT соответственно. (я не до конца понимаю как это работает я не смог разобрать принцип работы )
-

Как я понял, ты хочешь хранить количество выловленных рыб игроком. Для этого лучше использовать капу, так как нужно различать игроков(один игрок словил три рыбы, второй пять и т.д). Ищи тутор на форуме, был где-то.
(нет рыба была добавлена для отладки чтобы во время неё можно было подумать)
 
Последнее редактирование:

necauqua

когда-то был anti344
Администратор
1,216
27
172
Вообще что-то связанное с игроками лучше хранить в нбт игроков, нет?
Есть же как раз капабилити вроде
пример
 
1,470
19
189
ну смотри. у тебя есть класс, который наследуется от WSD. в нем переопределены методы чтения/записи. тебе надо сделать публичную переменную, fish например, и при чтении сетать ее из НБТ, а при записи записывать ее же. при эвенте ловли, менять переменную fish в классе.
 
10
2
Получилось произвести запись и чтения с помощью

помогли советы и спасибо за поддержку
necauqua
Nix13
Agravaine




и часть примера которая работала
IAttribute & DataWatcher/DataManager

Код:
package com.example.examplemod;

import org.apache.logging.log4j.Logger;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent;
import net.minecraftforge.fml.common.gameevent.PlayerEvent.PlayerLoggedOutEvent;

@Mod.EventBusSubscriber(modid = ExampleMod.MODID)
public class data {
   
    static Logger logger;
   
    //Сохранение значения жажды в NBT игрока.
    //Желательно сохранять значение при каждом изменении, иначе в случае аварийного завершения
    //игры (к примеру комбинацией Alt+F4) данные не будут сохранены (PlayerLoggedOutEvent не сработает).
    private static void saveThirstyToNBT(EntityPlayer player , String str , long i) {
 
        if(player.getEntityData().getTag(ExampleMod.MODID) != null)
        {
            NBTTagCompound nbt = (NBTTagCompound) player.getEntityData().getTag(ExampleMod.MODID);
            nbt.setLong(str, i);
        }
        else
        {
            NBTTagCompound nbt = new NBTTagCompound();
            nbt.setLong(str, i);
            player.getEntityData().setTag(ExampleMod.MODID, nbt);
        }

    }

    //Загрузка из NBT.
    private static long loadThirstyFromNBT(EntityPlayer player , String str) {
 
        NBTTagCompound nbt = (NBTTagCompound) player.getEntityData().getTag(ExampleMod.MODID);
        return nbt.getLong(str);
    }

    @SubscribeEvent
    public static void onPlayerLogIn(PlayerLoggedInEvent event) {                              
        System.out.println("Загрузка значения из NBT при входе на и сервер (срабатывает для физического и логического серверов).");
        mcmmoskill.Fishing_experience = loadThirstyFromNBT(event.player, "Fishing_experience"); // Загрузка значения в NBT игрока при выходе.
        System.out.println( " на прямую из баззы данных "+ mcmmoskill.Fishing_experience);
    }

    @SubscribeEvent
    public static void onPlayerLogOut(PlayerLoggedOutEvent event) {
        System.out.println("Сохранение значения в NBT игрока при выходе.");
        saveThirstyToNBT(event.player, "Fishing_experience", mcmmoskill.Fishing_experience);//Сохранение значения в NBT игрока при выходе.
    }
   
   
   
}
 
Сверху