Add facade support, allows covering bus cables with other blocks.
This commit is contained in:
@@ -2,12 +2,17 @@ package li.cil.oc2.client.model;
|
||||
|
||||
import li.cil.oc2.common.Constants;
|
||||
import li.cil.oc2.common.block.BusCableBlock;
|
||||
import li.cil.oc2.common.tileentity.BusCableTileEntity;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.BlockModelShapes;
|
||||
import net.minecraft.client.renderer.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.model.ItemOverrideList;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockDisplayReader;
|
||||
@@ -16,12 +21,17 @@ import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.data.ModelDataMap;
|
||||
import net.minecraftforge.client.model.data.ModelProperty;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
public final class BusCableBakedModel implements IDynamicBakedModel {
|
||||
private static final ModelProperty<BusCableSupportSide> BUS_CABLE_SUPPORT_PROPERTY = new ModelProperty<>();
|
||||
private static final ModelProperty<BusCableFacade> BUS_CABLE_FACADE_PROPERTY = new ModelProperty<>();
|
||||
|
||||
private final IBakedModel proxy;
|
||||
private final IBakedModel[] straightModelByAxis;
|
||||
private final IBakedModel[] supportModelByFace;
|
||||
@@ -37,9 +47,15 @@ public final class BusCableBakedModel implements IDynamicBakedModel {
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public List<BakedQuad> getQuads(@Nullable final BlockState state, @Nullable final Direction side, final Random rand, final IModelData extraData) {
|
||||
if (extraData.hasProperty(BUS_CABLE_FACADE_PROPERTY)) {
|
||||
final BusCableFacade facade = extraData.getData(BUS_CABLE_FACADE_PROPERTY);
|
||||
return facade.model.getQuads(facade.blockState, side, rand, facade.data);
|
||||
}
|
||||
|
||||
if (state == null || !state.getValue(BusCableBlock.HAS_CABLE)) {
|
||||
return proxy.getQuads(null, side, rand, extraData);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
for (int i = 0; i < Constants.AXES.length; i++) {
|
||||
@@ -51,9 +67,9 @@ public final class BusCableBakedModel implements IDynamicBakedModel {
|
||||
|
||||
final ArrayList<BakedQuad> quads = new ArrayList<>(proxy.getQuads(state, side, rand, extraData));
|
||||
|
||||
final BusCableSupportSide supportSide = extraData.getData(BusCableSupportSide.BUS_CABLE_SUPPORT_PROPERTY);
|
||||
final BusCableSupportSide supportSide = extraData.getData(BUS_CABLE_SUPPORT_PROPERTY);
|
||||
if (supportSide != null) {
|
||||
quads.addAll(supportModelByFace[supportSide.get().get3DDataValue()].getQuads(state, side, rand, extraData));
|
||||
quads.addAll(supportModelByFace[supportSide.value.get3DDataValue()].getQuads(state, side, rand, extraData));
|
||||
}
|
||||
|
||||
return quads;
|
||||
@@ -69,7 +85,6 @@ public final class BusCableBakedModel implements IDynamicBakedModel {
|
||||
return proxy.isGui3d();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean usesBlockLight() {
|
||||
return proxy.usesBlockLight();
|
||||
@@ -80,6 +95,7 @@ public final class BusCableBakedModel implements IDynamicBakedModel {
|
||||
return proxy.isCustomRenderer();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleIcon() {
|
||||
return proxy.getParticleIcon();
|
||||
@@ -91,7 +107,26 @@ public final class BusCableBakedModel implements IDynamicBakedModel {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public IModelData getModelData(final IBlockDisplayReader world, final BlockPos pos, final BlockState state, final IModelData tileData) {
|
||||
if (state.hasProperty(BusCableBlock.HAS_FACADE) && state.getValue(BusCableBlock.HAS_FACADE)) {
|
||||
final TileEntity tileEntity = world.getBlockEntity(pos);
|
||||
final BlockState facadeState;
|
||||
if (tileEntity instanceof BusCableTileEntity && ((BusCableTileEntity) tileEntity).hasFacade()) {
|
||||
facadeState = ((BusCableTileEntity) tileEntity).getFacade();
|
||||
} else {
|
||||
facadeState = Blocks.IRON_BLOCK.defaultBlockState();
|
||||
}
|
||||
|
||||
final BlockModelShapes shapes = Minecraft.getInstance().getBlockRenderer().getBlockModelShaper();
|
||||
final IBakedModel model = shapes.getBlockModel(facadeState);
|
||||
final IModelData data = model.getModelData(world, pos, facadeState, tileData);
|
||||
|
||||
return new ModelDataMap.Builder()
|
||||
.withInitial(BUS_CABLE_FACADE_PROPERTY, new BusCableFacade(facadeState, model, data))
|
||||
.build();
|
||||
}
|
||||
|
||||
Direction supportSide = null;
|
||||
for (final Direction direction : Constants.DIRECTIONS) {
|
||||
if (isNeighborInDirectionSolid(world, pos, direction)) {
|
||||
@@ -108,7 +143,7 @@ public final class BusCableBakedModel implements IDynamicBakedModel {
|
||||
|
||||
if (supportSide != null) {
|
||||
return new ModelDataMap.Builder()
|
||||
.withInitial(BusCableSupportSide.BUS_CABLE_SUPPORT_PROPERTY, new BusCableSupportSide(supportSide))
|
||||
.withInitial(BUS_CABLE_SUPPORT_PROPERTY, new BusCableSupportSide(supportSide))
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -141,17 +176,23 @@ public final class BusCableBakedModel implements IDynamicBakedModel {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static final class BusCableSupportSide {
|
||||
public static final ModelProperty<BusCableSupportSide> BUS_CABLE_SUPPORT_PROPERTY = new ModelProperty<>();
|
||||
|
||||
private final Direction value;
|
||||
private static final class BusCableSupportSide {
|
||||
public final Direction value;
|
||||
|
||||
private BusCableSupportSide(final Direction value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
public Direction get() {
|
||||
return value;
|
||||
private static final class BusCableFacade {
|
||||
public final BlockState blockState;
|
||||
public final IBakedModel model;
|
||||
public final IModelData data;
|
||||
|
||||
public BusCableFacade(final BlockState blockState, final IBakedModel model, final IModelData data) {
|
||||
this.blockState = blockState;
|
||||
this.model = model;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,8 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static li.cil.oc2.common.util.TranslationUtils.text;
|
||||
|
||||
public final class BusCableBlock extends Block {
|
||||
public enum ConnectionType implements IStringSerializable {
|
||||
NONE,
|
||||
@@ -69,6 +71,7 @@ public final class BusCableBlock extends Block {
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static final BooleanProperty HAS_CABLE = BooleanProperty.create("has_cable");
|
||||
public static final BooleanProperty HAS_FACADE = BooleanProperty.create("has_facade");
|
||||
public static final EnumProperty<ConnectionType> CONNECTION_NORTH = EnumProperty.create("connection_north", ConnectionType.class);
|
||||
public static final EnumProperty<ConnectionType> CONNECTION_EAST = EnumProperty.create("connection_east", ConnectionType.class);
|
||||
public static final EnumProperty<ConnectionType> CONNECTION_SOUTH = EnumProperty.create("connection_south", ConnectionType.class);
|
||||
@@ -125,6 +128,7 @@ public final class BusCableBlock extends Block {
|
||||
defaultState = defaultState.setValue(property, ConnectionType.NONE);
|
||||
}
|
||||
defaultState = defaultState.setValue(HAS_CABLE, true);
|
||||
defaultState = defaultState.setValue(HAS_FACADE, false);
|
||||
registerDefaultState(defaultState);
|
||||
|
||||
shapes = makeShapes();
|
||||
@@ -132,7 +136,15 @@ public final class BusCableBlock extends Block {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public boolean addInterface(final World world, final BlockPos pos, final BlockState state, final Direction side) {
|
||||
public static boolean addInterface(final World world, final BlockPos pos, final BlockState state, final Direction side) {
|
||||
if (state.getBlock() != Blocks.BUS_CABLE.get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (state.getValue(HAS_FACADE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final EnumProperty<BusCableBlock.ConnectionType> property = FACING_TO_CONNECTION_MAP.get(side);
|
||||
if (state.getValue(property) != ConnectionType.NONE) {
|
||||
return false;
|
||||
@@ -145,7 +157,11 @@ public final class BusCableBlock extends Block {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean addCable(final World world, final BlockPos pos, final BlockState state) {
|
||||
public static boolean addCable(final World world, final BlockPos pos, final BlockState state) {
|
||||
if (state.getBlock() != Blocks.BUS_CABLE.get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (state.getValue(HAS_CABLE)) {
|
||||
return false;
|
||||
}
|
||||
@@ -157,6 +173,16 @@ public final class BusCableBlock extends Block {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void setHasFacade(final World world, final BlockPos pos, final BlockState state, final boolean value) {
|
||||
if (state.getValue(HAS_FACADE) == value) {
|
||||
return;
|
||||
}
|
||||
|
||||
world.setBlock(pos, state.setValue(HAS_FACADE, value), BlockFlags.DEFAULT_AND_RERENDER);
|
||||
|
||||
WorldUtils.playSound(world, pos, state.getSoundType(), value ? SoundType::getPlaceSound : SoundType::getBreakSound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasTileEntity(final BlockState state) {
|
||||
return true;
|
||||
@@ -180,26 +206,48 @@ public final class BusCableBlock extends Block {
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public ActionResultType use(final BlockState state, final World world, final BlockPos pos, final PlayerEntity player, final Hand hand, final BlockRayTraceResult hit) {
|
||||
if (Wrenches.isWrench(player.getItemInHand(hand))) {
|
||||
if (player.isShiftKeyDown()) {
|
||||
// NB: leave wrenching logic up to wrench when the to-be-removed interface is the last
|
||||
// part of this bus. This ensures we properly remove the block itself without having
|
||||
// to duplicate the logic needed for that.
|
||||
if (getPartCount(state) > 1)
|
||||
if (tryRemovePlug(state, world, pos, player, hit) || tryRemoveCable(state, world, pos, player)) {
|
||||
return ActionResultType.sidedSuccess(world.isClientSide);
|
||||
}
|
||||
} else {
|
||||
final TileEntity tileEntity = world.getBlockEntity(pos);
|
||||
if (tileEntity instanceof BusCableTileEntity) {
|
||||
final BusCableTileEntity busCableTileEntity = (BusCableTileEntity) tileEntity;
|
||||
final ItemStack heldItem = player.getItemInHand(hand);
|
||||
if (heldItem.getItem() == Items.BUS_CABLE.get() ||
|
||||
heldItem.getItem() == Items.BUS_INTERFACE.get()) {
|
||||
return ActionResultType.PASS;
|
||||
}
|
||||
|
||||
final Direction side = getHitSide(pos, hit);
|
||||
if (getConnectionType(state, side) == ConnectionType.INTERFACE) {
|
||||
openBusInterfaceScreen(busCableTileEntity, side);
|
||||
final TileEntity tileEntity = world.getBlockEntity(pos);
|
||||
if (!(tileEntity instanceof BusCableTileEntity)) {
|
||||
return super.use(state, world, pos, player, hand, hit);
|
||||
}
|
||||
|
||||
final BusCableTileEntity busCableTileEntity = (BusCableTileEntity) tileEntity;
|
||||
|
||||
if (Wrenches.isWrench(heldItem)) {
|
||||
if (player.isShiftKeyDown()) {
|
||||
if (busCableTileEntity.hasFacade()) {
|
||||
busCableTileEntity.removeFacade();
|
||||
return ActionResultType.sidedSuccess(world.isClientSide);
|
||||
} else {
|
||||
// NB: leave wrenching logic up to wrench when the to-be-removed interface is the last
|
||||
// part of this bus. This ensures we properly remove the block itself without having
|
||||
// to duplicate the logic needed for that.
|
||||
if (getPartCount(state) > 1 && (tryRemovePlug(state, world, pos, player, hit) || tryRemoveCable(state, world, pos, player))) {
|
||||
return ActionResultType.sidedSuccess(world.isClientSide);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
final Direction side = getHitSide(pos, hit);
|
||||
if (getConnectionType(state, side) == ConnectionType.INTERFACE) {
|
||||
openBusInterfaceScreen(busCableTileEntity, side);
|
||||
return ActionResultType.sidedSuccess(world.isClientSide);
|
||||
}
|
||||
}
|
||||
} else if (getInterfaceCount(state) == 0 && !player.isShiftKeyDown()) {
|
||||
final BlockState blockState = ItemStackUtils.getBlockState(heldItem);
|
||||
if (blockState != null) {
|
||||
if (!busCableTileEntity.trySetFacade(blockState) && !world.isClientSide()) {
|
||||
player.displayClientMessage(text("message.{mod}.invalid_facade_block"), true);
|
||||
}
|
||||
|
||||
// Always return success (even on failure) to avoid accidentally placing blocks.
|
||||
return ActionResultType.sidedSuccess(world.isClientSide);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,6 +317,10 @@ public final class BusCableBlock extends Block {
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public VoxelShape getShape(final BlockState state, final IBlockReader world, final BlockPos pos, final ISelectionContext context) {
|
||||
if (state.getValue(HAS_FACADE)) {
|
||||
return VoxelShapes.block();
|
||||
}
|
||||
|
||||
return shapes[getShapeIndex(state)];
|
||||
}
|
||||
|
||||
@@ -279,6 +331,7 @@ public final class BusCableBlock extends Block {
|
||||
super.createBlockStateDefinition(builder);
|
||||
FACING_TO_CONNECTION_MAP.values().forEach(builder::add);
|
||||
builder.add(HAS_CABLE);
|
||||
builder.add(HAS_FACADE);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package li.cil.oc2.common.item;
|
||||
|
||||
import li.cil.oc2.common.Config;
|
||||
import li.cil.oc2.common.block.Blocks;
|
||||
import li.cil.oc2.common.block.BusCableBlock;
|
||||
import li.cil.oc2.common.util.TooltipUtils;
|
||||
import li.cil.oc2.common.util.WorldUtils;
|
||||
@@ -53,14 +52,12 @@ public final class BusCableItem extends ModBlockItem {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private ActionResultType tryAddToBlock(final ItemUseContext context) {
|
||||
final BusCableBlock busCableBlock = Blocks.BUS_CABLE.get();
|
||||
|
||||
private static ActionResultType tryAddToBlock(final ItemUseContext context) {
|
||||
final World world = context.getLevel();
|
||||
final BlockPos pos = context.getClickedPos();
|
||||
final BlockState state = world.getBlockState(pos);
|
||||
|
||||
if (state.getBlock() == busCableBlock && busCableBlock.addCable(world, pos, state)) {
|
||||
if (BusCableBlock.addCable(world, pos, state)) {
|
||||
final PlayerEntity player = context.getPlayer();
|
||||
final ItemStack stack = context.getItemInHand();
|
||||
|
||||
|
||||
@@ -93,14 +93,12 @@ public final class BusInterfaceItem extends ModBlockItem {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private ActionResultType tryAddToBlock(final ItemUseContext context, final Direction side) {
|
||||
final BusCableBlock busCableBlock = Blocks.BUS_CABLE.get();
|
||||
|
||||
private static ActionResultType tryAddToBlock(final ItemUseContext context, final Direction side) {
|
||||
final World world = context.getLevel();
|
||||
final BlockPos pos = context.getClickedPos();
|
||||
final BlockState state = world.getBlockState(pos);
|
||||
|
||||
if (state.getBlock() == busCableBlock && busCableBlock.addInterface(world, pos, state, side)) {
|
||||
if (BusCableBlock.addInterface(world, pos, state, side)) {
|
||||
final PlayerEntity player = context.getPlayer();
|
||||
final ItemStack stack = context.getItemInHand();
|
||||
|
||||
|
||||
@@ -10,9 +10,12 @@ import li.cil.oc2.common.capabilities.Capabilities;
|
||||
import li.cil.oc2.common.network.Network;
|
||||
import li.cil.oc2.common.network.message.BusInterfaceNameMessage;
|
||||
import li.cil.oc2.common.util.NBTTagIds;
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.nbt.ListNBT;
|
||||
import net.minecraft.nbt.NBTUtil;
|
||||
import net.minecraft.nbt.StringNBT;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.StringUtils;
|
||||
@@ -26,11 +29,13 @@ import java.util.Objects;
|
||||
public final class BusCableTileEntity extends AbstractTileEntity {
|
||||
private static final String BUS_ELEMENT_TAG_NAME = "busElement";
|
||||
private static final String INTERFACE_NAMES_TAG_NAME = "interfaceNames";
|
||||
private static final String FACADE_TAG_NAME = "facade";
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private final TileEntityDeviceBusElement busElement = new BusCableBusElement();
|
||||
private final String[] interfaceNames = new String[Constants.BLOCK_FACE_COUNT];
|
||||
private BlockState facade = Blocks.AIR.defaultBlockState();
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -59,6 +64,38 @@ public final class BusCableTileEntity extends AbstractTileEntity {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasFacade() {
|
||||
return getFacade() != Blocks.AIR.defaultBlockState();
|
||||
}
|
||||
|
||||
public BlockState getFacade() {
|
||||
return facade;
|
||||
}
|
||||
|
||||
public boolean trySetFacade(final BlockState state) {
|
||||
if (!trySetFacadeWithoutUpdate(state)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!getLevel().isClientSide()) {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
BusCableBlock.setHasFacade(getLevel(), getBlockPos(), getBlockState(), true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void removeFacade() {
|
||||
facade = Blocks.AIR.defaultBlockState();
|
||||
|
||||
if (!getLevel().isClientSide()) {
|
||||
setChanged();
|
||||
}
|
||||
|
||||
BusCableBlock.setHasFacade(getLevel(), getBlockPos(), getBlockState(), false);
|
||||
}
|
||||
|
||||
public void handleNeighborChanged(final BlockPos pos) {
|
||||
busElement.handleNeighborChanged(pos);
|
||||
}
|
||||
@@ -92,6 +129,7 @@ public final class BusCableTileEntity extends AbstractTileEntity {
|
||||
final CompoundNBT tag = super.getUpdateTag();
|
||||
|
||||
tag.put(INTERFACE_NAMES_TAG_NAME, serializeInterfaceNames());
|
||||
tag.put(FACADE_TAG_NAME, NBTUtil.writeBlockState(facade));
|
||||
|
||||
return tag;
|
||||
}
|
||||
@@ -99,6 +137,7 @@ public final class BusCableTileEntity extends AbstractTileEntity {
|
||||
@Override
|
||||
public void handleUpdateTag(final BlockState state, final CompoundNBT tag) {
|
||||
deserializeInterfaceNames(tag.getList(INTERFACE_NAMES_TAG_NAME, NBTTagIds.TAG_STRING));
|
||||
trySetFacade(NBTUtil.readBlockState(tag.getCompound(FACADE_TAG_NAME)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,6 +145,7 @@ public final class BusCableTileEntity extends AbstractTileEntity {
|
||||
tag = super.save(tag);
|
||||
tag.put(BUS_ELEMENT_TAG_NAME, busElement.save());
|
||||
tag.put(INTERFACE_NAMES_TAG_NAME, serializeInterfaceNames());
|
||||
tag.put(FACADE_TAG_NAME, NBTUtil.writeBlockState(facade));
|
||||
|
||||
return tag;
|
||||
}
|
||||
@@ -115,6 +155,7 @@ public final class BusCableTileEntity extends AbstractTileEntity {
|
||||
super.load(state, tag);
|
||||
busElement.load(tag.getList(BUS_ELEMENT_TAG_NAME, NBTTagIds.TAG_COMPOUND));
|
||||
deserializeInterfaceNames(tag.getList(INTERFACE_NAMES_TAG_NAME, NBTTagIds.TAG_STRING));
|
||||
trySetFacadeWithoutUpdate(NBTUtil.readBlockState(tag.getCompound(FACADE_TAG_NAME)));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
@@ -135,6 +176,18 @@ public final class BusCableTileEntity extends AbstractTileEntity {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private boolean trySetFacadeWithoutUpdate(final BlockState state) {
|
||||
if (state.getRenderShape() != BlockRenderType.MODEL ||
|
||||
!state.isSolidRender(getLevel(), getBlockPos()) ||
|
||||
state.getBlock().hasTileEntity(state)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
facade = state;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private ListNBT serializeInterfaceNames() {
|
||||
final ListNBT tag = new ListNBT();
|
||||
for (int i = 0; i < Constants.BLOCK_FACE_COUNT; i++) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package li.cil.oc2.common.util;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
@@ -23,6 +25,20 @@ public final class ItemStackUtils {
|
||||
return NBTUtils.getOrCreateChildTag(stack.getOrCreateTag(), MOD_TAG_NAME);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static BlockState getBlockState(final ItemStack stack) {
|
||||
if (stack.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Block block = Block.byItem(stack.getItem());
|
||||
if (block == null || block == net.minecraft.block.Blocks.AIR) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return block.defaultBlockState();
|
||||
}
|
||||
|
||||
public static Optional<ItemEntity> spawnAsEntity(final World world, final BlockPos pos, final ItemStack stack) {
|
||||
return spawnAsEntity(world, Vector3d.atCenterOf(pos), stack);
|
||||
}
|
||||
|
||||
@@ -63,12 +63,11 @@ public class ModBlockStateProvider extends BlockStateProvider {
|
||||
final MultiPartBlockStateBuilder builder = getMultipartBuilder(Blocks.BUS_CABLE.get());
|
||||
|
||||
// NB: We use a custom model loader + baked model to replace the base part with straight parts and
|
||||
// insert supports where appropriate.
|
||||
// insert supports where appropriate, as well as for replacing it with a facade block model.
|
||||
|
||||
builder.part()
|
||||
.modelFile(baseModel)
|
||||
.addModel()
|
||||
.condition(BusCableBlock.HAS_CABLE, true)
|
||||
.end();
|
||||
|
||||
BusCableBlock.FACING_TO_CONNECTION_MAP.forEach((direction, connectionType) -> {
|
||||
@@ -88,6 +87,7 @@ public class ModBlockStateProvider extends BlockStateProvider {
|
||||
.rotationX(rotationX)
|
||||
.addModel()
|
||||
.condition(connectionType, BusCableBlock.ConnectionType.CABLE)
|
||||
.condition(BusCableBlock.HAS_FACADE, false)
|
||||
.end();
|
||||
|
||||
builder.part()
|
||||
@@ -96,6 +96,7 @@ public class ModBlockStateProvider extends BlockStateProvider {
|
||||
.rotationX(rotationX)
|
||||
.addModel()
|
||||
.condition(connectionType, BusCableBlock.ConnectionType.INTERFACE)
|
||||
.condition(BusCableBlock.HAS_FACADE, false)
|
||||
.end();
|
||||
});
|
||||
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
{
|
||||
"multipart": [
|
||||
{
|
||||
"when": {
|
||||
"has_cable": "true"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_base"
|
||||
}
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_down": "cable"
|
||||
"connection_down": "cable",
|
||||
"has_facade": "false"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_link",
|
||||
@@ -20,7 +18,8 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_down": "interface"
|
||||
"connection_down": "interface",
|
||||
"has_facade": "false"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_plug",
|
||||
@@ -30,7 +29,8 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_up": "cable"
|
||||
"connection_up": "cable",
|
||||
"has_facade": "false"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_link",
|
||||
@@ -40,7 +40,8 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_up": "interface"
|
||||
"connection_up": "interface",
|
||||
"has_facade": "false"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_plug",
|
||||
@@ -50,7 +51,8 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_north": "cable"
|
||||
"connection_north": "cable",
|
||||
"has_facade": "false"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_link",
|
||||
@@ -59,7 +61,8 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_north": "interface"
|
||||
"connection_north": "interface",
|
||||
"has_facade": "false"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_plug",
|
||||
@@ -68,7 +71,8 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_south": "cable"
|
||||
"connection_south": "cable",
|
||||
"has_facade": "false"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_link"
|
||||
@@ -76,7 +80,8 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_south": "interface"
|
||||
"connection_south": "interface",
|
||||
"has_facade": "false"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_plug"
|
||||
@@ -84,7 +89,8 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_west": "cable"
|
||||
"connection_west": "cable",
|
||||
"has_facade": "false"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_link",
|
||||
@@ -93,7 +99,8 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_west": "interface"
|
||||
"connection_west": "interface",
|
||||
"has_facade": "false"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_plug",
|
||||
@@ -102,7 +109,8 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_east": "cable"
|
||||
"connection_east": "cable",
|
||||
"has_facade": "false"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_link",
|
||||
@@ -111,7 +119,8 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_east": "interface"
|
||||
"connection_east": "interface",
|
||||
"has_facade": "false"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_plug",
|
||||
|
||||
@@ -75,6 +75,7 @@
|
||||
"message.oc2.connector.error.too_far": "Distance between connectors is too large.",
|
||||
"message.oc2.connector.error.obstructed": "No clear line of sight between connectors.",
|
||||
"message.oc2.import_file.file_too_large": "File is too large.",
|
||||
"message.oc2.invalid_facade_block": "This block cannot be used as a facade.",
|
||||
|
||||
"tooltip.oc2.device_needs_reboot": "Requires reboot",
|
||||
"tooltip.oc2.flash_memory_missing": "A flash memory containing a firmware is required to boot.",
|
||||
|
||||
Reference in New Issue
Block a user