Возвращение меты поворота и роста

Версия Minecraft
1.12.2
5,149
49
899
Здравствуйте! В общем, имеется некий блок, у которого есть два стейта - один инт - стадия роста, а другой EnumAxis. Собственно говоря, мне необходимо чтобы в мету нормально сохранялось и поворот, и мета роста. Но в мете можно вернуть только одно значение.

И вот никак у меня в голове не укладывается, как можно увязать и сохранить в мету обе переменных.
На данный момент у меня только дефолтный метод, который сохраняет лишь мету поворота... Сижу уже полдня над такой фигней, никак не придумаю.
Java:
public int getMetaFromState(IBlockState state)
    {
        int meta = 0;
        EnumFacing.Axis axis = (EnumFacing.Axis)state.getValue(AXIS);
       
       
        if (axis == EnumFacing.Axis.X)
        {
            meta |= 4;
        }
        else if (axis == EnumFacing.Axis.Z)
        {
            meta |= 8;
            return meta;
        }
        return meta;
    }

Вот как наоборот получить - я понял, а сохранить...

Java:
    public IBlockState getStateFromMeta(int meta)
    {
        EnumFacing.Axis enumfacing$axis = EnumFacing.Axis.Y;
    
        
        int i = meta & 12;

        if (i == 4)
        {
            enumfacing$axis = EnumFacing.Axis.X;
        }
        else if (i == 8)
        {
            enumfacing$axis = EnumFacing.Axis.Z;
        }

        return (this.getDefaultState().withProperty(AXIS, enumfacing$axis).withProperty(STAGE, meta));
    }
 
Решение
Изначально ты суешь мету которую хранит твой блок
BitsArray bits = new BitsArray(meta);

далее получаешь свои значения двух переменных:
Java:
int rotateAngle = bits.GetInt(1,2, 0); //0,1,2,3 * 90
int growth = bits.GetInt(3,6, 2);
GetInt(1,2,0)
взять число лежащим по биту с 1 до 2 бита, где 0 - это сколько из 8 бит нужно удалить справа (удалить с самого начала)
поворот у тебя имеет 4 значения (вторые числа - это в виде двоичной):
0 = 00
1 = 01
2 = 10
3 = 11
это чтоб тебе понятнее было, разберем вторую строку
int growth = bits.GetInt(3,6, 2);
Взять число начиная с 3го бита по 6ой включительно, и удалить 2 бита справа (в массиве хранятся числа в 8ми битах), первые два бита будут чему то равны, потому что там у нас другое число...
Да бы хорошо... но там тип бревна, там класс где метадата есть, которая задается. А у меня число обычное, integer.
Если бы можно было, я б так давно сделал вот... meta = meta | ((Integer)state.getValue(STAGE)).getMetadata();
Но нету в интеджере никакой метадаты.В принципе каст там необязательный даже, но это для наглядности
 
Up
 
Я нашел что то похожее в диоде... Но игра крашится с нуллом.
Java:
    public IBlockState getStateFromMeta(int meta)
    {
        return this.getDefaultState().withProperty(AXIS, EnumFacing.getFront(meta)).withProperty(STAGE, Integer.valueOf(1 + (meta >> 2)));
    }
    public int getMetaFromState(IBlockState state)
    {
        int meta = 0;
        meta = meta | ((EnumFacing)state.getValue(AXIS)).getIndex();
        meta = meta | ((Integer)state.getValue(STAGE)).intValue() - 1 << 2;
        return meta;
    }

Причем краш какой то очень странный. Не имеющий никакого отношения к блоку...
Но он точно из за этого.

Java:
[16:10:59] [main/FATAL] [FML]: The following problems were captured during this phase
[16:10:59] [main/ERROR] [FML]: Caught exception from realism (realism)
java.lang.ExceptionInInitializerError: null
    at com.legendgamer.realism.world.biomes.magmatic.MagmaticBiome.<init>(MagmaticBiome.java:28) ~[bin/:?]
    at com.legendgamer.realism.reg.RegBiomes.<clinit>(RegBiomes.java:17) ~[bin/:?]
    at com.legendgamer.realism.proxy.CommonProxy.preInit(CommonProxy.java:20) ~[bin/:?]
    at com.legendgamer.realism.proxy.ClientProxy.preInit(ClientProxy.java:31) ~[bin/:?]
    at com.legendgamer.realism.Realism.preInit(Realism.java:34) ~[bin/:?]
 
Всё просто друг мой.
Для поворота нужен 6 значений, число 6 в битах занимает 3 бита. Остальные БИТЫ ты можешь использовать для чего то ещё, их остается не так много, но может хватит для роста в том числе
4 бита - это уже 16 (от 0 до 15) значений.
System.out.println(Integer.toBinaryString(15));
 
Спасибо, за информацию. Но что мне это дает?
Мне трех значений вполне хватает, т.к поворот просто по трем осям.
 
Это тебе дает то, что на поворот у тебя 3 бита, и на стадию роста роста остается 1 бит (либо выросло, либо нет).
Но если тебе для поворота нужно только 4 состояния, то это 2 бита. И на стадии роста уже можно разгуляться.
 
поворота нужно только 4 состояния,
Так три же, а не 4. X ось, Y и Z. В таком случае сколько получается? Или так в принципе нельзя?

Вот в диоде каким то образом умещают енумфейсинг и инт

Java:
   i = i | ((EnumFacing)state.getValue(FACING)).getHorizontalIndex();
        i = i | ((Integer)state.getValue(DELAY)).intValue() - 1 << 2;
Я так понял этим <<2 два бита фейсинга сдвигаются в сторону освобождая ячейки еще двум битам инта. А те два которые были изначально от фейсинга куда сдвигаются то вообще?
 
Вот так сейчас код выглядит:

Java:
    public IBlockState getStateFromMeta(int meta)
    {
        EnumFacing.Axis enumfacing$axis = EnumFacing.Axis.Y;
   

        return (this.getDefaultState().withProperty(AXIS, enumfacing$axis).withProperty(STAGE, Integer.valueOf(1 + (meta >> 2))));
    }

   
    public int getMetaFromState(IBlockState state)
    {
    //    System.out.println("getMetaFromState " + state.getValue(AXIS));
        int meta = 0; //мета 0
        meta = meta | ((EnumFacing.Axis)state.getValue(AXIS)); //тут надо получить из осей каким то образом инт. Допустим это ordinal() можно сделать... или нельзя? 
       meta = meta | ((Integer)state.getValue(STAGE)).intValue() << 2;
        return meta;
   
       
       
    }
 
Последнее редактирование:
Код:
byte meta = 18;
BitsArray bits = new BitsArray(meta);
int rotateAngle = bits.GetInt(1,3); //0,1,2,3,4 * 90
int growth = bits.GetInt(4,7);
System.out.println("rotateAngle:" + rotateAngle);
System.out.println("growth:" + growth);

growth++;

BitsArray newbits = new BitsArray(Integer.toBinaryString(growth) + Integer.toBinaryString(rotateAngle));
meta = (byte)newbits.GetInt();
System.out.println("meta:" + meta);
ну а недостающий элемент тут ZZZubec/PluginUtils
специально для тебя написал ;)
 
Спасибо большое... А можешь теперь рассказать что тут происходит, пожалуйста? Я так ничерта и не понял...
И будет ли это с ванильными фейсингами и прочей лабудой работать?
Ты просто сделал кастомную мету? А она будет сохранятся в стейт? А будет она восприниматься майном?
Да и поворот .. это не не int, а EnumFacing.Axis который я пока даже не придумал как в инт перевести... если ток запарсить, но это парсер свой писать.
 
Последнее редактирование:
Блин, ошибки щас поправлю, погоди немного. Очень торопился..
 
Короче, я сгорел. Мне проще и быстрее создать еще один блок с фейсингами и назвать его ветки, чем мучаться этим говном. Спасибо, проблема решена.
 
Код:
System.out.println("-----------------------");
byte meta = 23;
BitsArray bits = new BitsArray(meta);
int rotateAngle = bits.GetInt(1,2, 0); //0,1,2,3 * 90
int growth = bits.GetInt(3,7, 2);
System.out.println("rotateAngle:" + rotateAngle);
System.out.println("growth:" + growth);

growth++;

BitsArray ba_growth = new BitsArray(growth);
BitsArray ba_rotate = new BitsArray(rotateAngle);
BitsArray result = BitsArray.join(ba_rotate, 2, ba_growth );
meta = (byte)result.GetInt();
System.out.println("meta:" + meta);
теперь пишу объяснение..
 
Изначально ты суешь мету которую хранит твой блок
BitsArray bits = new BitsArray(meta);

далее получаешь свои значения двух переменных:
Java:
int rotateAngle = bits.GetInt(1,2, 0); //0,1,2,3 * 90
int growth = bits.GetInt(3,6, 2);
GetInt(1,2,0)
взять число лежащим по биту с 1 до 2 бита, где 0 - это сколько из 8 бит нужно удалить справа (удалить с самого начала)
поворот у тебя имеет 4 значения (вторые числа - это в виде двоичной):
0 = 00
1 = 01
2 = 10
3 = 11
это чтоб тебе понятнее было, разберем вторую строку
int growth = bits.GetInt(3,6, 2);
Взять число начиная с 3го бита по 6ой включительно, и удалить 2 бита справа (в массиве хранятся числа в 8ми битах), первые два бита будут чему то равны, потому что там у нас другое число хранится. И эти 2а бита нам не нужны в этом числе.
второе число у нас занимает 4 бита (3ий бит, 4ый, 5ый, 6ой)

нам допустим надо увеличить рост, делаем
growth++;

теперь нам надо как то запихнуть это всё обратно

Java:
BitsArray ba_growth = new BitsArray(growth);
BitsArray ba_rotate = new BitsArray(rotateAngle);
BitsArray result = BitsArray.join(ba_rotate, 2, ba_growth );
meta = (byte)result.GetInt();

Создаем два обьекта, каждый из которых хранится и раскладывается в 8 битах
а потом соединяем первый, со вторым.
BitsArray.join(ba_rotate, 2, ba_growth );
число 2а, это длинна в битах первого числа. То есть записать второе число после 2го бита (то бишь начиная с 3го).

Пользуйся.. фух, писец меня тут отвлекали.
Не разберешься пиши в скайп или телеграмм, ну или тут. Просто там быстрее будет..
Пример написан вот прям то что тебе надо, ничего менять тебе не придется.
 
Последнее редактирование:
Я тут просто сделал второй блок уже. Но эта кастомная мета я думаю многим пригодится. А запили в туторах это. Чего мне то... пусть всем будет. А тут не найдет никто...
 
Назад
Сверху