diff --git a/src/main/java/li/cil/oc2/client/model/BusCableBakedModel.java b/src/main/java/li/cil/oc2/client/model/BusCableBakedModel.java index 0a54d8f8..ac844e1d 100644 --- a/src/main/java/li/cil/oc2/client/model/BusCableBakedModel.java +++ b/src/main/java/li/cil/oc2/client/model/BusCableBakedModel.java @@ -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 BUS_CABLE_SUPPORT_PROPERTY = new ModelProperty<>(); + private static final ModelProperty 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 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 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 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; } } } diff --git a/src/main/java/li/cil/oc2/common/block/BusCableBlock.java b/src/main/java/li/cil/oc2/common/block/BusCableBlock.java index 882af933..dd0c9a43 100644 --- a/src/main/java/li/cil/oc2/common/block/BusCableBlock.java +++ b/src/main/java/li/cil/oc2/common/block/BusCableBlock.java @@ -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 CONNECTION_NORTH = EnumProperty.create("connection_north", ConnectionType.class); public static final EnumProperty CONNECTION_EAST = EnumProperty.create("connection_east", ConnectionType.class); public static final EnumProperty 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 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); } /////////////////////////////////////////////////////////////////// diff --git a/src/main/java/li/cil/oc2/common/item/BusCableItem.java b/src/main/java/li/cil/oc2/common/item/BusCableItem.java index f7f6bf02..8f72acf5 100644 --- a/src/main/java/li/cil/oc2/common/item/BusCableItem.java +++ b/src/main/java/li/cil/oc2/common/item/BusCableItem.java @@ -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(); diff --git a/src/main/java/li/cil/oc2/common/item/BusInterfaceItem.java b/src/main/java/li/cil/oc2/common/item/BusInterfaceItem.java index 1ebc666f..1dff528a 100644 --- a/src/main/java/li/cil/oc2/common/item/BusInterfaceItem.java +++ b/src/main/java/li/cil/oc2/common/item/BusInterfaceItem.java @@ -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(); diff --git a/src/main/java/li/cil/oc2/common/tileentity/BusCableTileEntity.java b/src/main/java/li/cil/oc2/common/tileentity/BusCableTileEntity.java index 18f1b908..1a918048 100644 --- a/src/main/java/li/cil/oc2/common/tileentity/BusCableTileEntity.java +++ b/src/main/java/li/cil/oc2/common/tileentity/BusCableTileEntity.java @@ -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++) { diff --git a/src/main/java/li/cil/oc2/common/util/ItemStackUtils.java b/src/main/java/li/cil/oc2/common/util/ItemStackUtils.java index 223ffae8..6bbba65f 100644 --- a/src/main/java/li/cil/oc2/common/util/ItemStackUtils.java +++ b/src/main/java/li/cil/oc2/common/util/ItemStackUtils.java @@ -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 spawnAsEntity(final World world, final BlockPos pos, final ItemStack stack) { return spawnAsEntity(world, Vector3d.atCenterOf(pos), stack); } diff --git a/src/main/java/li/cil/oc2/data/ModBlockStateProvider.java b/src/main/java/li/cil/oc2/data/ModBlockStateProvider.java index 767ed9c0..dc5aba3e 100644 --- a/src/main/java/li/cil/oc2/data/ModBlockStateProvider.java +++ b/src/main/java/li/cil/oc2/data/ModBlockStateProvider.java @@ -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(); }); diff --git a/src/main/resources/assets/oc2/blockstates/bus_cable.json b/src/main/resources/assets/oc2/blockstates/bus_cable.json index ea735b47..afac4b92 100644 --- a/src/main/resources/assets/oc2/blockstates/bus_cable.json +++ b/src/main/resources/assets/oc2/blockstates/bus_cable.json @@ -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", diff --git a/src/main/resources/assets/oc2/lang/en_us.json b/src/main/resources/assets/oc2/lang/en_us.json index c233b3a2..553ad1bd 100644 --- a/src/main/resources/assets/oc2/lang/en_us.json +++ b/src/main/resources/assets/oc2/lang/en_us.json @@ -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.",