Сохранение числа в тайл и считывание его.

Версия Minecraft
1.12.2
5,018
47
783
Проблема, казалось бы просторешаемая, но я уже сижу над ней в сумме семь часов. Может это я аутист, но настолько надоело, что решил обратится за помощью сюда, иначе я ** уже скоро. Он мне ночью снился, этот сраный тайл. В общем, у меня есть стейт, который в мету уже не влазит. Было решено этот стейт вместо меты сохранять в тайл, и считывать оттуда же.
Естественно при выходе из игры мой стейт будет скидываться до нуля. Моей задачей является достать значение сохраненной переменной из тайла и задать его стейту.
Написал код в итоге всех мучений, который в теории работать должен так:
Я получаю тайл, проверяю переменную, которая сохранена в тайле(te.stage), на то, что она больше нуля. Если она больше нуля(т.е имеет какое то значение), то я беру и ставлю стейт с этим числом. Иначе - присваиваю значение стейта(ноль, в данном случае). Дальше, если te.stage все таки еще меньше шести, то я делаю рост - увеличиваю переменную на единицу и перезаписываю значение переменной в стейте.
На практике же, получается так:
Все в порядке, блок вырастает до нужного. Однако при перезаходе значение te.stage вновь обнуляется! И вот почему, мне непонятно(
Java:
@Override
    @Override
    public void updateTick(World world, BlockPos pos, IBlockState state, Random random)
    {

        RealTreeTileEntity te = (RealTreeTileEntity)this.getTileEntity(world, pos);
        world.scheduleUpdate(pos, this, 60);
        if(te.stage > 0) {
            world.setBlockState(pos, state.withProperty(STAGE, te.stage));
            if(te.stage < 6) {
                world.setBlockState(pos, state.withProperty(STAGE, te.stage+1));
                te.saveStage(te.stage+1);     
            }
        } else {
            te.stage = state.getValue(STAGE);
        }
        //    stage = te.getStage();
    }
    }
Java:
public class RealTreeTileEntity extends TileEntity {

    public int stage;
  
    public NBTTagCompound writeToNBT(NBTTagCompound nbt)
    {
      
         nbt.setInteger("stage", this.stage);

         return super.writeToNBT(nbt);
    }
    public void readFromNBT(NBTTagCompound nbt)
    {

       this.stage = nbt.getInteger("stage");
        super.readFromNBT(nbt);
    }
    public int getStage() {
  
        return stage;
    }
    public void saveStage(int stage) {
      
        this.stage = stage;
        this.markDirty();
    }
}
 
5,018
47
783
Проблема не в том чтобы стейт поставить, а в том, что переменная, которая должна сохранятся, не сохраняется...(
 
5,018
47
783
Я меняю стейт, он на сервере, как и тайл. Стейт и модель синхронизируются сами, ваниллой, это тут вообще не причем.
 

tox1cozZ

aka Agravaine
8,454
598
2,890
Сколько раз мусолили тебе тему с тайлами - бестолку.
Для чего ты юзаешь updateTick блока и забиваешь список отложенных блоков, если можно этот апдейт делать в тайле расширив ITickable и реализовав метод update? :m_faceplam: 🤷‍♀️

По теме:
У тайла есть метод validate, который вызывается когда тайл "устанавливается" в мир и привязывается к блоку.
В этом методе сделай world.setBlockState(world.getBlockState(pos).withProperty(STAGE, stage)).
Код апдейта будет таким:
Java:
if(world.getTotalWorldTime() % 60 == 0 && stage < 6){
    stage++;
    IBlockState state = world.getBlockState(pos);
    world.setBlockState(pos, state.withProperty(STAGE, stage));
}
 
5,018
47
783
Сколько раз мусолили тебе тему с тайлами - бестолку.
Для чего ты юзаешь updateTick блока и забиваешь список отложенных блоков, если можно этот апдейт делать в тайле расширив ITickable и реализовав метод update? :m_faceplam: 🤷‍♀️
Я так и знал что ты это напишешь.:ROFLMAO: Я даже специально для тебя написал комментарий к этой строчке, но ты видимо не читаешь
Блок у меня будет тикать рандомно, а не через шедулапдейт, сейчас он включен просто для дебага.

Насчет по теме - большое спасибо, щас попробую
 
5,018
47
783
Попробовал, происходит нечто непонятно. Стейт ставится 1, затем 2, затем опять 1 и опять 2
список отложенных блоков
Кстати вопрос, причем тут вообще ванильные отложенные блоки, когда у меня свой мир со своими блоками? Мне так то пофиг на ваниль, вообще говоря
 
5,018
47
783
Ну я сделал, как мне агравайн посоветовал, раз уж все равно сделал тайл.

Java:
public class RealTreeTileEntity extends TileEntity implements ITickable {

    public int stage;
    
    public NBTTagCompound writeToNBT(NBTTagCompound nbt)
    {
        
         nbt.setInteger("stage", this.stage);

         return super.writeToNBT(nbt);
    }
    public void readFromNBT(NBTTagCompound nbt)
    {

       this.stage = nbt.getInteger("stage");
        super.readFromNBT(nbt);
    }
    public int getStage() {
    
        return stage;
    }
    public void saveStage(int stage) {
        
        this.stage = stage;
        this.markDirty();
    }
    @Override
    public void update() {
        IBlockState state = world.getBlockState(pos);
        int stage = this.stage;
        
        if(world.getTotalWorldTime() % 60 == 0 && stage < 6 && !world.isRemote){
            stage++;
            world.setBlockState(pos, state.withProperty(BasicLogBlockTile.STAGE, stage));
            this.saveStage(stage);
            System.out.println("stage " +  stage);
        }
        
    }
}
ты его зарегал?
Конечно, в первую очередь.
 

tox1cozZ

aka Agravaine
8,454
598
2,890
Кстати вопрос, причем тут вообще ванильные отложенные блоки, когда у меня свой мир со своими блоками? Мне так то пофиг на ваниль, вообще говоря
На этом сервере фикс, но в ванилле такое работает изи.
Собственно, здесь куча рельс чтобы забить очередь отложенных блоков. Из-за этого когда ломаем блок -> очередь заполнена -> баннер остается висеть в воздухе.
У тебя же какие-то растения и их может быть ну ваще дофига, соответственно из-за этого могут быть довольно частыми такие аномалии в мире.
 
5,018
47
783
Вопрос решен. Оказывается, при установке с помощью setBlockState меняется и тайл. Проблему решил с помощью копирования старого значения из старого тайла и сохранения его в новый тайл.
Java:
    public void updateTick(World world, BlockPos pos, IBlockState state, Random random)
    {
        RealTreeTileEntity te = (RealTreeTileEntity)this.getTileEntity(world, pos);
        world.scheduleUpdate(pos, this, 60);
        if(te.stage == 6) {
            world.setBlockState(pos, state.withProperty(STAGE, 6));
        } else
            if(te.stage < 6) {
                int stage = te.stage;
                world.removeTileEntity(pos);
                world.setBlockState(pos, state.withProperty(STAGE, stage+1));
                RealTreeTileEntity tile = (RealTreeTileEntity)world.getTileEntity(pos);
                tile.stage = stage + 1;
            }
    }

Так как тики у меня обновляются рандомно, необходимо теперь решить вопрос с обновлением блока непосредственно в момент загрузки мира. Есть методы в блоке, которые вызываются, когда мир загружен?
 
5,018
47
783
Нет, я сделаю в randomTick. Тикающие тайлы мне не нужны. Несмотря на то что там можно сделать рандом, он все равно будет вызыватся и тикать каждый тик, а мне это не нужно.
 
Сверху