Add custom model loader + baked model to simplify bus cable block state.

Also added small supports at ends and bends to make cables look less floaty.
This commit is contained in:
Florian Nücke
2021-01-09 18:12:50 +01:00
parent f9df904aea
commit 25444a5382
20 changed files with 317 additions and 9573 deletions

View File

@@ -1,20 +1,32 @@
package li.cil.oc2.client;
import li.cil.oc2.api.API;
import li.cil.oc2.client.gui.ComputerContainerScreen;
import li.cil.oc2.client.model.BusCableModelLoader;
import li.cil.oc2.client.renderer.NetworkCableRenderer;
import li.cil.oc2.client.renderer.tileentity.ComputerTileEntityRenderer;
import li.cil.oc2.common.container.Containers;
import li.cil.oc2.common.tileentity.TileEntities;
import net.minecraft.client.gui.ScreenManager;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.event.ModelRegistryEvent;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
public final class ClientSetup {
public static void run(final FMLClientSetupEvent event) {
@SubscribeEvent
public static void handleSetupEvent(final FMLClientSetupEvent event) {
NetworkCableRenderer.initialize();
ScreenManager.registerFactory(Containers.COMPUTER_CONTAINER.get(), ComputerContainerScreen::new);
ClientRegistry.bindTileEntityRenderer(TileEntities.COMPUTER_TILE_ENTITY.get(), ComputerTileEntityRenderer::new);
}
@SubscribeEvent
public static void handleModelRegistryEvent(final ModelRegistryEvent event) {
ModelLoaderRegistry.registerLoader(new ResourceLocation(API.MOD_ID, "bus_cable"), new BusCableModelLoader());
}
}

View File

@@ -0,0 +1,158 @@
package li.cil.oc2.client.model;
import li.cil.oc2.common.block.BusCableBlock;
import net.minecraft.block.BlockState;
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.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockDisplayReader;
import net.minecraftforge.client.model.data.IDynamicBakedModel;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelDataMap;
import net.minecraftforge.client.model.data.ModelProperty;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public final class BusCableBakedModel implements IDynamicBakedModel {
private static final Direction[] DIRECTIONS = Direction.values();
private static final Direction.Axis[] AXES = Direction.Axis.values();
private final IBakedModel proxy;
private final IBakedModel[] straightModelByAxis;
private final IBakedModel[] supportModelByFace;
public BusCableBakedModel(final IBakedModel proxy, final IBakedModel[] straightModelByAxis, final IBakedModel[] supportModelByFace) {
this.proxy = proxy;
this.straightModelByAxis = straightModelByAxis;
this.supportModelByFace = supportModelByFace;
}
@Override
public List<BakedQuad> getQuads(@Nullable final BlockState state, @Nullable final Direction side, final Random rand, final IModelData extraData) {
if (state == null) {
return proxy.getQuads(null, side, rand, extraData);
}
for (int i = 0; i < AXES.length; i++) {
final Direction.Axis axis = AXES[i];
if (isStraightAlongAxis(state, axis)) {
return straightModelByAxis[i].getQuads(state, side, rand, extraData);
}
}
final ArrayList<BakedQuad> quads = new ArrayList<>(proxy.getQuads(state, side, rand, extraData));
final BusCableSupportSide supportSide = extraData.getData(BusCableSupportSide.BUS_CABLE_SUPPORT_PROPERTY);
if (supportSide != null) {
quads.addAll(supportModelByFace[supportSide.get().getIndex()].getQuads(state, side, rand, extraData));
}
return quads;
}
@Override
public boolean isAmbientOcclusion() {
return proxy.isAmbientOcclusion();
}
@Override
public boolean isGui3d() {
return proxy.isGui3d();
}
@Override
public boolean isSideLit() {
return proxy.isSideLit();
}
@Override
public boolean isBuiltInRenderer() {
return proxy.isBuiltInRenderer();
}
@Override
public TextureAtlasSprite getParticleTexture() {
return proxy.getParticleTexture();
}
@Override
public ItemOverrideList getOverrides() {
return proxy.getOverrides();
}
@Override
public IModelData getModelData(final IBlockDisplayReader world, final BlockPos pos, final BlockState state, final IModelData tileData) {
return getBusCableSupportSideData(world, pos, state, tileData);
}
public static IModelData getBusCableSupportSideData(final IBlockDisplayReader world, final BlockPos pos, final BlockState state, final IModelData tileData) {
Direction supportSide = null;
for (final Direction direction : 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) {
return tileData; // Plug is already supporting us, bail.
}
if (supportSide == null) { // Prefer vertical supports.
supportSide = direction;
}
}
}
if (supportSide != null) {
return new ModelDataMap.Builder()
.withInitial(BusCableSupportSide.BUS_CABLE_SUPPORT_PROPERTY, new BusCableSupportSide(supportSide))
.build();
}
return tileData;
}
///////////////////////////////////////////////////////////////////
private static boolean isNeighborInDirectionSolid(final IBlockDisplayReader world, final BlockPos pos, final Direction direction) {
final BlockPos neighborPos = pos.offset(direction);
return world.getBlockState(neighborPos).isSolidSide(world, neighborPos, direction.getOpposite());
}
private static boolean isStraightAlongAxis(final BlockState state, final Direction.Axis axis) {
for (final Direction direction : DIRECTIONS) {
final EnumProperty<BusCableBlock.ConnectionType> property = BusCableBlock.FACING_TO_CONNECTION_MAP.get(direction);
if (axis.test(direction)) {
if (state.get(property) != BusCableBlock.ConnectionType.LINK) {
return false;
}
} else {
if (state.get(property) != BusCableBlock.ConnectionType.NONE) {
return false;
}
}
}
return true;
}
///////////////////////////////////////////////////////////////////
public static final class BusCableSupportSide {
public static final ModelProperty<BusCableSupportSide> BUS_CABLE_SUPPORT_PROPERTY = new ModelProperty<>();
private final Direction value;
private BusCableSupportSide(final Direction value) {
this.value = value;
}
public Direction get() {
return value;
}
}
}

View File

@@ -0,0 +1,56 @@
package li.cil.oc2.client.model;
import com.mojang.datafixers.util.Pair;
import li.cil.oc2.api.API;
import net.minecraft.client.renderer.model.*;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.IModelConfiguration;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.client.model.ModelTransformComposition;
import net.minecraftforge.client.model.geometry.IModelGeometry;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;
import java.util.Set;
import java.util.function.Function;
public final class BusCableModel implements IModelGeometry<BusCableModel> {
private static final ResourceLocation BUS_CABLE_STRAIGHT_MODEL = new ResourceLocation(API.MOD_ID, "block/cable_straight");
private static final ResourceLocation BUS_CABLE_SUPPORT_MODEL = new ResourceLocation(API.MOD_ID, "block/cable_support");
private final ModelLoaderRegistry.VanillaProxy proxy;
public BusCableModel(final ModelLoaderRegistry.VanillaProxy proxy) {
this.proxy = proxy;
}
@Override
public IBakedModel bake(final IModelConfiguration owner, final ModelBakery bakery, final Function<RenderMaterial, TextureAtlasSprite> spriteGetter, final IModelTransform modelTransform, final ItemOverrideList overrides, final ResourceLocation modelLocation) {
final IBakedModel bakedBaseModel = proxy.bake(owner, bakery, spriteGetter, modelTransform, overrides, modelLocation);
final IBakedModel[] straightModelByAxis = {
Objects.requireNonNull(bakery.getBakedModel(BUS_CABLE_STRAIGHT_MODEL, new ModelTransformComposition(modelTransform, ModelRotation.X0_Y90), spriteGetter)),
Objects.requireNonNull(bakery.getBakedModel(BUS_CABLE_STRAIGHT_MODEL, new ModelTransformComposition(modelTransform, ModelRotation.X90_Y0), spriteGetter)),
Objects.requireNonNull(bakery.getBakedModel(BUS_CABLE_STRAIGHT_MODEL, modelTransform, spriteGetter))
};
final IBakedModel[] supportModelByFace = {
Objects.requireNonNull(bakery.getBakedModel(BUS_CABLE_SUPPORT_MODEL, new ModelTransformComposition(modelTransform, ModelRotation.X270_Y0), spriteGetter)), // -y
Objects.requireNonNull(bakery.getBakedModel(BUS_CABLE_SUPPORT_MODEL, new ModelTransformComposition(modelTransform, ModelRotation.X90_Y0), spriteGetter)), // +y
Objects.requireNonNull(bakery.getBakedModel(BUS_CABLE_SUPPORT_MODEL, new ModelTransformComposition(modelTransform, ModelRotation.X0_Y180), spriteGetter)), // -z
Objects.requireNonNull(bakery.getBakedModel(BUS_CABLE_SUPPORT_MODEL, modelTransform, spriteGetter)), // +z
Objects.requireNonNull(bakery.getBakedModel(BUS_CABLE_SUPPORT_MODEL, new ModelTransformComposition(modelTransform, ModelRotation.X0_Y90), spriteGetter)), // -x
Objects.requireNonNull(bakery.getBakedModel(BUS_CABLE_SUPPORT_MODEL, new ModelTransformComposition(modelTransform, ModelRotation.X0_Y270), spriteGetter)) // +x
};
return new BusCableBakedModel(bakedBaseModel, straightModelByAxis, supportModelByFace);
}
@Override
public Collection<RenderMaterial> getTextures(final IModelConfiguration owner, final Function<ResourceLocation, IUnbakedModel> modelGetter, final Set<Pair<String, String>> missingTextureErrors) {
final ArrayList<RenderMaterial> textures = new ArrayList<>(proxy.getTextures(owner, modelGetter, missingTextureErrors));
textures.addAll(modelGetter.apply(BUS_CABLE_STRAIGHT_MODEL).getTextures(modelGetter, missingTextureErrors));
textures.addAll(modelGetter.apply(BUS_CABLE_SUPPORT_MODEL).getTextures(modelGetter, missingTextureErrors));
return textures;
}
}

View File

@@ -0,0 +1,18 @@
package li.cil.oc2.client.model;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonObject;
import net.minecraft.resources.IResourceManager;
import net.minecraftforge.client.model.IModelLoader;
import net.minecraftforge.client.model.ModelLoaderRegistry;
public final class BusCableModelLoader implements IModelLoader<BusCableModel> {
@Override
public void onResourceManagerReload(final IResourceManager resourceManager) {
}
@Override
public BusCableModel read(final JsonDeserializationContext context, final JsonObject modelContents) {
return new BusCableModel(ModelLoaderRegistry.VanillaProxy.Loader.INSTANCE.read(context, modelContents));
}
}

View File

@@ -0,0 +1,7 @@
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
package li.cil.oc2.client.model;
import mcp.MethodsReturnNonnullByDefault;
import javax.annotation.ParametersAreNonnullByDefault;

View File

@@ -13,13 +13,15 @@ import li.cil.oc2.common.vm.Allocator;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent;
import net.minecraftforge.fml.event.server.FMLServerStoppedEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
public final class CommonSetup {
public static void run(final FMLCommonSetupEvent event) {
@SubscribeEvent
public static void handleSetupEvent(final FMLCommonSetupEvent event) {
Capabilities.initialize();
Network.setup();
@@ -32,19 +34,19 @@ public final class CommonSetup {
addBuiltinRPCMethodParameterTypeAdapters();
}
public static void handleServerAboutToStart(final FMLServerAboutToStartEvent event) {
///////////////////////////////////////////////////////////////////
private static void handleServerAboutToStart(final FMLServerAboutToStartEvent event) {
BlobStorage.setServer(event.getServer());
FileSystems.initialize(event.getServer());
}
public static void handleServerStopped(final FMLServerStoppedEvent event) {
private static void handleServerStopped(final FMLServerStoppedEvent event) {
BlobStorage.synchronize();
Allocator.resetAndCheckLeaks();
FileSystems.reset();
}
///////////////////////////////////////////////////////////////////
private static void addBuiltinRPCMethodParameterTypeAdapters() {
RPCMethodParameterTypeAdapters.addTypeAdapter(ItemStack.class, new ItemStackJsonSerializer());
RPCMethodParameterTypeAdapters.addTypeAdapter(Direction.class, new DirectionJsonSerializer());

View File

@@ -32,7 +32,7 @@ public final class OpenComputers {
BaseBlockDevices.initialize();
Firmwares.initialize();
FMLJavaModLoadingContext.get().getModEventBus().addListener(CommonSetup::run);
FMLJavaModLoadingContext.get().getModEventBus().addListener(ClientSetup::run);
FMLJavaModLoadingContext.get().getModEventBus().register(CommonSetup.class);
FMLJavaModLoadingContext.get().getModEventBus().register(ClientSetup.class);
}
}

View File

@@ -145,36 +145,11 @@ 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))) {
return ActionResultType.PASS;
if (Wrenches.isWrench(player.getHeldItem(hand)) && tryRemovePlug(state, world, pos, player, hit)) {
return ActionResultType.SUCCESS;
}
final Vector3d localHitPos = hit.getHitVec().subtract(Vector3d.copyCentered(pos));
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) {
return ActionResultType.PASS;
}
final BlockPos neighborPos = pos.offset(side);
if (isCableBlock(world.getBlockState(neighborPos))) {
world.setBlockState(pos, state.with(property, ConnectionType.LINK));
} else {
world.setBlockState(pos, state.with(property, ConnectionType.NONE));
}
onConnectionTypeChanged(world, pos, side);
if (!player.isCreative() && world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)) {
ItemStackUtils.spawnAsEntity(world, pos, new ItemStack(Items.BUS_INTERFACE_ITEM.get()), side).ifPresent(entity -> {
entity.setNoPickupDelay();
entity.onCollideWithPlayer(player);
});
}
WorldUtils.playSound(world, pos, state.getSoundType(), SoundType::getBreakSound);
return ActionResultType.SUCCESS;
return ActionResultType.PASS;
}
@SuppressWarnings("deprecation")
@@ -296,4 +271,33 @@ public final class BusCableBlock extends Block {
busCable.handleConnectionTypeChanged(face);
}
}
private boolean tryRemovePlug(final BlockState state, final World world, final BlockPos pos, final PlayerEntity player, final BlockRayTraceResult hit) {
final Vector3d localHitPos = hit.getHitVec().subtract(Vector3d.copyCentered(pos));
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) {
return false;
}
final BlockPos neighborPos = pos.offset(side);
if (isCableBlock(world.getBlockState(neighborPos))) {
world.setBlockState(pos, state.with(property, ConnectionType.LINK));
} else {
world.setBlockState(pos, state.with(property, ConnectionType.NONE));
}
onConnectionTypeChanged(world, pos, side);
if (!player.isCreative() && world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS)) {
ItemStackUtils.spawnAsEntity(world, pos, new ItemStack(Items.BUS_INTERFACE_ITEM.get()), side).ifPresent(entity -> {
entity.setNoPickupDelay();
entity.onCollideWithPlayer(player);
});
}
WorldUtils.playSound(world, pos, state.getSoundType(), SoundType::getBreakSound);
return true;
}
}

View File

@@ -1,5 +1,6 @@
package li.cil.oc2.common.tileentity;
import li.cil.oc2.client.model.BusCableBakedModel;
import li.cil.oc2.common.block.BusCableBlock;
import li.cil.oc2.common.bus.TileEntityDeviceBusElement;
import li.cil.oc2.common.capabilities.Capabilities;
@@ -8,6 +9,9 @@ import net.minecraft.block.BlockState;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.client.model.data.IModelData;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
@@ -28,6 +32,9 @@ public final class BusCableTileEntity extends AbstractTileEntity {
public void handleNeighborChanged(final BlockPos pos) {
busElement.handleNeighborChanged(pos);
// TODO Remove if https://github.com/MinecraftForge/MinecraftForge/pull/7595 gets merged.
requestModelDataUpdate();
}
public void handleConnectionTypeChanged(final Direction side) {
@@ -76,6 +83,17 @@ public final class BusCableTileEntity extends AbstractTileEntity {
busElement.scheduleScan();
}
// TODO Remove if https://github.com/MinecraftForge/MinecraftForge/pull/7595 gets merged.
@NotNull
@Override
public IModelData getModelData() {
final World world = getWorld();
if (world != null) {
return BusCableBakedModel.getBusCableSupportSideData(world, getPos(), getBlockState(), super.getModelData());
}
return super.getModelData();
}
///////////////////////////////////////////////////////////////////
private final class BusCableBusElement extends TileEntityDeviceBusElement {

View File

@@ -1,26 +1,18 @@
package li.cil.oc2.data;
import com.google.common.collect.Maps;
import li.cil.oc2.api.API;
import li.cil.oc2.common.block.Blocks;
import li.cil.oc2.common.block.BusCableBlock;
import li.cil.oc2.common.item.Items;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.data.DataGenerator;
import net.minecraft.item.Item;
import net.minecraft.state.EnumProperty;
import net.minecraft.state.Property;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Util;
import net.minecraftforge.client.model.generators.*;
import net.minecraftforge.client.model.generators.MultiPartBlockStateBuilder.PartBuilder;
import net.minecraftforge.common.data.ExistingFileHelper;
import net.minecraftforge.fml.RegistryObject;
import java.util.Map;
public class BlockStates extends BlockStateProvider {
public BlockStates(final DataGenerator generator, final ExistingFileHelper existingFileHelper) {
super(generator, API.MOD_ID, existingFileHelper);
@@ -47,66 +39,16 @@ public class BlockStates extends BlockStateProvider {
registerCableStates();
}
private <T extends Comparable<T>> boolean doesStateMatches(final BlockState state, final Map<? extends Property<T>, T> properties) {
return properties.entrySet().stream().allMatch(entry -> state.get(entry.getKey()) == entry.getValue());
}
private void registerCableStates() {
final ModelFile baseModel = models().getExistingFile(new ResourceLocation(API.MOD_ID, "block/cable_base"));
final ModelFile linkModel = models().getExistingFile(new ResourceLocation(API.MOD_ID, "block/cable_link"));
final ModelFile plugModel = models().getExistingFile(new ResourceLocation(API.MOD_ID, "block/cable_plug"));
final ModelFile straightModel = models().getExistingFile(new ResourceLocation(API.MOD_ID, "block/cable_straight"));
final MultiPartBlockStateBuilder builder = getMultipartBuilder(Blocks.BUS_CABLE_BLOCK.get());
// Core element, use straight connections if and only if two opposite ends are
// links and there are no other connections. Since there's no "not" condition we
// have to provide all permutations for regular core piece... this sucks.
final Map<EnumProperty<BusCableBlock.ConnectionType>, BusCableBlock.ConnectionType> straightX = Util.make(Maps.newHashMap(), map -> {
map.put(BusCableBlock.CONNECTION_SOUTH, BusCableBlock.ConnectionType.LINK);
map.put(BusCableBlock.CONNECTION_NORTH, BusCableBlock.ConnectionType.LINK);
map.put(BusCableBlock.CONNECTION_UP, BusCableBlock.ConnectionType.NONE);
map.put(BusCableBlock.CONNECTION_DOWN, BusCableBlock.ConnectionType.NONE);
map.put(BusCableBlock.CONNECTION_EAST, BusCableBlock.ConnectionType.NONE);
map.put(BusCableBlock.CONNECTION_WEST, BusCableBlock.ConnectionType.NONE);
});
final Map<EnumProperty<BusCableBlock.ConnectionType>, BusCableBlock.ConnectionType> straightY = Util.make(Maps.newHashMap(), map -> {
map.put(BusCableBlock.CONNECTION_SOUTH, BusCableBlock.ConnectionType.NONE);
map.put(BusCableBlock.CONNECTION_NORTH, BusCableBlock.ConnectionType.NONE);
map.put(BusCableBlock.CONNECTION_UP, BusCableBlock.ConnectionType.LINK);
map.put(BusCableBlock.CONNECTION_DOWN, BusCableBlock.ConnectionType.LINK);
map.put(BusCableBlock.CONNECTION_EAST, BusCableBlock.ConnectionType.NONE);
map.put(BusCableBlock.CONNECTION_WEST, BusCableBlock.ConnectionType.NONE);
});
final Map<EnumProperty<BusCableBlock.ConnectionType>, BusCableBlock.ConnectionType> straightZ = Util.make(Maps.newHashMap(), map -> {
map.put(BusCableBlock.CONNECTION_SOUTH, BusCableBlock.ConnectionType.NONE);
map.put(BusCableBlock.CONNECTION_NORTH, BusCableBlock.ConnectionType.NONE);
map.put(BusCableBlock.CONNECTION_UP, BusCableBlock.ConnectionType.NONE);
map.put(BusCableBlock.CONNECTION_DOWN, BusCableBlock.ConnectionType.NONE);
map.put(BusCableBlock.CONNECTION_EAST, BusCableBlock.ConnectionType.LINK);
map.put(BusCableBlock.CONNECTION_WEST, BusCableBlock.ConnectionType.LINK);
});
for (final BlockState state : Blocks.BUS_CABLE_BLOCK.get().getStateContainer().getValidStates()) {
final ConfiguredModel.Builder<PartBuilder> model = builder.part();
final PartBuilder part;
if (doesStateMatches(state, straightX)) {
part = model.modelFile(straightModel).addModel();
} else if (doesStateMatches(state, straightY)) {
part = model.modelFile(straightModel).rotationX(90).addModel();
} else if (doesStateMatches(state, straightZ)) {
part = model.modelFile(straightModel).rotationY(90).addModel();
} else {
part = model.modelFile(baseModel).addModel();
}
part
.condition(BusCableBlock.CONNECTION_SOUTH, state.get(BusCableBlock.CONNECTION_SOUTH))
.condition(BusCableBlock.CONNECTION_NORTH, state.get(BusCableBlock.CONNECTION_NORTH))
.condition(BusCableBlock.CONNECTION_EAST, state.get(BusCableBlock.CONNECTION_EAST))
.condition(BusCableBlock.CONNECTION_WEST, state.get(BusCableBlock.CONNECTION_WEST))
.condition(BusCableBlock.CONNECTION_UP, state.get(BusCableBlock.CONNECTION_UP))
.condition(BusCableBlock.CONNECTION_DOWN, state.get(BusCableBlock.CONNECTION_DOWN))
.end();
}
// 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();
BusCableBlock.FACING_TO_CONNECTION_MAP.forEach((direction, connectionType) -> {
final int rotationY = (int) direction.getHorizontalAngle();

File diff suppressed because it is too large Load Diff

View File

@@ -1 +1 @@
{"parent":"block/block","textures":{"east":"oc2:blocks/cable_base/cable_base_east","west":"oc2:blocks/cable_base/cable_base_west","down":"oc2:blocks/cable_base/cable_base_down","north":"oc2:blocks/cable_base/cable_base_north","south":"oc2:blocks/cable_base/cable_base_south","up":"oc2:blocks/cable_base/cable_base_up","particle":"#north"},"elements":[{"from":[6,5,6],"to":[10,6,10],"faces":{"east":{"texture":"east"},"west":{"texture":"west"},"down":{"texture":"down"},"north":{"texture":"north"},"south":{"texture":"south"}}},{"from":[6,6,10],"to":[10,10,11],"faces":{"east":{"texture":"east"},"west":{"texture":"west"},"up":{"texture":"up"},"down":{"texture":"down"},"south":{"texture":"south"}}},{"from":[5,6,6],"to":[11,10,10],"faces":{"east":{"texture":"east"},"west":{"texture":"west"},"up":{"texture":"up"},"down":{"texture":"down"},"north":{"texture":"north"},"south":{"texture":"south"}}},{"from":[6,6,5],"to":[10,10,6],"faces":{"east":{"texture":"east"},"west":{"texture":"west"},"up":{"texture":"up"},"down":{"texture":"down"},"north":{"texture":"north"}}},{"from":[6,10,6],"to":[10,11,10],"faces":{"east":{"texture":"east"},"west":{"texture":"west"},"up":{"texture":"up"},"north":{"texture":"north"},"south":{"texture":"south"}}}]}
{"parent":"block/block","loader":"oc2:bus_cable","textures":{"east":"oc2:blocks/cable_base/cable_base_east","west":"oc2:blocks/cable_base/cable_base_west","down":"oc2:blocks/cable_base/cable_base_down","north":"oc2:blocks/cable_base/cable_base_north","south":"oc2:blocks/cable_base/cable_base_south","up":"oc2:blocks/cable_base/cable_base_up","particle":"#north"},"elements":[{"from":[6,5,6],"to":[10,6,10],"faces":{"east":{"texture":"east"},"west":{"texture":"west"},"down":{"texture":"down"},"north":{"texture":"north"},"south":{"texture":"south"}}},{"from":[6,6,10],"to":[10,10,11],"faces":{"east":{"texture":"east"},"west":{"texture":"west"},"up":{"texture":"up"},"down":{"texture":"down"},"south":{"texture":"south"}}},{"from":[5,6,6],"to":[11,10,10],"faces":{"east":{"texture":"east"},"west":{"texture":"west"},"up":{"texture":"up"},"down":{"texture":"down"},"north":{"texture":"north"},"south":{"texture":"south"}}},{"from":[6,6,5],"to":[10,10,6],"faces":{"east":{"texture":"east"},"west":{"texture":"west"},"up":{"texture":"up"},"down":{"texture":"down"},"north":{"texture":"north"}}},{"from":[6,10,6],"to":[10,11,10],"faces":{"east":{"texture":"east"},"west":{"texture":"west"},"up":{"texture":"up"},"north":{"texture":"north"},"south":{"texture":"south"}}}]}

View File

@@ -0,0 +1 @@
{"parent":"block/block","textures":{"east":"oc2:blocks/cable_support/cable_support_east","west":"oc2:blocks/cable_support/cable_support_west","up":"oc2:blocks/cable_support/cable_support_up","down":"oc2:blocks/cable_support/cable_support_down","north":"oc2:blocks/cable_support/cable_support_north","south":"oc2:blocks/cable_support/cable_support_south","particle":"#north"},"elements":[{"from":[7,7,11],"to":[9,9,16],"faces":{"east":{"texture":"east"},"west":{"texture":"west"},"up":{"texture":"up"},"down":{"texture":"down"},"north":{"texture":"north"},"south":{"texture":"south","cullface":"south"}}}]}

View File

@@ -1,5 +1,5 @@
{
"parent": "oc2:block/cable_base",
"parent": "oc2:block/cable_straight",
"display": {
"gui": {
"rotation": [

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 B