Improve cable/interface placement/breaking logic.
Can now place interfaces on their own, add cable later. Can remove just cable via wrench.
This commit is contained in:
@@ -35,7 +35,7 @@ public final class BusCableBakedModel implements IDynamicBakedModel {
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable final BlockState state, @Nullable final Direction side, final Random rand, final IModelData extraData) {
|
||||
if (state == null) {
|
||||
if (state == null || !state.get(BusCableBlock.HAS_CABLE)) {
|
||||
return proxy.getQuads(null, side, rand, extraData);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ public final class BusCableBakedModel implements IDynamicBakedModel {
|
||||
for (final Direction direction : Constants.DIRECTIONS) {
|
||||
if (isNeighborInDirectionSolid(world, pos, direction)) {
|
||||
final EnumProperty<BusCableBlock.ConnectionType> property = BusCableBlock.FACING_TO_CONNECTION_MAP.get(direction);
|
||||
if (state.hasProperty(property) && state.get(property) == BusCableBlock.ConnectionType.PLUG) {
|
||||
if (state.hasProperty(property) && state.get(property) == BusCableBlock.ConnectionType.INTERFACE) {
|
||||
return tileData; // Plug is already supporting us, bail.
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public final class BusCableBakedModel implements IDynamicBakedModel {
|
||||
for (final Direction direction : Constants.DIRECTIONS) {
|
||||
final EnumProperty<BusCableBlock.ConnectionType> property = BusCableBlock.FACING_TO_CONNECTION_MAP.get(direction);
|
||||
if (axis.test(direction)) {
|
||||
if (state.get(property) != BusCableBlock.ConnectionType.LINK) {
|
||||
if (state.get(property) != BusCableBlock.ConnectionType.CABLE) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -16,41 +16,46 @@ import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.loot.LootContext;
|
||||
import net.minecraft.state.BooleanProperty;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
import net.minecraft.state.StateContainer;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.shapes.ISelectionContext;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.util.math.vector.Vector3i;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.util.Constants.BlockFlags;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public final class BusCableBlock extends Block {
|
||||
public enum ConnectionType implements IStringSerializable {
|
||||
NONE,
|
||||
LINK,
|
||||
PLUG;
|
||||
CABLE,
|
||||
INTERFACE;
|
||||
|
||||
@Override
|
||||
public String getString() {
|
||||
switch (this) {
|
||||
case NONE:
|
||||
return "none";
|
||||
case LINK:
|
||||
return "link";
|
||||
case PLUG:
|
||||
return "plug";
|
||||
case CABLE:
|
||||
return "cable";
|
||||
case INTERFACE:
|
||||
return "interface";
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
@@ -59,6 +64,7 @@ public final class BusCableBlock extends Block {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static final BooleanProperty HAS_CABLE = BooleanProperty.create("has_cable");
|
||||
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);
|
||||
@@ -99,6 +105,7 @@ public final class BusCableBlock extends Block {
|
||||
for (final EnumProperty<ConnectionType> property : FACING_TO_CONNECTION_MAP.values()) {
|
||||
defaultState = defaultState.with(property, ConnectionType.NONE);
|
||||
}
|
||||
defaultState = defaultState.with(HAS_CABLE, true);
|
||||
setDefaultState(defaultState);
|
||||
|
||||
shapes = makeShapes();
|
||||
@@ -106,18 +113,29 @@ public final class BusCableBlock extends Block {
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public boolean addPlug(final World world, final BlockPos pos, final BlockState state, final Direction side) {
|
||||
final EnumProperty<BusCableBlock.ConnectionType> property = BusCableBlock.FACING_TO_CONNECTION_MAP.get(side);
|
||||
if (state.get(property) == BusCableBlock.ConnectionType.NONE) {
|
||||
if (!world.isRemote()) {
|
||||
world.setBlockState(pos, state.with(property, ConnectionType.PLUG));
|
||||
onConnectionTypeChanged(world, pos, side);
|
||||
WorldUtils.playSound(world, pos, state.getSoundType(), SoundType::getPlaceSound);
|
||||
}
|
||||
return true;
|
||||
public boolean addInterface(final World world, final BlockPos pos, final BlockState state, final Direction side) {
|
||||
final EnumProperty<BusCableBlock.ConnectionType> property = FACING_TO_CONNECTION_MAP.get(side);
|
||||
if (state.get(property) != ConnectionType.NONE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
world.setBlockState(pos, state.with(property, ConnectionType.INTERFACE), BlockFlags.DEFAULT_AND_RERENDER);
|
||||
|
||||
onConnectionTypeChanged(world, pos, side);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean addCable(final World world, final BlockPos pos, final BlockState state) {
|
||||
if (state.get(HAS_CABLE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
world.setBlockState(pos, state.with(HAS_CABLE, true), BlockFlags.DEFAULT_AND_RERENDER);
|
||||
|
||||
onConnectionTypeChanged(world, pos, null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -144,11 +162,17 @@ public final class BusCableBlock extends Block {
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public ActionResultType onBlockActivated(final BlockState state, final World world, final BlockPos pos, final PlayerEntity player, final Hand hand, final BlockRayTraceResult hit) {
|
||||
if (Wrenches.isWrench(player.getHeldItem(hand)) && tryRemovePlug(state, world, pos, player, hit)) {
|
||||
return ActionResultType.SUCCESS;
|
||||
if (player.isSneaking() && Wrenches.isWrench(player.getHeldItem(hand))) {
|
||||
// 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.func_233537_a_(world.isRemote());
|
||||
}
|
||||
}
|
||||
|
||||
return ActionResultType.PASS;
|
||||
return super.onBlockActivated(state, world, pos, player, hand, hit);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@@ -156,16 +180,20 @@ public final class BusCableBlock extends Block {
|
||||
public List<ItemStack> getDrops(final BlockState state, final LootContext.Builder builder) {
|
||||
final List<ItemStack> drops = new ArrayList<>(super.getDrops(state, builder));
|
||||
|
||||
int plugCount = 0;
|
||||
if (state.get(HAS_CABLE)) {
|
||||
drops.add(new ItemStack(Items.BUS_CABLE.get()));
|
||||
}
|
||||
|
||||
int interfaceCount = 0;
|
||||
for (final Direction side : Constants.DIRECTIONS) {
|
||||
final ConnectionType connectionType = state.get(FACING_TO_CONNECTION_MAP.get(side));
|
||||
if (connectionType == ConnectionType.PLUG) {
|
||||
plugCount++;
|
||||
if (connectionType == ConnectionType.INTERFACE) {
|
||||
interfaceCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (plugCount > 0) {
|
||||
drops.add(new ItemStack(Items.BUS_INTERFACE.get(), plugCount));
|
||||
if (interfaceCount > 0) {
|
||||
drops.add(new ItemStack(Items.BUS_INTERFACE.get(), interfaceCount));
|
||||
}
|
||||
|
||||
return drops;
|
||||
@@ -180,8 +208,9 @@ public final class BusCableBlock extends Block {
|
||||
for (final Map.Entry<Direction, EnumProperty<ConnectionType>> entry : FACING_TO_CONNECTION_MAP.entrySet()) {
|
||||
final Direction facing = entry.getKey();
|
||||
final BlockPos facingPos = position.offset(facing);
|
||||
if (isCableBlock(world.getBlockState(facingPos))) {
|
||||
state = state.with(entry.getValue(), ConnectionType.LINK);
|
||||
if (context.getItem().getItem() == Items.BUS_CABLE.get() &&
|
||||
canHaveCableTo(world.getBlockState(facingPos), facing.getOpposite())) {
|
||||
state = state.with(entry.getValue(), ConnectionType.CABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,11 +220,16 @@ public final class BusCableBlock extends Block {
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public BlockState updatePostPlacement(BlockState state, final Direction facing, final BlockState facingState, final IWorld world, final BlockPos currentPos, final BlockPos facingPos) {
|
||||
if (isCableBlock(facingState)) {
|
||||
state = state.with(FACING_TO_CONNECTION_MAP.get(facing), ConnectionType.LINK);
|
||||
} else if (state.get(FACING_TO_CONNECTION_MAP.get(facing)) != ConnectionType.PLUG) {
|
||||
if (state.get(FACING_TO_CONNECTION_MAP.get(facing)) == ConnectionType.INTERFACE) {
|
||||
return state;
|
||||
}
|
||||
|
||||
if (state.get(HAS_CABLE) && canHaveCableTo(facingState, facing.getOpposite())) {
|
||||
state = state.with(FACING_TO_CONNECTION_MAP.get(facing), ConnectionType.CABLE);
|
||||
} else {
|
||||
state = state.with(FACING_TO_CONNECTION_MAP.get(facing), ConnectionType.NONE);
|
||||
}
|
||||
|
||||
onConnectionTypeChanged(world, currentPos, facing);
|
||||
|
||||
return state;
|
||||
@@ -213,62 +247,22 @@ public final class BusCableBlock extends Block {
|
||||
protected void fillStateContainer(final StateContainer.Builder<Block, BlockState> builder) {
|
||||
super.fillStateContainer(builder);
|
||||
FACING_TO_CONNECTION_MAP.values().forEach(builder::add);
|
||||
builder.add(HAS_CABLE);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private VoxelShape[] makeShapes() {
|
||||
final VoxelShape coreShape = Block.makeCuboidShape(5, 5, 5, 11, 11, 11);
|
||||
final VoxelShape[] connectionShapes = new VoxelShape[Constants.DIRECTIONS.length];
|
||||
for (int i = 0; i < Constants.DIRECTIONS.length; i++) {
|
||||
final Direction direction = Constants.DIRECTIONS[i];
|
||||
connectionShapes[i] = VoxelShapes.create(
|
||||
0.5 + Math.min((-2.0 / (16 - 6)), direction.getXOffset() * 0.5),
|
||||
0.5 + Math.min((-2.0 / (16 - 6)), direction.getYOffset() * 0.5),
|
||||
0.5 + Math.min((-2.0 / (16 - 6)), direction.getZOffset() * 0.5),
|
||||
0.5 + Math.max(2.0 / (16 - 6), direction.getXOffset() * 0.5),
|
||||
0.5 + Math.max(2.0 / (16 - 6), direction.getYOffset() * 0.5),
|
||||
0.5 + Math.max(2.0 / (16 - 6), direction.getZOffset() * 0.5));
|
||||
}
|
||||
|
||||
final VoxelShape[] result = new VoxelShape[1 << 6];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
VoxelShape shape = coreShape;
|
||||
|
||||
for (int j = 0; j < Constants.DIRECTIONS.length; j++) {
|
||||
if ((i & (1 << j)) != 0) {
|
||||
shape = VoxelShapes.or(shape, connectionShapes[j]);
|
||||
}
|
||||
}
|
||||
|
||||
result[i] = shape;
|
||||
}
|
||||
|
||||
return result;
|
||||
private boolean canHaveCableTo(final BlockState state, final Direction side) {
|
||||
return state.getBlock() == this && state.get(HAS_CABLE) && state.get(FACING_TO_CONNECTION_MAP.get(side)) != ConnectionType.INTERFACE;
|
||||
}
|
||||
|
||||
private int getShapeIndex(final BlockState state) {
|
||||
int index = 0;
|
||||
|
||||
for (int i = 0; i < Constants.DIRECTIONS.length; i++) {
|
||||
if (state.get(FACING_TO_CONNECTION_MAP.get(Constants.DIRECTIONS[i])) != ConnectionType.NONE) {
|
||||
index |= 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
private boolean isCableBlock(final BlockState state) {
|
||||
return state.getBlock() == this;
|
||||
}
|
||||
|
||||
private void onConnectionTypeChanged(final IWorld world, final BlockPos pos, final Direction face) {
|
||||
final TileEntity tileEntity = world.getTileEntity(pos);
|
||||
if (tileEntity instanceof BusCableTileEntity) {
|
||||
final BusCableTileEntity busCable = (BusCableTileEntity) tileEntity;
|
||||
busCable.handleConnectionTypeChanged(face);
|
||||
private static int getPartCount(final BlockState state) {
|
||||
int partCount = 0;
|
||||
if (state.get(HAS_CABLE)) partCount++;
|
||||
for (final EnumProperty<ConnectionType> connectionType : FACING_TO_CONNECTION_MAP.values()) {
|
||||
if (state.get(connectionType) == ConnectionType.INTERFACE) partCount++;
|
||||
}
|
||||
return partCount;
|
||||
}
|
||||
|
||||
private boolean tryRemovePlug(final BlockState state, final World world, final BlockPos pos, final PlayerEntity player, final BlockRayTraceResult hit) {
|
||||
@@ -276,27 +270,169 @@ public final class BusCableBlock extends Block {
|
||||
final Direction side = Direction.getFacingFromVector(localHitPos.x, localHitPos.y, localHitPos.z);
|
||||
final EnumProperty<ConnectionType> property = FACING_TO_CONNECTION_MAP.get(side);
|
||||
|
||||
if (state.get(property) != ConnectionType.PLUG) {
|
||||
if (state.get(property) != ConnectionType.INTERFACE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final BlockPos neighborPos = pos.offset(side);
|
||||
if (isCableBlock(world.getBlockState(neighborPos))) {
|
||||
world.setBlockState(pos, state.with(property, ConnectionType.LINK));
|
||||
if (state.get(HAS_CABLE) && canHaveCableTo(world.getBlockState(neighborPos), side.getOpposite())) {
|
||||
world.setBlockState(pos, state.with(property, ConnectionType.CABLE));
|
||||
} else {
|
||||
world.setBlockState(pos, state.with(property, ConnectionType.NONE));
|
||||
}
|
||||
|
||||
handlePartRemoved(state, world, pos, side, player, new ItemStack(Items.BUS_INTERFACE.get()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean tryRemoveCable(final BlockState state, final World world, final BlockPos pos, final PlayerEntity player) {
|
||||
if (!state.get(HAS_CABLE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
world.setBlockState(pos, state.with(HAS_CABLE, false));
|
||||
|
||||
handlePartRemoved(state, world, pos, null, player, new ItemStack(Items.BUS_CABLE.get()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void handlePartRemoved(final BlockState state, final World world, final BlockPos pos, @Nullable final Direction side, final PlayerEntity player, final ItemStack drop) {
|
||||
onConnectionTypeChanged(world, pos, side);
|
||||
|
||||
if (!player.isCreative() && world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)) {
|
||||
ItemStackUtils.spawnAsEntity(world, pos, new ItemStack(Items.BUS_INTERFACE.get()), side).ifPresent(entity -> {
|
||||
ItemStackUtils.spawnAsEntity(world, pos, drop, side).ifPresent(entity -> {
|
||||
entity.setNoPickupDelay();
|
||||
entity.onCollideWithPlayer(player);
|
||||
});
|
||||
}
|
||||
|
||||
WorldUtils.playSound(world, pos, state.getSoundType(), SoundType::getBreakSound);
|
||||
}
|
||||
|
||||
return true;
|
||||
private void onConnectionTypeChanged(final IWorld world, final BlockPos pos, @Nullable final Direction face) {
|
||||
final TileEntity tileEntity = world.getTileEntity(pos);
|
||||
if (tileEntity instanceof BusCableTileEntity) {
|
||||
final BusCableTileEntity busCable = (BusCableTileEntity) tileEntity;
|
||||
busCable.handleConnectivityChanged(face);
|
||||
}
|
||||
}
|
||||
|
||||
private static VoxelShape[] makeShapes() {
|
||||
final VoxelShape ownCableBounds = Block.makeCuboidShape(5, 5, 5, 11, 11, 11);
|
||||
final VoxelShape[] cableShapes = new VoxelShape[Constants.BLOCK_FACE_COUNT];
|
||||
final VoxelShape[] interfaceShapes = new VoxelShape[Constants.BLOCK_FACE_COUNT];
|
||||
for (int i = 0; i < Constants.BLOCK_FACE_COUNT; i++) {
|
||||
cableShapes[i] = getCableShape(Constants.DIRECTIONS[i]);
|
||||
interfaceShapes[i] = getInterfaceShape(Constants.DIRECTIONS[i]);
|
||||
}
|
||||
|
||||
// We pack info as such:
|
||||
// [has interface on side] [has cable on side] [has own cable]
|
||||
// Which is a total of 13 bits (6 + 6 + 1), so 8k combinations.
|
||||
// It's a lot, but not so much that it's not ok to still cache
|
||||
// it and avoid recomputing the bounds all the time.
|
||||
|
||||
final int configurations = 1 << (6 + 6 + 1);
|
||||
final VoxelShape[] result = new VoxelShape[configurations];
|
||||
Arrays.fill(result, VoxelShapes.empty());
|
||||
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
final int mask = i >> 1;
|
||||
for (int sideIndex = 0; sideIndex < Constants.BLOCK_FACE_COUNT; sideIndex++) {
|
||||
final int cableBit = 1 << sideIndex;
|
||||
if ((mask & cableBit) != 0) {
|
||||
result[i] = VoxelShapes.or(result[i], cableShapes[sideIndex]);
|
||||
}
|
||||
|
||||
final int interfaceBit = cableBit << 6;
|
||||
if ((mask & interfaceBit) != 0) {
|
||||
result[i] = VoxelShapes.or(result[i], interfaceShapes[sideIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
if ((i & 1) != 0) {
|
||||
result[i] = VoxelShapes.or(result[i], ownCableBounds);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
private static VoxelShape getCableShape(final Direction zDirection) {
|
||||
final int xSize = 6;
|
||||
final int ySize = 6;
|
||||
final int zSize = 5;
|
||||
|
||||
final Direction yDirection = zDirection.getAxis() == Direction.Axis.Y ? Direction.NORTH : Direction.UP;
|
||||
final Direction xDirection = zDirection.getAxis() == Direction.Axis.Y ? Direction.WEST : zDirection.rotateY();
|
||||
|
||||
final Vector3i min = new Vector3i(8, 8, 8)
|
||||
.offset(xDirection, -xSize / 2)
|
||||
.offset(yDirection, -ySize / 2)
|
||||
.offset(zDirection, 8 - zSize);
|
||||
final Vector3i max = new Vector3i(8, 8, 8)
|
||||
.offset(xDirection, xSize / 2)
|
||||
.offset(yDirection, ySize / 2)
|
||||
.offset(zDirection, 8);
|
||||
|
||||
final AxisAlignedBB bounds = new AxisAlignedBB(
|
||||
Vector3d.copy(min).scale(1 / 16.0),
|
||||
Vector3d.copy(max).scale(1 / 16.0)
|
||||
);
|
||||
|
||||
return VoxelShapes.create(bounds);
|
||||
}
|
||||
|
||||
private static VoxelShape getInterfaceShape(final Direction zDirection) {
|
||||
final int xSize = 8;
|
||||
final int ySize = 8;
|
||||
final int zSize = 1;
|
||||
|
||||
final Direction yDirection = zDirection.getAxis() == Direction.Axis.Y ? Direction.NORTH : Direction.UP;
|
||||
final Direction xDirection = zDirection.getAxis() == Direction.Axis.Y ? Direction.WEST : zDirection.rotateY();
|
||||
|
||||
final Vector3i min = new Vector3i(8, 8, 8)
|
||||
.offset(xDirection, -xSize / 2)
|
||||
.offset(yDirection, -ySize / 2)
|
||||
.offset(zDirection, 8 - zSize);
|
||||
final Vector3i max = new Vector3i(8, 8, 8)
|
||||
.offset(xDirection, xSize / 2)
|
||||
.offset(yDirection, ySize / 2)
|
||||
.offset(zDirection, 8);
|
||||
|
||||
final AxisAlignedBB bounds = new AxisAlignedBB(
|
||||
Vector3d.copy(min).scale(1 / 16.0),
|
||||
Vector3d.copy(max).scale(1 / 16.0)
|
||||
);
|
||||
|
||||
return VoxelShapes.or(getCableShape(zDirection), VoxelShapes.create(bounds));
|
||||
}
|
||||
|
||||
private static int getShapeIndex(final BlockState state) {
|
||||
int index = 0;
|
||||
|
||||
for (int sideIndex = 0; sideIndex < Constants.BLOCK_FACE_COUNT; sideIndex++) {
|
||||
final int cableBit = 1 << sideIndex;
|
||||
final int interfaceBit = cableBit << 6;
|
||||
switch (state.get(FACING_TO_CONNECTION_MAP.get(Constants.DIRECTIONS[sideIndex]))) {
|
||||
case CABLE:
|
||||
index |= cableBit;
|
||||
break;
|
||||
case INTERFACE:
|
||||
index |= interfaceBit;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
index = index << 1;
|
||||
|
||||
if (state.get(HAS_CABLE)) {
|
||||
index |= 1;
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.capabilities.Capability;
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider;
|
||||
import net.minecraftforge.common.util.Constants.BlockFlags;
|
||||
import net.minecraftforge.common.util.LazyOptional;
|
||||
import net.minecraftforge.event.world.ChunkEvent;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
@@ -270,7 +271,7 @@ public final class RobotEntity extends Entity implements Robot {
|
||||
.withParameter(LootParameters.BLOCK_STATE, blockState)
|
||||
.withNullableParameter(LootParameters.BLOCK_ENTITY, tileEntity);
|
||||
final List<ItemStack> drops = blockState.getDrops(builder);
|
||||
world.setBlockState(mutablePosition, Blocks.AIR.getDefaultState(), 3);
|
||||
world.setBlockState(mutablePosition, Blocks.AIR.getDefaultState());
|
||||
for (final ItemStack drop : drops) {
|
||||
Block.spawnAsEntity(world, mutablePosition, drop);
|
||||
}
|
||||
|
||||
66
src/main/java/li/cil/oc2/common/item/BusCableItem.java
Normal file
66
src/main/java/li/cil/oc2/common/item/BusCableItem.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package li.cil.oc2.common.item;
|
||||
|
||||
import li.cil.oc2.common.block.Blocks;
|
||||
import li.cil.oc2.common.block.BusCableBlock;
|
||||
import li.cil.oc2.common.util.WorldUtils;
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public final class BusCableItem extends ModBlockItem {
|
||||
public BusCableItem(final Block block) {
|
||||
super(block);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Override
|
||||
public ActionResultType onItemUse(final ItemUseContext context) {
|
||||
final ActionResultType result = tryAddToBlock(context);
|
||||
return result.isSuccessOrConsume() ? result : super.onItemUse(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType tryPlace(final BlockItemUseContext context) {
|
||||
final ActionResultType result = tryAddToBlock(context);
|
||||
return result.isSuccessOrConsume() ? result : super.tryPlace(context);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private ActionResultType tryAddToBlock(final ItemUseContext context) {
|
||||
final BusCableBlock busCableBlock = Blocks.BUS_CABLE.get();
|
||||
|
||||
final World world = context.getWorld();
|
||||
final BlockPos pos = context.getPos();
|
||||
final BlockState state = world.getBlockState(pos);
|
||||
|
||||
if (state.getBlock() == busCableBlock && busCableBlock.addCable(world, pos, state)) {
|
||||
final PlayerEntity player = context.getPlayer();
|
||||
final ItemStack stack = context.getItem();
|
||||
|
||||
if (player instanceof ServerPlayerEntity) {
|
||||
CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayerEntity) player, pos, stack);
|
||||
}
|
||||
|
||||
WorldUtils.playSound(world, pos, state.getSoundType(world, pos, player), SoundType::getPlaceSound);
|
||||
|
||||
if (player == null || !player.abilities.isCreativeMode) {
|
||||
stack.shrink(1);
|
||||
}
|
||||
|
||||
return ActionResultType.func_233537_a_(world.isRemote);
|
||||
}
|
||||
|
||||
return ActionResultType.PASS;
|
||||
}
|
||||
}
|
||||
@@ -2,47 +2,85 @@ package li.cil.oc2.common.item;
|
||||
|
||||
import li.cil.oc2.common.block.Blocks;
|
||||
import li.cil.oc2.common.block.BusCableBlock;
|
||||
import li.cil.oc2.common.block.BusCableBlock.ConnectionType;
|
||||
import li.cil.oc2.common.util.WorldUtils;
|
||||
import net.minecraft.advancements.CriteriaTriggers;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.BlockItemUseContext;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.state.EnumProperty;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.vector.Vector3d;
|
||||
import net.minecraft.world.World;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class BusInterfaceItem extends ModBlockItem {
|
||||
public BusInterfaceItem(final Block block) {
|
||||
super(block);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public final class BusInterfaceItem extends ModItem {
|
||||
@Override
|
||||
public ActionResultType onItemUse(final ItemUseContext context) {
|
||||
final Vector3d localHitPos = context.getHitVec().subtract(Vector3d.copyCentered(context.getPos()));
|
||||
final Direction side = Direction.getFacingFromVector(localHitPos.x, localHitPos.y, localHitPos.z);
|
||||
final ActionResultType result = tryAddToBlock(context, side);
|
||||
return result.isSuccessOrConsume() ? result : super.onItemUse(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionResultType tryPlace(final BlockItemUseContext context) {
|
||||
final ActionResultType result = tryAddToBlock(context, context.getFace().getOpposite());
|
||||
return result.isSuccessOrConsume() ? result : super.tryPlace(context);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected BlockState getStateForPlacement(final BlockItemUseContext context) {
|
||||
final BlockState state = super.getStateForPlacement(context);
|
||||
final EnumProperty<ConnectionType> connectionTypeProperty =
|
||||
BusCableBlock.FACING_TO_CONNECTION_MAP.get(context.getFace().getOpposite());
|
||||
return state
|
||||
.with(BusCableBlock.HAS_CABLE, false)
|
||||
.with(connectionTypeProperty, ConnectionType.INTERFACE);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
private ActionResultType tryAddToBlock(final ItemUseContext context, final Direction side) {
|
||||
final BusCableBlock busCableBlock = Blocks.BUS_CABLE.get();
|
||||
|
||||
final World world = context.getWorld();
|
||||
final BlockPos pos = context.getPos();
|
||||
final BlockState state = world.getBlockState(pos);
|
||||
|
||||
final BusCableBlock busCableBlock = Blocks.BUS_CABLE.get();
|
||||
if (state.getBlock() == busCableBlock) {
|
||||
final Vector3d localHitPos = context.getHitVec().subtract(Vector3d.copyCentered(pos));
|
||||
final Direction side = Direction.getFacingFromVector(localHitPos.x, localHitPos.y, localHitPos.z);
|
||||
if (busCableBlock.addPlug(world, pos, state, side)) {
|
||||
context.getItem().shrink(1);
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
} else {
|
||||
final BlockPos neighborPos = pos.offset(context.getFace());
|
||||
final BlockState neighborState = world.getBlockState(neighborPos);
|
||||
if (state.getBlock() == busCableBlock && busCableBlock.addInterface(world, pos, state, side)) {
|
||||
final PlayerEntity player = context.getPlayer();
|
||||
final ItemStack stack = context.getItem();
|
||||
|
||||
// TODO Store in cable whether cable itself is present, i.e. allow bus blocks that are just plugs.
|
||||
// if (neighborState.isReplaceable(new BlockItemUseContext(context))) {
|
||||
// world.setBlockState(neighborPos, Blocks.BUS_CABLE.get().getDefaultState());
|
||||
// }
|
||||
|
||||
if (neighborState.getBlock() == busCableBlock) {
|
||||
final Direction side = context.getFace().getOpposite();
|
||||
if (busCableBlock.addPlug(world, neighborPos, neighborState, side)) {
|
||||
context.getItem().shrink(1);
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
if (player instanceof ServerPlayerEntity) {
|
||||
CriteriaTriggers.PLACED_BLOCK.trigger((ServerPlayerEntity) player, pos, stack);
|
||||
}
|
||||
|
||||
WorldUtils.playSound(world, pos, state.getSoundType(world, pos, player), SoundType::getPlaceSound);
|
||||
|
||||
if (player == null || !player.abilities.isCreativeMode) {
|
||||
stack.shrink(1);
|
||||
}
|
||||
|
||||
return ActionResultType.func_233537_a_(world.isRemote);
|
||||
}
|
||||
|
||||
return super.onItemUse(context);
|
||||
return ActionResultType.PASS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.registries.DeferredRegister;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public final class Items {
|
||||
@@ -18,7 +19,8 @@ public final class Items {
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
public static final RegistryObject<Item> COMPUTER = register(Constants.COMPUTER_BLOCK_NAME, Blocks.COMPUTER);
|
||||
public static final RegistryObject<Item> BUS_CABLE = register(Constants.BUS_CABLE_BLOCK_NAME, Blocks.BUS_CABLE);
|
||||
public static final RegistryObject<Item> BUS_CABLE = register(Constants.BUS_CABLE_BLOCK_NAME, Blocks.BUS_CABLE, BusCableItem::new);
|
||||
public static final RegistryObject<BusInterfaceItem> BUS_INTERFACE = register(Constants.BUS_INTERFACE_ITEM_NAME, Blocks.BUS_CABLE, BusInterfaceItem::new);
|
||||
public static final RegistryObject<Item> NETWORK_CONNECTOR = register(Constants.NETWORK_CONNECTOR_BLOCK_NAME, Blocks.NETWORK_CONNECTOR);
|
||||
public static final RegistryObject<Item> NETWORK_HUB = register(Constants.NETWORK_HUB_BLOCK_NAME, Blocks.NETWORK_HUB);
|
||||
public static final RegistryObject<Item> REDSTONE_INTERFACE = register(Constants.REDSTONE_INTERFACE_BLOCK_NAME, Blocks.REDSTONE_INTERFACE);
|
||||
@@ -28,8 +30,7 @@ public final class Items {
|
||||
|
||||
public static final RegistryObject<Item> WRENCH = register(Constants.WRENCH_ITEM_NAME, WrenchItem::new);
|
||||
|
||||
public static final RegistryObject<Item> BUS_INTERFACE = register(Constants.BUS_INTERFACE_ITEM_NAME, BusInterfaceItem::new);
|
||||
public static final RegistryObject<Item> NETWORK_CABLE = register(Constants.NETWORK_CABLE_ITEM_NAME, NetworkCableItem::new);
|
||||
public static final RegistryObject<NetworkCableItem> NETWORK_CABLE = register(Constants.NETWORK_CABLE_ITEM_NAME, NetworkCableItem::new);
|
||||
public static final RegistryObject<Item> ROBOT = register(Constants.ROBOT_ENTITY_NAME, RobotItem::new);
|
||||
|
||||
public static final RegistryObject<MemoryItem> MEMORY = register(Constants.MEMORY_ITEM_NAME, MemoryItem::new);
|
||||
@@ -59,6 +60,10 @@ public final class Items {
|
||||
}
|
||||
|
||||
private static <T extends Block> RegistryObject<Item> register(final String name, final RegistryObject<T> block) {
|
||||
return register(name, () -> new ModBlockItem(block.get()));
|
||||
return register(name, block, ModBlockItem::new);
|
||||
}
|
||||
|
||||
private static <TBlock extends Block, TItem extends Item> RegistryObject<TItem> register(final String name, final RegistryObject<TBlock> block, final Function<TBlock, TItem> factory) {
|
||||
return register(name, () -> factory.apply(block.get()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +1,43 @@
|
||||
package li.cil.oc2.common.item;
|
||||
|
||||
import li.cil.oc2.api.API;
|
||||
import li.cil.oc2.common.util.WorldUtils;
|
||||
import li.cil.oc2.common.tags.BlockTags;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.SoundType;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.ItemUseContext;
|
||||
import net.minecraft.server.management.PlayerInteractionManager;
|
||||
import net.minecraft.util.ActionResultType;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IWorldReader;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public final class WrenchItem extends ModItem {
|
||||
@Override
|
||||
public ActionResultType onItemUse(final ItemUseContext context) {
|
||||
final World world = context.getWorld();
|
||||
final BlockPos pos = context.getPos();
|
||||
final BlockState state = world.getBlockState(pos);
|
||||
final ResourceLocation registryName = state.getBlock().getRegistryName();
|
||||
if (registryName == null || !Objects.equals(registryName.getNamespace(), API.MOD_ID)) {
|
||||
final PlayerEntity player = context.getPlayer();
|
||||
if (!player.isSneaking()) {
|
||||
return super.onItemUse(context);
|
||||
}
|
||||
|
||||
final PlayerEntity player = context.getPlayer();
|
||||
if (player instanceof ServerPlayerEntity) {
|
||||
final PlayerInteractionManager interactionManager = ((ServerPlayerEntity) player).interactionManager;
|
||||
if (interactionManager.tryHarvestBlock(pos)) {
|
||||
WorldUtils.playSound(world, pos, state.getSoundType(), SoundType::getBreakSound);
|
||||
return ActionResultType.SUCCESS;
|
||||
}
|
||||
final World world = context.getWorld();
|
||||
final BlockPos pos = context.getPos();
|
||||
final BlockState state = world.getBlockState(pos);
|
||||
if (!state.isIn(BlockTags.WRENCH_BREAKABLE)) {
|
||||
return super.onItemUse(context);
|
||||
}
|
||||
|
||||
return super.onItemUse(context);
|
||||
if (world.isRemote()) {
|
||||
Minecraft.getInstance().playerController.onPlayerDestroyBlock(pos);
|
||||
} else if (player instanceof ServerPlayerEntity) {
|
||||
((ServerPlayerEntity) player).interactionManager.tryHarvestBlock(pos);
|
||||
}
|
||||
|
||||
return ActionResultType.func_233537_a_(world.isRemote);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean doesSneakBypassUse(final ItemStack stack, final IWorldReader world, final BlockPos pos, final PlayerEntity player) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.minecraftforge.common.Tags;
|
||||
public final class BlockTags {
|
||||
public static final Tags.IOptionalNamedTag<Block> DEVICES = tag("devices");
|
||||
public static final Tags.IOptionalNamedTag<Block> CABLES = tag("cables");
|
||||
public static final Tags.IOptionalNamedTag<Block> WRENCH_BREAKABLE = tag("wrench_breakable");
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -36,9 +36,16 @@ public final class BusCableTileEntity extends AbstractTileEntity {
|
||||
requestModelDataUpdate();
|
||||
}
|
||||
|
||||
public void handleConnectionTypeChanged(final Direction side) {
|
||||
invalidateCapability(Capabilities.DEVICE_BUS_ELEMENT, side);
|
||||
handleNeighborChanged(getPos().offset(side));
|
||||
public void handleConnectivityChanged(@Nullable final Direction side) {
|
||||
if (side == null) {
|
||||
busElement.scheduleScan();
|
||||
|
||||
// TODO Remove if https://github.com/MinecraftForge/MinecraftForge/pull/7595 gets merged.
|
||||
requestModelDataUpdate();
|
||||
} else {
|
||||
invalidateCapability(Capabilities.DEVICE_BUS_ELEMENT, side);
|
||||
handleNeighborChanged(getPos().offset(side));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,14 +109,14 @@ public final class BusCableTileEntity extends AbstractTileEntity {
|
||||
@Override
|
||||
public boolean canScanContinueTowards(@Nullable final Direction direction) {
|
||||
final BusCableBlock.ConnectionType connectionType = BusCableBlock.getConnectionType(getBlockState(), direction);
|
||||
return connectionType == BusCableBlock.ConnectionType.LINK ||
|
||||
connectionType == BusCableBlock.ConnectionType.PLUG;
|
||||
return connectionType == BusCableBlock.ConnectionType.CABLE ||
|
||||
connectionType == BusCableBlock.ConnectionType.INTERFACE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canDetectDevicesTowards(@Nullable final Direction direction) {
|
||||
final BusCableBlock.ConnectionType connectionType = BusCableBlock.getConnectionType(getBlockState(), direction);
|
||||
return connectionType == BusCableBlock.ConnectionType.PLUG;
|
||||
return connectionType == BusCableBlock.ConnectionType.INTERFACE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,11 +106,15 @@ public final class ItemStackUtils {
|
||||
return Optional.of(entity);
|
||||
}
|
||||
|
||||
public static Optional<ItemEntity> spawnAsEntity(final World world, final BlockPos pos, final ItemStack stack, final Direction direction) {
|
||||
public static Optional<ItemEntity> spawnAsEntity(final World world, final BlockPos pos, final ItemStack stack, @Nullable final Direction direction) {
|
||||
return spawnAsEntity(world, Vector3d.copyCentered(pos), stack, direction);
|
||||
}
|
||||
|
||||
public static Optional<ItemEntity> spawnAsEntity(final World world, final Vector3d pos, final ItemStack stack, final Direction direction) {
|
||||
public static Optional<ItemEntity> spawnAsEntity(final World world, final Vector3d pos, final ItemStack stack, @Nullable final Direction direction) {
|
||||
if (direction == null) {
|
||||
return spawnAsEntity(world, pos, stack);
|
||||
}
|
||||
|
||||
if (world.isRemote() || stack.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@@ -49,7 +49,12 @@ public class ModBlockStateProvider extends BlockStateProvider {
|
||||
|
||||
// NB: We use a custom model loader + baked model to replace the base part with straight parts and
|
||||
// insert supports where appropriate.
|
||||
builder.part().modelFile(baseModel).addModel().end();
|
||||
|
||||
builder.part()
|
||||
.modelFile(baseModel)
|
||||
.addModel()
|
||||
.condition(BusCableBlock.HAS_CABLE, true)
|
||||
.end();
|
||||
|
||||
BusCableBlock.FACING_TO_CONNECTION_MAP.forEach((direction, connectionType) -> {
|
||||
final int rotationY = (int) direction.getHorizontalAngle();
|
||||
@@ -67,7 +72,7 @@ public class ModBlockStateProvider extends BlockStateProvider {
|
||||
.rotationY(rotationY)
|
||||
.rotationX(rotationX)
|
||||
.addModel()
|
||||
.condition(connectionType, BusCableBlock.ConnectionType.LINK)
|
||||
.condition(connectionType, BusCableBlock.ConnectionType.CABLE)
|
||||
.end();
|
||||
|
||||
builder.part()
|
||||
@@ -75,7 +80,7 @@ public class ModBlockStateProvider extends BlockStateProvider {
|
||||
.rotationY(rotationY)
|
||||
.rotationX(rotationX)
|
||||
.addModel()
|
||||
.condition(connectionType, BusCableBlock.ConnectionType.PLUG)
|
||||
.condition(connectionType, BusCableBlock.ConnectionType.INTERFACE)
|
||||
.end();
|
||||
});
|
||||
|
||||
|
||||
@@ -7,8 +7,7 @@ import net.minecraftforge.common.data.ExistingFileHelper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import static li.cil.oc2.common.block.Blocks.*;
|
||||
import static li.cil.oc2.common.tags.BlockTags.CABLES;
|
||||
import static li.cil.oc2.common.tags.BlockTags.DEVICES;
|
||||
import static li.cil.oc2.common.tags.BlockTags.*;
|
||||
|
||||
public final class ModBlockTagsProvider extends BlockTagsProvider {
|
||||
public ModBlockTagsProvider(final DataGenerator generatorIn, @Nullable final ExistingFileHelper existingFileHelper) {
|
||||
@@ -22,6 +21,16 @@ public final class ModBlockTagsProvider extends BlockTagsProvider {
|
||||
REDSTONE_INTERFACE.get(),
|
||||
DISK_DRIVE.get()
|
||||
);
|
||||
getOrCreateBuilder(CABLES).add(BUS_CABLE.get());
|
||||
getOrCreateBuilder(CABLES).add(
|
||||
BUS_CABLE.get()
|
||||
);
|
||||
getOrCreateBuilder(WRENCH_BREAKABLE).add(
|
||||
COMPUTER.get(),
|
||||
BUS_CABLE.get(),
|
||||
NETWORK_CONNECTOR.get(),
|
||||
NETWORK_HUB.get(),
|
||||
REDSTONE_INTERFACE.get(),
|
||||
DISK_DRIVE.get()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ public final class ModLootTableProvider extends LootTableProvider {
|
||||
public static final class ModBlockLootTables extends BlockLootTables {
|
||||
@Override
|
||||
protected void addTables() {
|
||||
registerDropSelfLootTable(Blocks.BUS_CABLE.get());
|
||||
registerDropSelfLootTable(Blocks.REDSTONE_INTERFACE.get());
|
||||
registerDropSelfLootTable(Blocks.NETWORK_CONNECTOR.get());
|
||||
registerDropSelfLootTable(Blocks.NETWORK_HUB.get());
|
||||
@@ -55,6 +54,7 @@ public final class ModLootTableProvider extends LootTableProvider {
|
||||
protected Iterable<Block> getKnownBlocks() {
|
||||
return StreamSupport.stream(super.getKnownBlocks().spliterator(), false)
|
||||
.filter(block -> requireNonNull(block.getRegistryName()).getNamespace().equals(API.MOD_ID))
|
||||
.filter(block -> block != Blocks.BUS_CABLE.get()) // All bus drops depend on block state.
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
{
|
||||
"multipart": [
|
||||
{
|
||||
"when": {
|
||||
"has_cable": "true"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_base"
|
||||
}
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_down": "link"
|
||||
"connection_down": "cable"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_link",
|
||||
@@ -17,7 +20,7 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_down": "plug"
|
||||
"connection_down": "interface"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_plug",
|
||||
@@ -27,7 +30,7 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_up": "link"
|
||||
"connection_up": "cable"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_link",
|
||||
@@ -37,7 +40,7 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_up": "plug"
|
||||
"connection_up": "interface"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_plug",
|
||||
@@ -47,7 +50,7 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_north": "link"
|
||||
"connection_north": "cable"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_link",
|
||||
@@ -56,7 +59,7 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_north": "plug"
|
||||
"connection_north": "interface"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_plug",
|
||||
@@ -65,7 +68,7 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_south": "link"
|
||||
"connection_south": "cable"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_link"
|
||||
@@ -73,7 +76,7 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_south": "plug"
|
||||
"connection_south": "interface"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_plug"
|
||||
@@ -81,7 +84,7 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_west": "link"
|
||||
"connection_west": "cable"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_link",
|
||||
@@ -90,7 +93,7 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_west": "plug"
|
||||
"connection_west": "interface"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_plug",
|
||||
@@ -99,7 +102,7 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_east": "link"
|
||||
"connection_east": "cable"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_link",
|
||||
@@ -108,7 +111,7 @@
|
||||
},
|
||||
{
|
||||
"when": {
|
||||
"connection_east": "plug"
|
||||
"connection_east": "interface"
|
||||
},
|
||||
"apply": {
|
||||
"model": "oc2:block/cable_plug",
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"type": "minecraft:block",
|
||||
"pools": [
|
||||
{
|
||||
"rolls": 1,
|
||||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"name": "oc2:bus_cable"
|
||||
}
|
||||
],
|
||||
"conditions": [
|
||||
{
|
||||
"condition": "minecraft:survives_explosion"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"oc2:computer",
|
||||
"oc2:bus_cable",
|
||||
"oc2:network_connector",
|
||||
"oc2:network_hub",
|
||||
"oc2:redstone_interface",
|
||||
"oc2:disk_drive"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user