Реализация труб

Версия Minecraft
1.11.2
1,015
9
102
Как сделать трубы, как в buildcraft? А именно в плане модельки, в зависимости от соседних труб. Я конечно могу наклипать все вариации моделей и каждую засунуть под свою метадату, и определять эту метадату по соседним блокам. Есть ли вариант по-проще? Например, можно ли как-нибудь самому рендрить полигоны и текстуры в блоке?
 
Решение
Blockstates.json
Код:
{
  "variants": {
   "barrel=false,spigot=false": { "model": "fm:stand" },
    "barrel=true,spigot=false": { "model": "fm:stand_barrel" },
    "barrel=true,spigot=true,": { "model": "fm:stand_barrel_spigot" }
  }
}
Код стенда:
Код:
public static final PropertyBool 
 BARREL = PropertyBool.create("barrel"), 
 SPIGOT = PropertyBool.create("spigot");

public Constructor()
{
 this.setDefaultState(this.blockState.getBaseState().withProperty(BARREL, false).withProperty(SPIGOT, false));
}

/**
 * Данный метод будет срабатывать при обновлении блока.
 */
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos)
{
 //У меня здесь есть проверка на то, что есть...
1,015
9
102
Ivasik написал(а):
Блокстайты и метод гетактуалстате. Можешь глянуть загрузочную воронку.
И как его использовать? Кстати он @Deprecated, и в воронке уже не юзается. В каждый стейт отдельную модель пихать, или как?
 
3,005
192
592
Код не мой, код с автор правами, дальнейшее использование - сами знаете что будет.
Код:
public class BlockConnectedTexture extends Block {
    
    public static final PropertyBool CONNECTED_DOWN = PropertyBool.create("connected_down");
    public static final PropertyBool CONNECTED_UP = PropertyBool.create("connected_up");
    public static final PropertyBool CONNECTED_NORTH = PropertyBool.create("connected_north");
    public static final PropertyBool CONNECTED_SOUTH = PropertyBool.create("connected_south");
    public static final PropertyBool CONNECTED_WEST = PropertyBool.create("connected_west");
    public static final PropertyBool CONNECTED_EAST = PropertyBool.create("connected_east");
    
    public BlockConnectedTexture(Material material) {
        
      super(material);
      this.setDefaultState(this.blockState.getBaseState()
                                          .withProperty(CONNECTED_DOWN, Boolean.FALSE)
                                          .withProperty(CONNECTED_EAST, Boolean.FALSE)
                                          .withProperty(CONNECTED_NORTH, Boolean.FALSE)
                                          .withProperty(CONNECTED_SOUTH, Boolean.FALSE)
                                          .withProperty(CONNECTED_UP, Boolean.FALSE)
                                          .withProperty(CONNECTED_WEST, Boolean.FALSE));
    }
    
    @Override
    public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos position) {
      return state.withProperty(CONNECTED_DOWN,  this.isSideConnectable(world, position, EnumFacing.DOWN))
                  .withProperty(CONNECTED_EAST,  this.isSideConnectable(world, position, EnumFacing.EAST))
                  .withProperty(CONNECTED_NORTH, this.isSideConnectable(world, position, EnumFacing.NORTH))
                  .withProperty(CONNECTED_SOUTH, this.isSideConnectable(world, position, EnumFacing.SOUTH))
                  .withProperty(CONNECTED_UP,    this.isSideConnectable(world, position, EnumFacing.UP))
                  .withProperty(CONNECTED_WEST,  this.isSideConnectable(world, position, EnumFacing.WEST));
    }

    @Nonnull
    @Override
    protected BlockStateContainer createBlockState() {
      return new BlockStateContainer(this, new IProperty[] { CONNECTED_DOWN, CONNECTED_UP, CONNECTED_NORTH, CONNECTED_SOUTH, CONNECTED_WEST, CONNECTED_EAST });
    }
    
    @Override
    public int getMetaFromState(IBlockState state) {
      return 0;
    }
    
    private boolean isSideConnectable(IBlockAccess world, BlockPos pos, EnumFacing side) {
      final IBlockState original = world.getBlockState(pos);
      final IBlockState connected = world.getBlockState(pos.offset(side));

      return original != null && connected != null && canConnect(original, connected);
    }
    
    protected boolean canConnect(@Nonnull IBlockState original, @Nonnull IBlockState connected) {
      return original.getBlock() == connected.getBlock();
    }
}

Код:
public class BlockClearGlass extends BlockConnectedTexture {

  public BlockClearGlass() {
    super(Material.GLASS);

    this.setHardness(0.3f);
    setHarvestLevel("pickaxe", -1);
    this.setSoundType(SoundType.GLASS);

    this.setCreativeTab(CreativeTabs.REDSTONE);
  }
  @Nonnull
  @Override
  @SideOnly(Side.CLIENT)
  public BlockRenderLayer getBlockLayer() {
    return BlockRenderLayer.CUTOUT;
  }

  @Override
  public boolean isFullCube(IBlockState state) {
    return false;
  }

  @Override
  public boolean isOpaqueCube(IBlockState state) {
    return false;
  }
}
 
1,015
9
102
Doc написал(а):
Код не мой, код с автор правами, дальнейшее использование - сами знаете что будет.
Код:
public class BlockConnectedTexture extends Block {
    
    public static final PropertyBool CONNECTED_DOWN = PropertyBool.create("connected_down");
    public static final PropertyBool CONNECTED_UP = PropertyBool.create("connected_up");
    public static final PropertyBool CONNECTED_NORTH = PropertyBool.create("connected_north");
    public static final PropertyBool CONNECTED_SOUTH = PropertyBool.create("connected_south");
    public static final PropertyBool CONNECTED_WEST = PropertyBool.create("connected_west");
    public static final PropertyBool CONNECTED_EAST = PropertyBool.create("connected_east");
    
    public BlockConnectedTexture(Material material) {
        
      super(material);
      this.setDefaultState(this.blockState.getBaseState()
                                          .withProperty(CONNECTED_DOWN, Boolean.FALSE)
                                          .withProperty(CONNECTED_EAST, Boolean.FALSE)
                                          .withProperty(CONNECTED_NORTH, Boolean.FALSE)
                                          .withProperty(CONNECTED_SOUTH, Boolean.FALSE)
                                          .withProperty(CONNECTED_UP, Boolean.FALSE)
                                          .withProperty(CONNECTED_WEST, Boolean.FALSE));
    }
    
    @Override
    public IBlockState getActualState(IBlockState state, IBlockAccess world, BlockPos position) {
      return state.withProperty(CONNECTED_DOWN,  this.isSideConnectable(world, position, EnumFacing.DOWN))
                  .withProperty(CONNECTED_EAST,  this.isSideConnectable(world, position, EnumFacing.EAST))
                  .withProperty(CONNECTED_NORTH, this.isSideConnectable(world, position, EnumFacing.NORTH))
                  .withProperty(CONNECTED_SOUTH, this.isSideConnectable(world, position, EnumFacing.SOUTH))
                  .withProperty(CONNECTED_UP,    this.isSideConnectable(world, position, EnumFacing.UP))
                  .withProperty(CONNECTED_WEST,  this.isSideConnectable(world, position, EnumFacing.WEST));
    }

    @Nonnull
    @Override
    protected BlockStateContainer createBlockState() {
      return new BlockStateContainer(this, new IProperty[] { CONNECTED_DOWN, CONNECTED_UP, CONNECTED_NORTH, CONNECTED_SOUTH, CONNECTED_WEST, CONNECTED_EAST });
    }
    
    @Override
    public int getMetaFromState(IBlockState state) {
      return 0;
    }
    
    private boolean isSideConnectable(IBlockAccess world, BlockPos pos, EnumFacing side) {
      final IBlockState original = world.getBlockState(pos);
      final IBlockState connected = world.getBlockState(pos.offset(side));

      return original != null && connected != null && canConnect(original, connected);
    }
    
    protected boolean canConnect(@Nonnull IBlockState original, @Nonnull IBlockState connected) {
      return original.getBlock() == connected.getBlock();
    }
}

Код:
public class BlockClearGlass extends BlockConnectedTexture {

  public BlockClearGlass() {
    super(Material.GLASS);

    this.setHardness(0.3f);
    setHarvestLevel("pickaxe", -1);
    this.setSoundType(SoundType.GLASS);

    this.setCreativeTab(CreativeTabs.REDSTONE);
  }
  @Nonnull
  @Override
  @SideOnly(Side.CLIENT)
  public BlockRenderLayer getBlockLayer() {
    return BlockRenderLayer.CUTOUT;
  }

  @Override
  public boolean isFullCube(IBlockState state) {
    return false;
  }

  @Override
  public boolean isOpaqueCube(IBlockState state) {
    return false;
  }
}

С кодом то понятно, мне бы пример с json. Я прост не до конца догоняю, как использовать больше одного property. Да и вообще, интересно, как лучше его реализовать
 

Icosider

Kotliner
Администратор
3,603
99
664
Blockstates.json
Код:
{
  "variants": {
   "barrel=false,spigot=false": { "model": "fm:stand" },
    "barrel=true,spigot=false": { "model": "fm:stand_barrel" },
    "barrel=true,spigot=true,": { "model": "fm:stand_barrel_spigot" }
  }
}
Код стенда:
Код:
public static final PropertyBool 
 BARREL = PropertyBool.create("barrel"), 
 SPIGOT = PropertyBool.create("spigot");

public Constructor()
{
 this.setDefaultState(this.blockState.getBaseState().withProperty(BARREL, false).withProperty(SPIGOT, false));
}

/**
 * Данный метод будет срабатывать при обновлении блока.
 */
@Override
public IBlockState getActualState(IBlockState state, IBlockAccess worldIn, BlockPos pos)
{
 //У меня здесь есть проверка на то, что есть блок над стендом.
    Block block = worldIn.getBlockState(pos.up()).getBlock();
    return state.withProperty(UPPER, Boolean.valueOf(block != Blocks.AIR));
}

@Override
protected BlockStateContainer createBlockState()
{
    return new BlockStateContainer(this, new IProperty[] {BARREL, SPIGOT});
}

/**
 * Получаем стейты из метадаты
 */
@Override
public IBlockState getStateFromMeta(int meta)
{
 //Здесь происходит побитовое вычисление
    return this.getDefaultState().withProperty(BARREL, Boolean.valueOf((meta & 8) > 0)).withProperty(SPIGOT, Boolean.valueOf((meta & 4) > 0));
}

/**
 * Получаем метадату из стейтов
 */
@Override
public int getMetaFromState(IBlockState state)
{
    int i = 0;

    if(state.getValue(BARREL).booleanValue())
    {
        i |= 8;
    }

    if(state.getValue(SPIGOT).booleanValue())
    {
        i |= 4;
    }

    return i;
}

/**
 *  Если хочешь внутри блока менять что либо(изменять стейты), то юзай такой способо:
 */
world.setBlockState(pos, state.withProperty(SPIGOT, false), 4);
 
1,015
9
102
Ivasik написал(а):

А свой рендер? По полигоном будет проще


Можно же отрисовывать центр трубы, дальше перебирать всех соседей вокруг, если это тоже трубы, то в соответствующую сторону отрисовать ответвление от центра. Эт ж возможно в коде как-то реализовать?
 
699
9
53
Minebot написал(а):
Ivasik написал(а):

А свой рендер? По полигоном будет проще


Можно же отрисовывать центр трубы, дальше перебирать всех соседей вокруг, если это тоже трубы, то в соответствующую сторону отрисовать ответвление от центра. Эт ж возможно в коде как-то реализовать?


Чекни другие моды на трубы декомпилятором.
 
Сверху