Помогите с метадатой

Версия Minecraft
1.12.2
5,018
47
783
Привет! Прошу помощи ввиду полной своей непонимаемости того, как работает мета и как в нее надо сохранять, уже пытался много раз понять, но результата нет. Если кто то хорошо разбирается в ней, запилите пожалуйста гайд по мете...
Имеется блок, который поворачивается по двум осям - X и Z, а также имеет стадии роста от 0 до 6. У меня никак не получается сохранить и поворот, и стадию роста. Постоянно подставляется какое то левое значение - то поворот изменится, то стадия.
Справедливости ради, скажу что сидел над этим говном вчера часов пять. От безысходности начал уже перебирать все по кругу.
Путем перебора всех цифр, побитовых операторов никакой закономерности обнаружить не удалось.
Памагити...
Java:
public class BlockThickBranch extends BasicBlock {
    
    public static final PropertyInteger STAGE = PropertyInteger.create("stage", 0, 6);
    public static final PropertyEnum<EnumAxis> AXIS = PropertyEnum.<EnumAxis>create("axis", EnumAxis.class);
    
    public BlockThickBranch(Material materialIn, String name, float hardness, float resistanse, SoundType soundtype,
            CreativeTabs tab) {
        super(materialIn, name, hardness, resistanse, soundtype, tab);
        this.setDefaultState(this.blockState.getBaseState().withProperty(STAGE, 0).withProperty(AXIS, EnumAxis.X));
    }
    
    //Вот эти два дьявольских метода. Надо сохранять 2 поворота по X и Z, а также шесть значений роста.
    //Два поворота 1 бит (0 - x, 1 - z), шесть роста - 3 бита. По идее.. сука, но я не знаю, почему это не работает!!!1!адинадин
    public IBlockState getStateFromMeta(int meta)
    {
        EnumAxis enumfacing$axis = EnumAxis.X;
        
        int i = meta & 12;
    //    System.out.println("getStateFromMeta meta: " + i );
    //    System.out.println("getStateFromMeta i: " + i );
        
        if (i == 4)
        {
            
            enumfacing$axis = EnumAxis.X;
            
        }
        else if (i == 8)
        {
            enumfacing$axis = EnumAxis.Z;
            
        }
    
        return this.getDefaultState().withProperty(AXIS, enumfacing$axis).withProperty(STAGE, Integer.valueOf(((meta & 6))));
        
    }
    public int getMetaFromState(IBlockState state)
    {
        int i = 0;
    //    System.out.println("getMetaFromState STAGE: " + state.getValue(STAGE));
    //   i = i | ((Integer)state.getValue(STAGE)).intValue() << 4;

         switch ((EnumAxis)state.getValue(AXIS))
            {
                case X:
                    i |= 4;
                    break;
                case Z:
                    i |= 8;
                    break;
            }
         i = i | ((Integer)state.getValue(STAGE)).intValue();
    //     System.out.println("getMetaFromState post i: " + i);
        return i;
    }
    
    public boolean onBlockActivated(World world, BlockPos pos, IBlockState state, EntityPlayer playerIn, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ)
    {
        int i = 0;
       i = state.getValue(STAGE) << 2;
       System.out.println(Integer.toBinaryString(i));

       if(state.getValue(STAGE) < 6) world.setBlockState(pos, state.withProperty(STAGE, state.getValue(STAGE)+1));

        return true;
    }
    
    @Override
    public boolean rotateBlock(World world, BlockPos pos, EnumFacing axis)
    {
        IBlockState state = world.getBlockState(pos);
        for (net.minecraft.block.properties.IProperty<?> prop : state.getProperties().keySet())
        {
            if (prop.getName().equals("axis"))
            {
                world.setBlockState(pos, state.cycleProperty(prop));
                return true;
            }
        }
        return false;
    }
    public IBlockState getStateForPlacement(World worldIn, BlockPos pos, EnumFacing facing, float hitX, float hitY, float hitZ, int meta, EntityLivingBase placer)
    {
        
        return this.getStateFromMeta(meta).withProperty(AXIS, EnumAxis.fromFacingAxis(facing.getAxis()));
    }
    
    
    public IBlockState withRotation(IBlockState state, Rotation rot)
    {
        switch (rot)
        {
        case COUNTERCLOCKWISE_90:
        case CLOCKWISE_90:

            switch ((EnumAxis)state.getValue(AXIS))
            {
            case X:
                return state.withProperty(AXIS, EnumAxis.Z);
            case Z:
                return state.withProperty(AXIS, EnumAxis.X);
            default:
                return state;
            }

        default:
            return state;
        }
    }
    @Override
    public boolean isOpaqueCube(IBlockState state) {
        return false;
    }
    @Override
    @SideOnly(Side.CLIENT)
    public boolean shouldSideBeRendered(IBlockState blockState, IBlockAccess blockAccess, BlockPos pos, EnumFacing side) {
        return true;
    }
    @Override
    @SideOnly(Side.CLIENT)
    public boolean isFullCube(IBlockState state) {
        if(state.getValue(STAGE) == 6) {
            return true;
        }
        return false;
    }     


    protected BlockStateContainer createBlockState()
    {
        return new BlockStateContainer(this, new IProperty[] {STAGE, AXIS});
    }
    public static enum EnumAxis implements IStringSerializable {
        X("x"),
        Z("z");

        private final String name;

        private EnumAxis(String name)
        {
            this.name = name;
        }

        public String toString()
        {
            return this.name;
        }

        public static EnumAxis fromFacingAxis(Axis axis)
        {
            switch (axis)
            {
            case X:
                return X;
            case Z:
                return Z;
            default:
                return X;
            }
        }

        public String getName()
        {
            return this.name;
        }

    }
}
 
Решение
Сделай декартово произведение сочетаний двух проперти, размести его в листе. Тогда индексы листа 0-11 будут метой, а значения соответствовать стейтам. Для оптимизации getMetaFromState можно отобразить лист в мапу Map<Pair<Integer, EnumAxis>, Integer>
Красивое и изящное решение)
~~~
Че-то типо того
Java:
List<Pair<Integer,EnumAxis>> metaToState =
    ImmutableSet.of(EnumAxis.X, BlockLog.EnumAxis.Z).stream()
                .flatMap(axis -> IntStream.range(0, 6)
                        .mapToObj(stage -> Pair.of(stage, axis)))
                .collect(Collectors.toList());

tox1cozZ

aka Agravaine
8,455
598
2,892
Если я не ошибаюсь, то ты никак не сохранишь поворот и стадию роста в один бит (от 0 до 15).
Смотри, у тебя значений будет больше 15, так как 4 (стороны поворота) * 6 (стадии роста) уже 24 варианта значений.
 
7,099
324
1,510
Сделай декартово произведение сочетаний двух проперти, размести его в листе. Тогда индексы листа 0-11 будут метой, а значения соответствовать стейтам. Для оптимизации getMetaFromState можно отобразить лист в мапу Map<Pair<Integer, EnumAxis>, Integer>
Красивое и изящное решение)
~~~
Че-то типо того
Java:
List<Pair<Integer,EnumAxis>> metaToState =
    ImmutableSet.of(EnumAxis.X, BlockLog.EnumAxis.Z).stream()
                .flatMap(axis -> IntStream.range(0, 6)
                        .mapToObj(stage -> Pair.of(stage, axis)))
                .collect(Collectors.toList());
 
Последнее редактирование:
5,018
47
783
Вопрос был решен, но как - вы возможно узнаете завтра :)
Лучшим из всех ответов, а также за помощь в лс, назначаю @hohserg1
 
Сверху