From 7d0e48c08d09c61800218372e9a32caa536e86b6 Mon Sep 17 00:00:00 2001 From: M-W-K <31022105+M-W-K@users.noreply.github.com> Date: Wed, 17 Dec 2025 14:30:25 -0700 Subject: [PATCH 1/2] Separate render rewrite --- .../api/block/UnlistedByteProperty.java | 36 ++ .../api/block/UnlistedFloatProperty.java | 36 ++ .../api/block/UnlistedPropertyMaterial.java | 37 ++ src/main/java/gregtech/api/cover/Cover.java | 5 + .../java/gregtech/api/cover/CoverBase.java | 14 + .../gregtech/api/pipenet/block/BlockPipe.java | 98 ++- .../gregtech/api/pipenet/block/IPipeType.java | 7 + .../api/pipenet/block/ItemBlockPipe.java | 5 + .../block/material/BlockMaterialPipe.java | 43 +- .../block/material/ItemBlockMaterialPipe.java | 7 +- .../material/TileEntityMaterialPipeBase.java | 14 +- .../pipenet/block/simple/BlockSimplePipe.java | 42 -- .../gregtech/api/pipenet/tile/IPipeTile.java | 10 + .../tile/PipeCoverableImplementation.java | 13 + .../api/pipenet/tile/TileEntityPipeBase.java | 49 +- .../java/gregtech/api/util/GTUtility.java | 125 ++++ .../api/util/collection/ListHashSet.java | 214 +++++++ .../api/util/collection/MapFunction.java | 8 + .../api/util/collection/PairedBiMap.java | 139 +++++ .../api/util/collection/WeakHashSet.java | 136 +++++ .../java/gregtech/client/ClientProxy.java | 22 +- .../renderer/handler/FacadeRenderer.java | 34 ++ .../renderer/pipe/AbstractPipeModel.java | 162 +++++ .../renderer/pipe/ActivablePipeModel.java | 114 ++++ .../client/renderer/pipe/CableModel.java | 112 ++++ .../client/renderer/pipe/CableRenderer.java | 108 ---- .../renderer/pipe/FluidPipeRenderer.java | 69 --- .../renderer/pipe/ItemPipeRenderer.java | 58 -- .../renderer/pipe/LaserPipeRenderer.java | 102 ---- .../renderer/pipe/OpticalPipeRenderer.java | 56 -- .../client/renderer/pipe/PipeItemModel.java | 105 ++++ .../client/renderer/pipe/PipeModel.java | 85 +++ .../renderer/pipe/PipeModelRedirector.java | 123 ++++ .../renderer/pipe/PipeModelRegistry.java | 235 ++++++++ .../renderer/pipe/PipeRenderProperties.java | 24 + .../client/renderer/pipe/PipeRenderer.java | 570 ------------------ .../renderer/pipe/cache/ActivableSQC.java | 86 +++ .../renderer/pipe/cache/BlockableSQC.java | 100 +++ .../renderer/pipe/cache/ColorQuadCache.java | 39 ++ .../renderer/pipe/cache/ExtraCappedSQC.java | 80 +++ .../renderer/pipe/cache/RestrictiveSQC.java | 86 +++ .../pipe/cache/StructureQuadCache.java | 119 ++++ .../renderer/pipe/cache/SubListAddress.java | 14 + .../renderer/pipe/cover/CoverRenderer.java | 17 + .../pipe/cover/CoverRendererBuilder.java | 148 +++++ .../pipe/cover/CoverRendererPackage.java | 82 +++ .../pipe/cover/CoverRendererValues.java | 38 ++ .../client/renderer/pipe/quad/ColorData.java | 21 + .../pipe/quad/OverlayLayerDefinition.java | 18 + .../renderer/pipe/quad/PipeQuadHelper.java | 151 +++++ .../client/renderer/pipe/quad/QuadHelper.java | 117 ++++ .../pipe/quad/RecolorableBakedQuad.java | 48 ++ .../client/renderer/pipe/quad/UVMapper.java | 45 ++ .../renderer/pipe/util/ActivableCacheKey.java | 29 + .../client/renderer/pipe/util/CacheKey.java | 54 ++ .../pipe/util/MaterialModelOverride.java | 28 + .../pipe/util/MaterialModelSupplier.java | 14 + .../renderer/pipe/util/SpriteInformation.java | 16 + .../pipe/util/SpriteInformationWrapper.java | 39 ++ .../client/renderer/texture/Textures.java | 198 +++--- .../texture/cube/SimpleOverlayRenderer.java | 8 + .../gregtech/common/blocks/BlockFrame.java | 2 +- .../gregtech/common/blocks/MetaBlocks.java | 84 ++- .../gregtech/common/covers/CoverConveyor.java | 25 + .../common/covers/CoverDigitalInterface.java | 11 + .../gregtech/common/covers/CoverFacade.java | 9 + .../common/covers/CoverFluidFilter.java | 7 + .../common/covers/CoverFluidVoiding.java | 13 + .../covers/CoverFluidVoidingAdvanced.java | 7 + .../common/covers/CoverInfiniteWater.java | 7 + .../common/covers/CoverItemFilter.java | 7 + .../common/covers/CoverItemVoiding.java | 13 + .../covers/CoverItemVoidingAdvanced.java | 7 + .../common/covers/CoverMachineController.java | 7 + .../gregtech/common/covers/CoverPump.java | 24 + .../common/covers/CoverRoboticArm.java | 12 + .../gregtech/common/covers/CoverScreen.java | 7 + .../gregtech/common/covers/CoverShutter.java | 14 +- .../common/covers/CoverSolarPanel.java | 7 + .../gregtech/common/covers/CoverStorage.java | 7 + .../detector/CoverDetectorActivity.java | 7 + .../CoverDetectorActivityAdvanced.java | 7 + .../covers/detector/CoverDetectorEnergy.java | 7 + .../detector/CoverDetectorEnergyAdvanced.java | 7 + .../covers/detector/CoverDetectorFluid.java | 7 + .../detector/CoverDetectorFluidAdvanced.java | 7 + .../covers/detector/CoverDetectorItem.java | 7 + .../detector/CoverDetectorItemAdvanced.java | 7 + .../detector/CoverDetectorMaintenance.java | 7 + .../covers/ender/CoverEnderFluidLink.java | 7 + .../common/pipelike/cable/BlockCable.java | 30 +- .../common/pipelike/cable/Insulation.java | 11 + .../pipelike/cable/tile/TileEntityCable.java | 2 +- .../pipelike/fluidpipe/BlockFluidPipe.java | 28 - .../pipelike/fluidpipe/FluidPipeType.java | 19 + .../pipelike/itempipe/BlockItemPipe.java | 32 - .../pipelike/itempipe/ItemPipeType.java | 20 + .../common/pipelike/laser/BlockLaserPipe.java | 35 +- .../common/pipelike/laser/LaserPipeType.java | 11 + .../laser/tile/TileEntityLaserPipe.java | 10 + .../pipelike/optical/BlockOpticalPipe.java | 30 +- .../pipelike/optical/OpticalPipeType.java | 11 + .../optical/tile/TileEntityOpticalPipe.java | 10 + .../{insulation_5.png => insulation_full.png} | Bin .../blocks/pipe/blocked/pipe_blocked_dl.png | Bin 283 -> 0 bytes .../blocks/pipe/blocked/pipe_blocked_down.png | Bin 220 -> 0 bytes .../blocks/pipe/blocked/pipe_blocked_dr.png | Bin 268 -> 0 bytes .../blocks/pipe/blocked/pipe_blocked_left.png | Bin 224 -> 0 bytes .../blocks/pipe/blocked/pipe_blocked_lr.png | Bin 281 -> 0 bytes .../blocks/pipe/blocked/pipe_blocked_nd.png | Bin 331 -> 0 bytes .../blocks/pipe/blocked/pipe_blocked_nl.png | Bin 319 -> 0 bytes .../blocks/pipe/blocked/pipe_blocked_nr.png | Bin 322 -> 0 bytes .../blocks/pipe/blocked/pipe_blocked_nu.png | Bin 334 -> 0 bytes .../blocks/pipe/blocked/pipe_blocked_rd.png | Bin 268 -> 0 bytes .../pipe/blocked/pipe_blocked_right.png | Bin 220 -> 0 bytes .../blocks/pipe/blocked/pipe_blocked_ud.png | Bin 278 -> 0 bytes .../blocks/pipe/blocked/pipe_blocked_ul.png | Bin 270 -> 0 bytes .../blocks/pipe/blocked/pipe_blocked_up.png | Bin 222 -> 0 bytes .../blocks/pipe/blocked/pipe_blocked_ur.png | Bin 279 -> 0 bytes .../pipe/{blocked => }/pipe_blocked.png | Bin .../textures/blocks/pipe/pipe_laser_in.png | Bin 146 -> 219 bytes 121 files changed, 3857 insertions(+), 1344 deletions(-) create mode 100644 src/main/java/gregtech/api/block/UnlistedByteProperty.java create mode 100644 src/main/java/gregtech/api/block/UnlistedFloatProperty.java create mode 100644 src/main/java/gregtech/api/block/UnlistedPropertyMaterial.java delete mode 100644 src/main/java/gregtech/api/pipenet/block/simple/BlockSimplePipe.java create mode 100644 src/main/java/gregtech/api/util/collection/ListHashSet.java create mode 100644 src/main/java/gregtech/api/util/collection/MapFunction.java create mode 100644 src/main/java/gregtech/api/util/collection/PairedBiMap.java create mode 100644 src/main/java/gregtech/api/util/collection/WeakHashSet.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/AbstractPipeModel.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/ActivablePipeModel.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/CableModel.java delete mode 100644 src/main/java/gregtech/client/renderer/pipe/CableRenderer.java delete mode 100644 src/main/java/gregtech/client/renderer/pipe/FluidPipeRenderer.java delete mode 100644 src/main/java/gregtech/client/renderer/pipe/ItemPipeRenderer.java delete mode 100644 src/main/java/gregtech/client/renderer/pipe/LaserPipeRenderer.java delete mode 100644 src/main/java/gregtech/client/renderer/pipe/OpticalPipeRenderer.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/PipeItemModel.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/PipeModel.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/PipeModelRedirector.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/PipeModelRegistry.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/PipeRenderProperties.java delete mode 100644 src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/cache/ActivableSQC.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/cache/BlockableSQC.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/cache/ColorQuadCache.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/cache/ExtraCappedSQC.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/cache/RestrictiveSQC.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/cache/StructureQuadCache.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/cache/SubListAddress.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/cover/CoverRenderer.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererBuilder.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererPackage.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererValues.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/quad/ColorData.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/quad/OverlayLayerDefinition.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/quad/PipeQuadHelper.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/quad/QuadHelper.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/quad/RecolorableBakedQuad.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/quad/UVMapper.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/util/ActivableCacheKey.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/util/CacheKey.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/util/MaterialModelOverride.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/util/MaterialModelSupplier.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/util/SpriteInformation.java create mode 100644 src/main/java/gregtech/client/renderer/pipe/util/SpriteInformationWrapper.java rename src/main/resources/assets/gregtech/textures/blocks/cable/{insulation_5.png => insulation_full.png} (100%) delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_dl.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_down.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_dr.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_left.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_lr.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_nd.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_nl.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_nr.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_nu.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_rd.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_right.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_ud.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_ul.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_up.png delete mode 100644 src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_ur.png rename src/main/resources/assets/gregtech/textures/blocks/pipe/{blocked => }/pipe_blocked.png (100%) diff --git a/src/main/java/gregtech/api/block/UnlistedByteProperty.java b/src/main/java/gregtech/api/block/UnlistedByteProperty.java new file mode 100644 index 00000000000..5e90f08b40a --- /dev/null +++ b/src/main/java/gregtech/api/block/UnlistedByteProperty.java @@ -0,0 +1,36 @@ +package gregtech.api.block; + +import net.minecraftforge.common.property.IUnlistedProperty; + +import org.jetbrains.annotations.NotNull; + +public class UnlistedByteProperty implements IUnlistedProperty { + + private final String name; + + public UnlistedByteProperty(@NotNull String name) { + this.name = name; + } + + @NotNull + @Override + public String getName() { + return this.name; + } + + @Override + public boolean isValid(Byte value) { + return true; + } + + @NotNull + @Override + public Class getType() { + return Byte.class; + } + + @Override + public String valueToString(@NotNull Byte value) { + return value.toString(); + } +} diff --git a/src/main/java/gregtech/api/block/UnlistedFloatProperty.java b/src/main/java/gregtech/api/block/UnlistedFloatProperty.java new file mode 100644 index 00000000000..e35f2e1a396 --- /dev/null +++ b/src/main/java/gregtech/api/block/UnlistedFloatProperty.java @@ -0,0 +1,36 @@ +package gregtech.api.block; + +import net.minecraftforge.common.property.IUnlistedProperty; + +import org.jetbrains.annotations.NotNull; + +public class UnlistedFloatProperty implements IUnlistedProperty { + + private final String name; + + public UnlistedFloatProperty(@NotNull String name) { + this.name = name; + } + + @NotNull + @Override + public String getName() { + return this.name; + } + + @Override + public boolean isValid(Float value) { + return true; + } + + @NotNull + @Override + public Class getType() { + return Float.class; + } + + @Override + public String valueToString(@NotNull Float value) { + return value.toString(); + } +} diff --git a/src/main/java/gregtech/api/block/UnlistedPropertyMaterial.java b/src/main/java/gregtech/api/block/UnlistedPropertyMaterial.java new file mode 100644 index 00000000000..df9efb767e1 --- /dev/null +++ b/src/main/java/gregtech/api/block/UnlistedPropertyMaterial.java @@ -0,0 +1,37 @@ +package gregtech.api.block; + +import gregtech.api.unification.material.Material; + +import net.minecraftforge.common.property.IUnlistedProperty; + +import org.jetbrains.annotations.NotNull; + +public class UnlistedPropertyMaterial implements IUnlistedProperty { + + private final String name; + + public UnlistedPropertyMaterial(@NotNull String name) { + this.name = name; + } + + @NotNull + @Override + public String getName() { + return name; + } + + @Override + public boolean isValid(Material value) { + return true; + } + + @Override + public Class getType() { + return Material.class; + } + + @Override + public String valueToString(Material value) { + return value.toString(); + } +} diff --git a/src/main/java/gregtech/api/cover/Cover.java b/src/main/java/gregtech/api/cover/Cover.java index 0257544c99a..389e763850a 100644 --- a/src/main/java/gregtech/api/cover/Cover.java +++ b/src/main/java/gregtech/api/cover/Cover.java @@ -1,5 +1,6 @@ package gregtech.api.cover; +import gregtech.client.renderer.pipe.cover.CoverRenderer; import gregtech.client.utils.BloomEffectUtil; import net.minecraft.entity.player.EntityPlayer; @@ -248,6 +249,10 @@ void renderCoverPlate(@NotNull CCRenderState renderState, @NotNull Matrix4 trans @NotNull IVertexOperation[] pipeline, @NotNull Cuboid6 plateBox, @NotNull BlockRenderLayer layer); + @SideOnly(Side.CLIENT) + @NotNull + CoverRenderer getRenderer(); + default boolean canRenderBackside() { return true; } diff --git a/src/main/java/gregtech/api/cover/CoverBase.java b/src/main/java/gregtech/api/cover/CoverBase.java index 8382a8a1d4b..1583e5be0d3 100644 --- a/src/main/java/gregtech/api/cover/CoverBase.java +++ b/src/main/java/gregtech/api/cover/CoverBase.java @@ -2,6 +2,7 @@ import gregtech.api.GTValues; import gregtech.api.metatileentity.MetaTileEntity; +import gregtech.client.renderer.pipe.cover.CoverRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; @@ -19,6 +20,7 @@ import codechicken.lib.vec.Cuboid6; import codechicken.lib.vec.Matrix4; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; @@ -29,6 +31,9 @@ public abstract class CoverBase implements Cover { private final CoverableView coverableView; private final EnumFacing attachedSide; + @SideOnly(Side.CLIENT) + protected @Nullable CoverRenderer renderer; + public CoverBase(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, @NotNull EnumFacing attachedSide) { this.definition = definition; @@ -79,6 +84,15 @@ public void renderCoverPlate(@NotNull CCRenderState renderState, @NotNull Matrix } } + @Override + @SideOnly(Side.CLIENT) + public @NotNull CoverRenderer getRenderer() { + if (renderer == null) renderer = buildRenderer(); + return renderer; + } + + protected abstract CoverRenderer buildRenderer(); + @SideOnly(Side.CLIENT) protected @NotNull TextureAtlasSprite getPlateSprite() { return Textures.VOLTAGE_CASINGS[GTValues.LV].getSpriteOnSide(SimpleSidedCubeRenderer.RenderSide.SIDE); diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java index 24bd0ce911e..afbee08526e 100644 --- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java @@ -14,6 +14,8 @@ import gregtech.api.pipenet.tile.PipeCoverableImplementation; import gregtech.api.pipenet.tile.TileEntityPipeBase; import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.PipeRenderProperties; +import gregtech.client.renderer.pipe.cover.CoverRendererPackage; import gregtech.common.ConfigHolder; import gregtech.common.blocks.BlockFrame; import gregtech.common.blocks.MetaBlocks; @@ -23,9 +25,12 @@ import net.minecraft.block.Block; import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.SoundType; +import net.minecraft.block.properties.PropertyBool; import net.minecraft.block.state.BlockFaceShape; +import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; @@ -46,6 +51,7 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; +import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -53,11 +59,13 @@ import codechicken.lib.raytracer.IndexedCuboid6; import codechicken.lib.raytracer.RayTracer; import codechicken.lib.vec.Cuboid6; +import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.Collections; +import java.util.EnumMap; import java.util.List; import java.util.Random; @@ -68,6 +76,28 @@ public abstract class BlockPipe & IPipeType>> extends BuiltInRenderBlock implements ITileEntityProvider, IFacadeWrapper, IBlockAppearance { + public static final PropertyBool NORTH = PropertyBool.create("north"); + public static final PropertyBool EAST = PropertyBool.create("east"); + public static final PropertyBool SOUTH = PropertyBool.create("south"); + public static final PropertyBool WEST = PropertyBool.create("west"); + public static final PropertyBool UP = PropertyBool.create("up"); + public static final PropertyBool DOWN = PropertyBool.create("down"); + + public static final EnumMap FACINGS = buildFacings(); + + private static @NotNull EnumMap buildFacings() { + EnumMap map = new EnumMap<>(EnumFacing.class); + map.put(EnumFacing.NORTH, NORTH); + map.put(EnumFacing.EAST, EAST); + map.put(EnumFacing.SOUTH, SOUTH); + map.put(EnumFacing.WEST, WEST); + map.put(EnumFacing.UP, UP); + map.put(EnumFacing.DOWN, DOWN); + return map; + } + + public static final PropertyBool FRAMED = PropertyBool.create("framed"); + protected final ThreadLocal> tileEntities = new ThreadLocal<>(); public BlockPipe() { @@ -146,7 +176,7 @@ public ItemStack getItem(@NotNull World world, @NotNull BlockPos pos, @NotNull I protected abstract NodeDataType getFallbackType(); // TODO this has no reason to need an ItemStack parameter - public abstract PipeType getItemPipeType(ItemStack itemStack); + public abstract PipeType getPipeType(); public abstract void setTileEntityData(TileEntityPipeBase pipeTile, ItemStack itemStack); @@ -352,7 +382,7 @@ public boolean onPipeActivated(World world, IBlockState state, BlockPos pos, Ent IBlockState blockStateAtSide = world.getBlockState(pos.offset(side)); if (blockStateAtSide.getBlock() instanceof BlockFrame) { ItemBlockPipe itemBlockPipe = (ItemBlockPipe) itemStack.getItem(); - if (itemBlockPipe.blockPipe.getItemPipeType(itemStack) == getItemPipeType(itemStack)) { + if (itemBlockPipe.blockPipe.getPipeType() == getPipeType()) { BlockFrame frameBlock = (BlockFrame) blockStateAtSide.getBlock(); boolean wasPlaced = frameBlock.replaceWithFramedPipe(world, pos.offset(side), blockStateAtSide, entityPlayer, itemStack, side); @@ -734,4 +764,68 @@ public PipeConnectionData(EnumFacing side) { this.side = side; } } + + @Override + public int getMetaFromState(@NotNull IBlockState state) { + return 0; + } + + @Override + protected @NotNull BlockStateContainer createBlockState() { + return constructState(new BlockStateContainer.Builder(this)) + .add(NORTH, SOUTH, EAST, WEST, UP, DOWN, FRAMED) + .build(); + } + + protected @NotNull BlockStateContainer.Builder constructState(BlockStateContainer.@NotNull Builder builder) { + return builder.add(PipeRenderProperties.THICKNESS_PROPERTY).add(PipeRenderProperties.CLOSED_MASK_PROPERTY) + .add(PipeRenderProperties.BLOCKED_MASK_PROPERTY).add(PipeRenderProperties.COLOR_PROPERTY) + .add(PipeRenderProperties.FRAME_MATERIAL_PROPERTY).add(PipeRenderProperties.FRAME_MASK_PROPERTY) + .add(CoverRendererPackage.CRP_PROPERTY); + } + + @SuppressWarnings("deprecation") + @Override + public @NotNull IBlockState getActualState(@NotNull IBlockState state, @NotNull IBlockAccess worldIn, + @NotNull BlockPos pos) { + var tile = getPipeTileEntity(worldIn, pos); + if (tile == null) return state; + state = writeConnectionMask(state, tile.getCoverAdjustedConnectionMask()); + return state.withProperty(FRAMED, tile.getFrameMaterial() != null); + } + + public static IBlockState writeConnectionMask(@NotNull IBlockState state, byte connectionMask) { + for (EnumFacing facing : EnumFacing.VALUES) { + state = state.withProperty(FACINGS.get(facing), GTUtility.evalMask(facing, connectionMask)); + } + return state; + } + + public static byte readConnectionMask(@NotNull IBlockState state) { + byte mask = 0; + for (EnumFacing facing : EnumFacing.VALUES) { + if (state.getValue(FACINGS.get(facing))) { + mask |= (byte) (1 << facing.ordinal()); + } + } + return mask; + } + + @Override + public @NotNull IBlockState getExtendedState(@NotNull IBlockState state, @NotNull IBlockAccess world, + @NotNull BlockPos pos) { + var tile = getPipeTileEntity(world, pos); + if (tile == null) return state; + else return tile.getRenderInformation((IExtendedBlockState) state.getActualState(world, pos)); + } + + @SideOnly(Side.CLIENT) + @Override + protected Pair getParticleTexture(World world, BlockPos blockPos) { + var tile = getPipeTileEntity(world, blockPos); + if (tile != null) { + return getPipeType().getModel().getParticleTexture(tile.getPaintingColor(), null); + } + return null; + } } diff --git a/src/main/java/gregtech/api/pipenet/block/IPipeType.java b/src/main/java/gregtech/api/pipenet/block/IPipeType.java index c0b4caf8121..bac2c4aad7d 100644 --- a/src/main/java/gregtech/api/pipenet/block/IPipeType.java +++ b/src/main/java/gregtech/api/pipenet/block/IPipeType.java @@ -1,6 +1,10 @@ package gregtech.api.pipenet.block; +import gregtech.client.renderer.pipe.PipeModelRedirector; + import net.minecraft.util.IStringSerializable; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; public interface IPipeType extends IStringSerializable { @@ -9,4 +13,7 @@ public interface IPipeType extends IStringSerializable { NodeDataType modifyProperties(NodeDataType baseProperties); boolean isPaintable(); + + @SideOnly(Side.CLIENT) + PipeModelRedirector getModel(); } diff --git a/src/main/java/gregtech/api/pipenet/block/ItemBlockPipe.java b/src/main/java/gregtech/api/pipenet/block/ItemBlockPipe.java index 30b283a9b3f..3f8ff337e0d 100644 --- a/src/main/java/gregtech/api/pipenet/block/ItemBlockPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/ItemBlockPipe.java @@ -24,6 +24,11 @@ public ItemBlockPipe(BlockPipe block) { setHasSubtypes(true); } + @Override + public @NotNull BlockPipe getBlock() { + return (BlockPipe) super.getBlock(); + } + @Override public int getMetadata(int damage) { return damage; diff --git a/src/main/java/gregtech/api/pipenet/block/material/BlockMaterialPipe.java b/src/main/java/gregtech/api/pipenet/block/material/BlockMaterialPipe.java index 05d1ca26269..dc2696d734a 100644 --- a/src/main/java/gregtech/api/pipenet/block/material/BlockMaterialPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/material/BlockMaterialPipe.java @@ -1,6 +1,5 @@ package gregtech.api.pipenet.block.material; -import gregtech.api.GTValues; import gregtech.api.pipenet.PipeNet; import gregtech.api.pipenet.WorldPipeNet; import gregtech.api.pipenet.block.BlockPipe; @@ -10,21 +9,20 @@ import gregtech.api.unification.material.Material; import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.unification.ore.OrePrefix; -import gregtech.client.renderer.pipe.PipeRenderer; -import gregtech.common.blocks.MetaBlocks; +import gregtech.client.renderer.pipe.PipeRenderProperties; -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.block.state.BlockStateContainer; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.creativetab.CreativeTabs; -import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.util.NonNullList; -import net.minecraft.util.ResourceLocation; -import net.minecraftforge.client.model.ModelLoader; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import com.google.common.base.Preconditions; +import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; import java.util.*; @@ -45,7 +43,7 @@ public BlockMaterialPipe(@NotNull PipeType pipeType, @NotNull MaterialRegistry r } public boolean isValidPipeMaterial(Material material) { - return !getItemPipeType(getItem(material)).getOrePrefix().isIgnored(material); + return !getPipeType().getOrePrefix().isIgnored(material); } public void addPipeMaterial(Material material, NodeDataType pipeProperties) { @@ -122,7 +120,7 @@ public OrePrefix getPrefix() { return pipeType.getOrePrefix(); } - public PipeType getItemPipeType(ItemStack is) { + public PipeType getPipeType() { return pipeType; } @@ -131,20 +129,19 @@ public MaterialRegistry getMaterialRegistry() { return registry; } - @SideOnly(Side.CLIENT) @NotNull - public abstract PipeRenderer getPipeRenderer(); - - public void onModelRegister() { - ModelLoader.setCustomMeshDefinition(Item.getItemFromBlock(this), stack -> getPipeRenderer().getModelLocation()); - for (IBlockState state : this.getBlockState().getValidStates()) { - ModelResourceLocation resourceLocation = new ModelResourceLocation( - new ResourceLocation(GTValues.MODID, // force pipe models to always be GT's - Objects.requireNonNull(this.getRegistryName()).getPath()), - MetaBlocks.statePropertiesToString(state.getProperties())); - // noinspection ConstantConditions - ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(this), - this.getMetaFromState(state), resourceLocation); + @Override + protected BlockStateContainer.Builder constructState(BlockStateContainer.@NotNull Builder builder) { + return super.constructState(builder).add(PipeRenderProperties.MATERIAL_PROPERTY); + } + + @SideOnly(Side.CLIENT) + @Override + protected Pair getParticleTexture(World world, BlockPos blockPos) { + var tile = (TileEntityMaterialPipeBase) getPipeTileEntity(world, blockPos); + if (tile != null) { + return getPipeType().getModel().getParticleTexture(tile.getPaintingColor(), tile.getPipeMaterial()); } + return null; } } diff --git a/src/main/java/gregtech/api/pipenet/block/material/ItemBlockMaterialPipe.java b/src/main/java/gregtech/api/pipenet/block/material/ItemBlockMaterialPipe.java index 70467ecf809..e61d76795bf 100644 --- a/src/main/java/gregtech/api/pipenet/block/material/ItemBlockMaterialPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/material/ItemBlockMaterialPipe.java @@ -14,10 +14,15 @@ public ItemBlockMaterialPipe(BlockMaterialPipe block) super(block); } + @Override + public @NotNull BlockMaterialPipe getBlock() { + return (BlockMaterialPipe) super.getBlock(); + } + @NotNull @Override public String getItemStackDisplayName(@NotNull ItemStack stack) { - PipeType pipeType = blockPipe.getItemPipeType(stack); + PipeType pipeType = blockPipe.getPipeType(); Material material = ((BlockMaterialPipe) blockPipe).getItemMaterial(stack); return material == null ? " " : pipeType.getOrePrefix().getLocalNameForItem(material); } diff --git a/src/main/java/gregtech/api/pipenet/block/material/TileEntityMaterialPipeBase.java b/src/main/java/gregtech/api/pipenet/block/material/TileEntityMaterialPipeBase.java index d5164c30d11..bef97d09b11 100644 --- a/src/main/java/gregtech/api/pipenet/block/material/TileEntityMaterialPipeBase.java +++ b/src/main/java/gregtech/api/pipenet/block/material/TileEntityMaterialPipeBase.java @@ -6,9 +6,14 @@ import gregtech.api.unification.material.Material; import gregtech.api.unification.material.Materials; import gregtech.api.unification.material.registry.MaterialRegistry; +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.PipeRenderProperties; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.PacketBuffer; +import net.minecraftforge.common.property.IExtendedBlockState; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; @@ -40,7 +45,7 @@ public void setPipeData(BlockPipe pipeBlock, PipeType @Override public int getDefaultPaintingColor() { - return pipeMaterial == null ? super.getDefaultPaintingColor() : pipeMaterial.getMaterialRGB(); + return GTUtility.convertRGBtoARGB(getPipeMaterial().getMaterialRGB()); } @Override @@ -100,4 +105,11 @@ public void receiveCustomData(int discriminator, PacketBuffer buf) { scheduleChunkForRenderUpdate(); } } + + @Override + @SideOnly(Side.CLIENT) + public IExtendedBlockState getRenderInformation(IExtendedBlockState state) { + return super.getRenderInformation(state).withProperty(PipeRenderProperties.MATERIAL_PROPERTY, + getPipeMaterial()); + } } diff --git a/src/main/java/gregtech/api/pipenet/block/simple/BlockSimplePipe.java b/src/main/java/gregtech/api/pipenet/block/simple/BlockSimplePipe.java deleted file mode 100644 index 52e344243c8..00000000000 --- a/src/main/java/gregtech/api/pipenet/block/simple/BlockSimplePipe.java +++ /dev/null @@ -1,42 +0,0 @@ -package gregtech.api.pipenet.block.simple; - -import gregtech.api.pipenet.PipeNet; -import gregtech.api.pipenet.WorldPipeNet; -import gregtech.api.pipenet.block.BlockPipe; -import gregtech.api.pipenet.block.IPipeType; -import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.api.pipenet.tile.TileEntityPipeBase; - -import net.minecraft.item.ItemStack; - -public abstract class BlockSimplePipe & IPipeType, NodeDataType, - WorldPipeNetType extends WorldPipeNet>> - extends BlockPipe { - - @Override - public NodeDataType createProperties(IPipeTile pipeTile) { - return createProperties(pipeTile.getPipeType()); - } - - @Override - public NodeDataType createItemProperties(ItemStack itemStack) { - return createProperties(getItemPipeType(itemStack)); - } - - protected abstract NodeDataType createProperties(PipeType pipeType); - - @Override - public ItemStack getDropItem(IPipeTile pipeTile) { - return new ItemStack(this, 1, pipeTile.getPipeType().ordinal()); - } - - @Override - public PipeType getItemPipeType(ItemStack itemStack) { - return getPipeTypeClass().getEnumConstants()[itemStack.getMetadata()]; - } - - @Override - public void setTileEntityData(TileEntityPipeBase pipeTile, ItemStack itemStack) { - pipeTile.setPipeData(this, getItemPipeType(itemStack)); - } -} diff --git a/src/main/java/gregtech/api/pipenet/tile/IPipeTile.java b/src/main/java/gregtech/api/pipenet/tile/IPipeTile.java index 486ddfa6d8b..b951191b22d 100644 --- a/src/main/java/gregtech/api/pipenet/tile/IPipeTile.java +++ b/src/main/java/gregtech/api/pipenet/tile/IPipeTile.java @@ -10,7 +10,11 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.property.IExtendedBlockState; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; +import org.jetbrains.annotations.MustBeInvokedByOverriders; import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; @@ -97,4 +101,10 @@ default boolean canHaveBlockedFaces() { boolean isValidTile(); void scheduleChunkForRenderUpdate(); + + byte getCoverAdjustedConnectionMask(); + + @SideOnly(Side.CLIENT) + @MustBeInvokedByOverriders + IExtendedBlockState getRenderInformation(IExtendedBlockState state); } diff --git a/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java b/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java index df20bd54bfb..1a36b4344be 100644 --- a/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java +++ b/src/main/java/gregtech/api/pipenet/tile/PipeCoverableImplementation.java @@ -5,6 +5,7 @@ import gregtech.api.cover.CoverSaveHandler; import gregtech.api.pipenet.block.BlockPipe; import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.cover.CoverRendererPackage; import gregtech.common.ConfigHolder; import net.minecraft.item.ItemStack; @@ -16,6 +17,8 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -297,4 +300,14 @@ public boolean isValid() { public T getCapability(Capability capability, EnumFacing side) { return holder.getCapabilityInternal(capability, side); } + + @SideOnly(Side.CLIENT) + public CoverRendererPackage createPackage() { + if (covers.isEmpty()) return CoverRendererPackage.EMPTY; + CoverRendererPackage rendererPackage = new CoverRendererPackage(shouldRenderCoverBackSides()); + for (var cover : covers.entrySet()) { + rendererPackage.addRenderer(cover.getValue().getRenderer(), cover.getKey()); + } + return rendererPackage; + } } diff --git a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java index bce5904f2dd..9cf1aa77779 100644 --- a/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java +++ b/src/main/java/gregtech/api/pipenet/tile/TileEntityPipeBase.java @@ -10,6 +10,9 @@ import gregtech.api.pipenet.block.BlockPipe; import gregtech.api.pipenet.block.IPipeType; import gregtech.api.unification.material.Material; +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.PipeRenderProperties; +import gregtech.client.renderer.pipe.cover.CoverRendererPackage; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; @@ -24,7 +27,10 @@ import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.util.Constants.NBT; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.MustBeInvokedByOverriders; import org.jetbrains.annotations.NotNull; @@ -199,11 +205,7 @@ public int getDefaultPaintingColor() { @Override public boolean isConnected(EnumFacing side) { - return isConnected(connections, side); - } - - public static boolean isConnected(int connections, EnumFacing side) { - return (connections & 1 << side.getIndex()) > 0; + return GTUtility.evalMask(side, connections); } @Override @@ -568,4 +570,41 @@ public void doExplosion(float explosionPower) { getWorld().createExplosion(null, getPos().getX() + 0.5, getPos().getY() + 0.5, getPos().getZ() + 0.5, explosionPower, false); } + + @Override + public byte getCoverAdjustedConnectionMask() { + int connectionMask = this.connections; + for (EnumFacing facing : EnumFacing.VALUES) { + Cover cover = getCoverableImplementation().getCoverAtSide(facing); + if (cover != null) { + if (cover.shouldAutoConnectToPipes()) connectionMask |= 1 << facing.ordinal(); + } + } + return (byte) connectionMask; + } + + /** + * Note - the block corresponding to this tile entity must register any new unlisted properties to the default + * state. + */ + @SideOnly(Side.CLIENT) + @MustBeInvokedByOverriders + @Override + public IExtendedBlockState getRenderInformation(IExtendedBlockState state) { + byte frameMask = 0; + for (EnumFacing facing : EnumFacing.VALUES) { + Cover cover = getCoverableImplementation().getCoverAtSide(facing); + if (cover != null) { + frameMask |= (byte) (1 << facing.ordinal()); + } + } + frameMask = (byte) ~frameMask; + return state.withProperty(PipeRenderProperties.THICKNESS_PROPERTY, pipeType.getThickness()) + .withProperty(PipeRenderProperties.CLOSED_MASK_PROPERTY, (byte) (getVisualConnections() >> 6)) + .withProperty(PipeRenderProperties.BLOCKED_MASK_PROPERTY, (byte) blockedConnections) + .withProperty(PipeRenderProperties.COLOR_PROPERTY, getPaintingColor()) + .withProperty(PipeRenderProperties.FRAME_MATERIAL_PROPERTY, frameMaterial) + .withProperty(PipeRenderProperties.FRAME_MASK_PROPERTY, frameMask) + .withProperty(CoverRendererPackage.CRP_PROPERTY, getCoverableImplementation().createPackage()); + } } diff --git a/src/main/java/gregtech/api/util/GTUtility.java b/src/main/java/gregtech/api/util/GTUtility.java index 597f8ef6095..c4307565b20 100644 --- a/src/main/java/gregtech/api/util/GTUtility.java +++ b/src/main/java/gregtech/api/util/GTUtility.java @@ -26,6 +26,7 @@ import net.minecraft.block.material.MapColor; import net.minecraft.block.state.IBlockState; import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.init.SoundEvents; import net.minecraft.inventory.Slot; @@ -52,6 +53,8 @@ import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.fluids.capability.IFluidHandlerItem; import net.minecraftforge.fml.relauncher.ReflectionHelper; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandlerModifiable; @@ -67,6 +70,8 @@ import java.util.AbstractList; import java.util.ArrayList; +import java.util.BitSet; +import java.util.EnumSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; @@ -76,6 +81,8 @@ import java.util.function.BooleanSupplier; import java.util.function.DoubleSupplier; import java.util.function.Function; +import java.util.function.IntPredicate; +import java.util.function.LongPredicate; import java.util.function.Predicate; public class GTUtility { @@ -963,6 +970,124 @@ public static int safeCastLongToInt(long v) { return v > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) v; } + public static double geometricMean(double first, double... numbers) { + for (double number : numbers) { + first *= number; + } + return Math.pow(first, 1D / (1 + numbers.length)); + } + + @NotNull + @SideOnly(Side.CLIENT) + public static EntityPlayer getSP() { + return net.minecraft.client.Minecraft.getMinecraft().player; + } + + /** + * @param minValue the minimum possible succeeding value + * @param maxValue the maximum possible succeeding value + * @param test the predicate to query for success + * @param ascending determines the direction of search + * @return the smallest succeeding value if ascending, or the largest succeeding value if descending. + */ + public static long binarySearchLong(long minValue, long maxValue, LongPredicate test, boolean ascending) { + while (maxValue - minValue > 1) { + long middle = (minValue + maxValue) / 2; + // XOR + if (test.test(middle) ^ !ascending) { + maxValue = middle; + } else { + minValue = middle; + } + } + return test.test(ascending ? minValue : maxValue) ^ ascending ? maxValue : minValue; + } + + /** + * @param minValue the minimum possible succeeding value + * @param maxValue the maximum possible succeeding value + * @param test the predicate to query for success + * @param ascending determines the direction of search + * @return the smallest succeeding value if ascending, or the largest succeeding value if descending. + */ + public static int binarySearchInt(int minValue, int maxValue, IntPredicate test, boolean ascending) { + while (maxValue - minValue > 1) { + int middle = (minValue + maxValue) / 2; + // XOR + if (test.test(middle) ^ !ascending) { + maxValue = middle; + } else { + minValue = middle; + } + } + return test.test(ascending ? minValue : maxValue) ^ ascending ? maxValue : minValue; + } + + public static int[] convertARGBtoArray(int argb) { + int a = argb >> 24 & 255; + int r = argb >> 16 & 255; + int g = argb >> 8 & 255; + int b = argb & 255; + return new int[] { a, r, g, b }; + } + + @Contract(pure = true) + public static boolean evalMask(@NotNull Enum anEnum, int mask) { + return (mask & (1 << anEnum.ordinal())) > 0; + } + + @Contract(pure = true) + public static boolean evalMask(@NotNull Enum anEnum, @NotNull BitSet mask) { + return mask.get(anEnum.ordinal()); + } + + @Contract(pure = true) + @NotNull + public static > EnumSet maskToSet(@NotNull Class enumClass, byte mask) { + EnumSet set = EnumSet.noneOf(enumClass); + for (T anEnum : enumClass.getEnumConstants()) { + if (evalMask(anEnum, mask)) set.add(anEnum); + } + return set; + } + + @Contract(pure = true) + @NotNull + public static > EnumSet maskToSet(@NotNull Class enumClass, @NotNull BitSet mask) { + EnumSet set = EnumSet.noneOf(enumClass); + for (T anEnum : enumClass.getEnumConstants()) { + if (evalMask(anEnum, mask)) set.add(anEnum); + } + return set; + } + + @Contract(pure = true) + @NotNull + public static BitSet setToMask(@NotNull EnumSet enumSet) { + BitSet mask = new BitSet(); + for (Enum anEnum : enumSet) { + mask.set(anEnum.ordinal()); + } + return mask; + } + + /** + * Forces the initialization of a class; this includes things like loading its static fields. + * This can be useful because a statement like {@code AClass.class} does not initialize a class. + *
+ *
+ * Does nothing if the class is already initialized. + * + * @param clazz the class object to initialize. + */ + public static void forceInitialization(@NotNull Class clazz) { + try { + Class.forName(clazz.getName(), true, clazz.getClassLoader()); + } catch (ClassNotFoundException e) { + throw new AssertionError(e); // Can't happen + } + } + /** * Scales a proposed recipe voltage according to a provided Material working tier. * diff --git a/src/main/java/gregtech/api/util/collection/ListHashSet.java b/src/main/java/gregtech/api/util/collection/ListHashSet.java new file mode 100644 index 00000000000..e4311242c4e --- /dev/null +++ b/src/main/java/gregtech/api/util/collection/ListHashSet.java @@ -0,0 +1,214 @@ +package gregtech.api.util.collection; + +import it.unimi.dsi.fastutil.objects.AbstractObjectSortedSet; +import it.unimi.dsi.fastutil.objects.Object2IntMap; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.ObjectBidirectionalIterator; +import it.unimi.dsi.fastutil.objects.ObjectList; +import it.unimi.dsi.fastutil.objects.ObjectListIterator; +import it.unimi.dsi.fastutil.objects.ObjectSortedSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.ListIterator; +import java.util.Spliterator; + +/** + * A primitive implementation of a set and a list in parallel, with iteration order determined by the list + * while using the set for approximate {@code O(1)} time for {@link #contains(Object)} + */ +public class ListHashSet extends AbstractObjectSortedSet implements List { + + protected final Object2IntMap indexMap; + protected final ObjectList list; + + protected static final int DEFAULT_SIZE = 16; + + public ListHashSet() { + this(DEFAULT_SIZE); + } + + public ListHashSet(Collection c) { + this(c.size()); + addAll(c); + } + + public ListHashSet(int size) { + indexMap = new Object2IntOpenHashMap<>(size); + list = new ObjectArrayList<>(); + indexMap.defaultReturnValue(-1); + } + + protected void updateIndices(List sublist, int by) { + for (int i = 0; i < sublist.size(); i++) { + E e = sublist.get(i); + int index = indexMap.getInt(e); + if (index == -1) continue; + indexMap.put(e, index + by); + } + } + + @Override + public ObjectBidirectionalIterator iterator(E fromElement) { + int index = indexOf(fromElement); + if (index == -1) throw new IllegalArgumentException("ListHashSet must contain the specified element!"); + return list.listIterator(index); + } + + @Override + public ObjectListIterator iterator() { + return list.iterator(); + } + + @Override + public boolean addAll(final int index, @NotNull Collection c) { + if (index == list.size()) { + return addAll(c); + } + int shuffle = 0; + for (E e : c) { + if (indexMap.containsKey(e)) continue; + indexMap.put(e, index + shuffle); + list.add(index + shuffle, e); + shuffle++; + } + updateIndices(list.subList(index + shuffle, list.size()), shuffle); + return shuffle > 0; + } + + @Override + public boolean contains(Object o) { + return indexMap.containsKey(o); + } + + @Override + public E get(int index) { + return list.get(index); + } + + @Override + public E set(int index, E element) { + E prev = list.set(index, element); + indexMap.remove(prev); + indexMap.put(element, index); + return prev; + } + + @Override + public boolean add(E e) { + return addSensitive(size(), e); + } + + @Override + public void add(int index, E element) { + addSensitive(index, element); + } + + /** + * Equivalent to {@link #add(int, Object)}, but reports whether the addition was successful or not. + * + * @param index index at which the specified element is to be inserted + * @param element element to be inserted + * @return whether the element was inserted. + */ + public boolean addSensitive(int index, E element) { + if (indexMap.containsKey(element)) return false; + indexMap.put(element, index); + list.add(index, element); + // update if we didn't add to the end of the list + if (index != list.size() - 1) updateIndices(list.subList(index + 1, list.size()), 1); + return true; + } + + @Override + public E remove(int index) { + E element = list.remove(index); + indexMap.remove(element); + return element; + } + + @Override + public boolean rem(Object o) { + int index = indexOf(o); + if (index == -1) return false; + list.remove(index); + indexMap.remove(o); + return true; + } + + @Nullable + @Override + public Comparator comparator() { + return null; + } + + @Override + public E first() { + return list.get(0); + } + + @Override + public E last() { + return list.get(list.size() - 1); + } + + @Override + public Spliterator spliterator() { + return super.spliterator(); + } + + @Override + public int size() { + return list.size(); + } + + @Override + public int indexOf(Object o) { + return indexMap.getInt(o); + } + + @Override + public int lastIndexOf(Object o) { + // no duplicates because set + return indexOf(o); + } + + @NotNull + @Override + public ListIterator listIterator() { + return list.listIterator(); + } + + @NotNull + @Override + public ListIterator listIterator(int index) { + return list.listIterator(index); + } + + @NotNull + @Override + public List subList(int fromIndex, int toIndex) { + // TODO + throw new UnsupportedOperationException(); + } + + @Override + public ObjectSortedSet subSet(E fromElement, E toElement) { + // TODO + throw new UnsupportedOperationException(); + } + + @Override + public ObjectSortedSet headSet(E toElement) { + return subSet(first(), toElement); + } + + @Override + public ObjectSortedSet tailSet(E fromElement) { + return subSet(fromElement, null); + } +} diff --git a/src/main/java/gregtech/api/util/collection/MapFunction.java b/src/main/java/gregtech/api/util/collection/MapFunction.java new file mode 100644 index 00000000000..2e50730831c --- /dev/null +++ b/src/main/java/gregtech/api/util/collection/MapFunction.java @@ -0,0 +1,8 @@ +package gregtech.api.util.collection; + +import java.util.Map; + +public interface MapFunction { + + Map createMap(int size); +} diff --git a/src/main/java/gregtech/api/util/collection/PairedBiMap.java b/src/main/java/gregtech/api/util/collection/PairedBiMap.java new file mode 100644 index 00000000000..fddc2e3258e --- /dev/null +++ b/src/main/java/gregtech/api/util/collection/PairedBiMap.java @@ -0,0 +1,139 @@ +package gregtech.api.util.collection; + +import com.google.common.collect.BiMap; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.Set; + +/** + * An implementation of BiMap that pairs together a forward and backward version of normal maps to operate. + * + * @param the type of keys maintained by this map + * @param the type of mapped values + */ +public class PairedBiMap implements BiMap { + + private static final int DEFAULT_SIZE = 16; + + private final Map forwardMap; + private final Map backwardMap; + + private @Nullable BiMap reverse; + + protected final boolean byReference; + + public PairedBiMap(MapFunction function) { + this(function, DEFAULT_SIZE); + } + + public PairedBiMap(@NotNull MapFunction function, int size) { + this(function, size, false); + } + + public PairedBiMap(@NotNull MapFunction function, int size, boolean byReference) { + forwardMap = function.createMap(size); + backwardMap = function.createMap(size); + this.byReference = byReference; + } + + protected PairedBiMap(@NotNull PairedBiMap reverse, @NotNull Map forwardMap, + @NotNull Map backwardMap) { + this.reverse = reverse; + this.forwardMap = forwardMap; + this.backwardMap = backwardMap; + this.byReference = reverse.byReference; + } + + @Override + public int size() { + return forwardMap.size(); + } + + @Override + public boolean isEmpty() { + return forwardMap.isEmpty(); + } + + @Override + public boolean containsKey(Object key) { + return forwardMap.containsKey(key); + } + + @Override + public boolean containsValue(Object value) { + return backwardMap.containsKey(value); + } + + @Override + public V get(Object key) { + return forwardMap.get(key); + } + + @Override + public V put(K key, V value) { + K existing = backwardMap.get(value); + // throw if this value is already associated with a different key + if (existing != null && !equivalent(existing, key)) { + throw new IllegalArgumentException("Value already exists in BiMap!"); + } + V old = forwardMap.put(key, value); + backwardMap.put(value, key); + return old; + } + + @Override + public V remove(Object key) { + V rem = forwardMap.remove(key); + backwardMap.remove(rem); + return rem; + } + + @Override + public V forcePut(K key, V value) { + backwardMap.remove(value); + return put(key, value); + } + + @Override + public void putAll(Map map) { + for (var entry : map.entrySet()) { + put(entry.getKey(), entry.getValue()); + } + } + + @Override + public void clear() { + forwardMap.clear(); + backwardMap.clear(); + } + + @NotNull + @Override + public Set keySet() { + return forwardMap.keySet(); + } + + @Override + public Set values() { + return backwardMap.keySet(); + } + + @NotNull + @Override + public Set> entrySet() { + return forwardMap.entrySet(); + } + + @Override + public BiMap inverse() { + if (reverse == null) reverse = new PairedBiMap<>(this, backwardMap, forwardMap); + return reverse; + } + + private boolean equivalent(Object a, Object b) { + if (byReference) return a == b; + else return a.equals(b); + } +} diff --git a/src/main/java/gregtech/api/util/collection/WeakHashSet.java b/src/main/java/gregtech/api/util/collection/WeakHashSet.java new file mode 100644 index 00000000000..fb9d0a67176 --- /dev/null +++ b/src/main/java/gregtech/api/util/collection/WeakHashSet.java @@ -0,0 +1,136 @@ +package gregtech.api.util.collection; + +import org.jetbrains.annotations.NotNull; + +import java.util.AbstractSet; +import java.util.Collection; +import java.util.Iterator; +import java.util.Objects; +import java.util.Set; +import java.util.Spliterator; +import java.util.WeakHashMap; +import java.util.function.Consumer; +import java.util.function.Predicate; +import java.util.stream.Stream; + +/** + * Replica of {@link java.util.Collections.SetFromMap} for {@link WeakHashMap} to allow for greater type specificity + * than the {@link java.util.Set} interface. + */ +@SuppressWarnings("JavadocReference") +public class WeakHashSet extends AbstractSet { + + private final WeakHashMap m = new WeakHashMap<>(); + + private final transient Set s = m.keySet(); + + @Override + public void clear() { + m.clear(); + } + + @Override + public int size() { + return m.size(); + } + + @Override + public boolean isEmpty() { + return m.isEmpty(); + } + + // TODO access WeakHashMap#getEntry somehow + // public E get(Object o) { + // } + + @SuppressWarnings("SuspiciousMethodCalls") + @Override + public boolean contains(Object o) { + return m.containsKey(o); + } + + @Override + public boolean remove(Object o) { + return m.remove(o) != null; + } + + @Override + public boolean add(E e) { + return m.put(e, Boolean.TRUE) == null; + } + + @Override + public Iterator iterator() { + return s.iterator(); + } + + @Override + public Object[] toArray() { + return s.toArray(); + } + + @Override + public T[] toArray(T @NotNull [] a) { + return s.toArray(a); + } + + @Override + public String toString() { + return s.toString(); + } + + @Override + public int hashCode() { + return s.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + if (!super.equals(o)) return false; + WeakHashSet that = (WeakHashSet) o; + return Objects.equals(s, that.s); + } + + @Override + public boolean containsAll(@NotNull Collection c) { + return s.containsAll(c); + } + + @Override + public boolean removeAll(Collection c) { + return s.removeAll(c); + } + + @Override + public boolean retainAll(@NotNull Collection c) { + return s.retainAll(c); + } + // addAll is the only inherited implementation + + @Override + public void forEach(Consumer action) { + s.forEach(action); + } + + @Override + public boolean removeIf(Predicate filter) { + return s.removeIf(filter); + } + + @Override + public Spliterator spliterator() { + return s.spliterator(); + } + + @Override + public Stream stream() { + return s.stream(); + } + + @Override + public Stream parallelStream() { + return s.parallelStream(); + } +} diff --git a/src/main/java/gregtech/client/ClientProxy.java b/src/main/java/gregtech/client/ClientProxy.java index f9b712309a2..0721dc708e6 100644 --- a/src/main/java/gregtech/client/ClientProxy.java +++ b/src/main/java/gregtech/client/ClientProxy.java @@ -17,12 +17,8 @@ import gregtech.client.model.customtexture.MetadataSectionCTM; import gregtech.client.renderer.handler.FacadeRenderer; import gregtech.client.renderer.handler.MetaTileEntityRenderer; -import gregtech.client.renderer.pipe.CableRenderer; -import gregtech.client.renderer.pipe.FluidPipeRenderer; -import gregtech.client.renderer.pipe.ItemPipeRenderer; -import gregtech.client.renderer.pipe.LaserPipeRenderer; -import gregtech.client.renderer.pipe.OpticalPipeRenderer; -import gregtech.client.renderer.pipe.PipeRenderer; +import gregtech.client.renderer.pipe.AbstractPipeModel; +import gregtech.client.renderer.pipe.PipeModelRegistry; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.ItemRenderCompat; import gregtech.client.utils.TooltipHelper; @@ -100,11 +96,6 @@ public void onPreLoad() { } MetaTileEntityRenderer.preInit(); - CableRenderer.INSTANCE.preInit(); - FluidPipeRenderer.INSTANCE.preInit(); - ItemPipeRenderer.INSTANCE.preInit(); - OpticalPipeRenderer.INSTANCE.preInit(); - LaserPipeRenderer.INSTANCE.preInit(); MetaEntities.initRenderers(); MinecraftForge.EVENT_BUS.register(KeyBind.class); @@ -134,12 +125,6 @@ public static void textureStitchPre(@NotNull TextureStitchEvent.Pre event) { TextureMap map = event.getMap(); GTFluidRegistration.INSTANCE.registerSprites(map); Textures.register(map); - PipeRenderer.initializeRestrictor(map); - CableRenderer.INSTANCE.registerIcons(map); - FluidPipeRenderer.INSTANCE.registerIcons(map); - ItemPipeRenderer.INSTANCE.registerIcons(map); - OpticalPipeRenderer.INSTANCE.registerIcons(map); - LaserPipeRenderer.INSTANCE.registerIcons(map); } @SubscribeEvent @@ -156,6 +141,9 @@ public static void registerBakedModels(ModelBakeEvent event) { GTLog.logger.info("Registering special item models"); MetaItems.registerBakedModels(event); ToolItems.registerBakedModels(event); + GTLog.logger.info("Registering special block models"); + AbstractPipeModel.invalidateCaches(); + PipeModelRegistry.registerModels(event.getModelRegistry()); } @SubscribeEvent diff --git a/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java b/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java index 6db1848659a..af189744a90 100644 --- a/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java +++ b/src/main/java/gregtech/client/renderer/handler/FacadeRenderer.java @@ -4,6 +4,8 @@ import gregtech.api.items.metaitem.MetaItem; import gregtech.client.model.pipeline.VertexLighterFlatSpecial; import gregtech.client.model.pipeline.VertexLighterSmoothAoSpecial; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererValues; import gregtech.client.utils.AdvCCRSConsumer; import gregtech.client.utils.FacadeBlockAccess; import gregtech.client.utils.ItemRenderCompat; @@ -52,6 +54,7 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * Mostly based on and (copied from) ThermalDynamics with minor tweaks @@ -147,6 +150,37 @@ public static boolean renderBlockCover(CCRenderState ccrs, Matrix4 translation, return false; } + public static CoverRenderer createRenderer(IBlockAccess world, BlockPos pos, IBlockState state) { + BlockRendererDispatcher dispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher(); + try { + state = state.getActualState(world, pos); + } catch (Exception ignored) {} + + IBakedModel model = dispatcher.getModelForState(state); + + try { + state = state.getBlock().getExtendedState(state, world, pos); + } catch (Exception ignored) {} + IBlockState finalState = state; + return (quads, facing, renderPlate, renderBackside, renderLayer, data) -> { + if (renderLayer != BlockRenderLayer.CUTOUT_MIPPED) return; + // since the block model may be sensitive to the current render layer, we have to recalculate + // every call. + long posRand = MathHelper.getPositionRandom(pos); + List modelQuads = new ArrayList<>(model.getQuads(finalState, null, posRand)); + for (EnumFacing face : EnumFacing.VALUES) { + modelQuads.addAll(model.getQuads(finalState, face, posRand)); + } + // is there anything that can be done to make this cheaper? + quads.addAll(remap(sliceQuads(fromArray(modelQuads), facing.getIndex(), + new Cuboid6(CoverRendererValues.PLATE_AABBS.get(facing))))); + }; + } + + private static List remap(List quads) { + return quads.stream().map(CCQuad::bake).collect(Collectors.toList()); + } + public static void renderItemCover(CCRenderState ccrs, int side, ItemStack renderStack, Cuboid6 bounds) { Minecraft minecraft = Minecraft.getMinecraft(); RenderItem renderItem = minecraft.getRenderItem(); diff --git a/src/main/java/gregtech/client/renderer/pipe/AbstractPipeModel.java b/src/main/java/gregtech/client/renderer/pipe/AbstractPipeModel.java new file mode 100644 index 00000000000..dd72fcb0d02 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/AbstractPipeModel.java @@ -0,0 +1,162 @@ +package gregtech.client.renderer.pipe; + +import gregtech.api.pipenet.block.BlockPipe; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.info.MaterialIconType; +import gregtech.api.util.GTUtility; +import gregtech.api.util.collection.WeakHashSet; +import gregtech.client.renderer.pipe.cache.ColorQuadCache; +import gregtech.client.renderer.pipe.cache.StructureQuadCache; +import gregtech.client.renderer.pipe.cover.CoverRendererPackage; +import gregtech.client.renderer.pipe.quad.ColorData; +import gregtech.client.renderer.pipe.quad.PipeQuadHelper; +import gregtech.client.renderer.pipe.util.CacheKey; +import gregtech.client.renderer.pipe.util.SpriteInformation; +import gregtech.common.ConfigHolder; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.ResourceLocation; +import net.minecraft.world.World; +import net.minecraftforge.client.MinecraftForgeClient; +import net.minecraftforge.common.property.IExtendedBlockState; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; + +@SideOnly(Side.CLIENT) +public abstract class AbstractPipeModel { + + protected final Object2ObjectOpenHashMap frameCache = new Object2ObjectOpenHashMap<>(); + protected final Object2ObjectOpenHashMap pipeCache; + + protected static final WeakHashSet> PIPE_CACHES = new WeakHashSet<>(); + + public static void invalidateCaches() { + for (var cache : PIPE_CACHES) { + cache.clear(); + cache.trim(16); + } + } + + public AbstractPipeModel() { + pipeCache = new Object2ObjectOpenHashMap<>(); + PIPE_CACHES.add(pipeCache); + } + + public @NotNull List getQuads(IExtendedBlockState state, EnumFacing side, long rand) { + if (side == null) { + List quads; + ColorData data = computeColorData(state); + CoverRendererPackage rendererPackage = state.getValue(CoverRendererPackage.CRP_PROPERTY); + byte coverMask = rendererPackage == null ? 0 : rendererPackage.getMask(); + if (shouldRenderInLayer(getCurrentRenderLayer())) { + quads = getQuads(toKey(state), BlockPipe.readConnectionMask(state), + safeByte(state.getValue(PipeRenderProperties.CLOSED_MASK_PROPERTY)), safeByte(state.getValue( + PipeRenderProperties.BLOCKED_MASK_PROPERTY)), + data, state.getValue(PipeRenderProperties.FRAME_MATERIAL_PROPERTY), + safeByte(state.getValue(PipeRenderProperties.FRAME_MASK_PROPERTY)), coverMask); + } else quads = new ObjectArrayList<>(); + if (rendererPackage != null) renderCovers(quads, rendererPackage, state); + return quads; + } + return Collections.emptyList(); + } + + protected void renderCovers(List quads, @NotNull CoverRendererPackage rendererPackage, + @NotNull IExtendedBlockState ext) { + int color = safeInt(ext.getValue(PipeRenderProperties.COLOR_PROPERTY)); + if (ext.getUnlistedProperties().containsKey(PipeRenderProperties.MATERIAL_PROPERTY)) { + Material material = ext.getValue(PipeRenderProperties.MATERIAL_PROPERTY); + if (material != null) { + int matColor = GTUtility.convertRGBtoARGB(material.getMaterialRGB()); + if (color == 0 || color == matColor) { + // unpainted + color = ConfigHolder.client.defaultPaintingColor; + } + } + } + rendererPackage.addQuads(quads, getCurrentRenderLayer(), new ColorData(color)); + } + + protected ColorData computeColorData(@NotNull IExtendedBlockState ext) { + return new ColorData(safeInt(ext.getValue(PipeRenderProperties.COLOR_PROPERTY))); + } + + protected static byte safeByte(@Nullable Byte abyte) { + return abyte == null ? 0 : abyte; + } + + protected static int safeInt(@Nullable Integer integer) { + return integer == null ? 0 : integer; + } + + public @NotNull List getQuads(K key, byte connectionMask, byte closedMask, byte blockedMask, + ColorData data, + @Nullable Material frameMaterial, byte frameMask, byte coverMask) { + List quads = new ObjectArrayList<>(); + + StructureQuadCache cache = pipeCache.computeIfAbsent(key, this::constructForKey); + cache.addToList(quads, connectionMask, closedMask, + blockedMask, data, coverMask); + + if (frameMaterial != null) { + ResourceLocation rl = MaterialIconType.frameGt.getBlockTexturePath(frameMaterial.getMaterialIconSet()); + ColorQuadCache frame = frameCache.get(rl); + if (frame == null) { + frame = new ColorQuadCache(PipeQuadHelper + .createFrame(Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(rl.toString()))); + frameCache.put(rl, frame); + } + List frameQuads = frame + .getQuads(new ColorData(GTUtility.convertRGBtoARGB(frameMaterial.getMaterialRGB()))); + for (int i = 0; i < 6; i++) { + if ((frameMask & (1 << i)) > 0) { + quads.add(frameQuads.get(i)); + } + } + } + return quads; + } + + protected abstract @NotNull K toKey(@NotNull IExtendedBlockState state); + + protected final @NotNull CacheKey defaultKey(@NotNull IExtendedBlockState state) { + return CacheKey.of(state.getValue(PipeRenderProperties.THICKNESS_PROPERTY)); + } + + protected abstract StructureQuadCache constructForKey(K key); + + public Pair getParticleTexture(int paintColor, @Nullable Material material) { + SpriteInformation spriteInformation = getParticleSprite(material); + return new ImmutablePair<>(spriteInformation.sprite(), spriteInformation.colorable() ? paintColor : 0xFFFFFFFF); + } + + public abstract SpriteInformation getParticleSprite(@Nullable Material material); + + @Nullable + protected abstract PipeItemModel getItemModel(PipeModelRedirector redirector, @NotNull ItemStack stack, + World world, EntityLivingBase entity); + + protected boolean shouldRenderInLayer(BlockRenderLayer layer) { + return layer == BlockRenderLayer.CUTOUT_MIPPED; + } + + protected static BlockRenderLayer getCurrentRenderLayer() { + return MinecraftForgeClient.getRenderLayer(); + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/ActivablePipeModel.java b/src/main/java/gregtech/client/renderer/pipe/ActivablePipeModel.java new file mode 100644 index 00000000000..336e94cb9fa --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/ActivablePipeModel.java @@ -0,0 +1,114 @@ +package gregtech.client.renderer.pipe; + +import gregtech.api.pipenet.block.ItemBlockPipe; +import gregtech.api.unification.material.Material; +import gregtech.client.renderer.pipe.cache.ActivableSQC; +import gregtech.client.renderer.pipe.cache.StructureQuadCache; +import gregtech.client.renderer.pipe.quad.ColorData; +import gregtech.client.renderer.pipe.quad.PipeQuadHelper; +import gregtech.client.renderer.pipe.util.ActivableCacheKey; +import gregtech.client.renderer.pipe.util.SpriteInformation; +import gregtech.client.utils.BloomEffectUtil; +import gregtech.client.utils.RenderUtil; +import gregtech.common.ConfigHolder; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.world.World; +import net.minecraftforge.common.property.IExtendedBlockState; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +@SideOnly(Side.CLIENT) +public class ActivablePipeModel extends AbstractPipeModel { + + private final Supplier inTex; + private final Supplier sideTex; + private final Supplier overlayTex; + private final Supplier overlayActiveTex; + + private final boolean emissiveActive; + + public ActivablePipeModel(@NotNull Supplier inTex, @NotNull Supplier sideTex, + @NotNull Supplier overlayTex, + @NotNull Supplier overlayActiveTex, boolean emissiveActive) { + this.inTex = inTex; + this.sideTex = sideTex; + this.overlayTex = overlayTex; + this.overlayActiveTex = overlayActiveTex; + this.emissiveActive = emissiveActive; + } + + @Override + public @NotNull List getQuads(ActivableCacheKey key, byte connectionMask, byte closedMask, + byte blockedMask, ColorData data, @Nullable Material frameMaterial, + byte frameMask, byte coverMask) { + boolean bloomLayer = getCurrentRenderLayer() == BloomEffectUtil.getEffectiveBloomLayer(); + // don't render the main shape to the bloom layer + List quads = bloomLayer ? new ObjectArrayList<>() : + super.getQuads(key, connectionMask, closedMask, blockedMask, data, frameMaterial, frameMask, coverMask); + + if (key.isActive() && allowActive()) { + if (emissiveActive && bloomLayer) { + ((ActivableSQC) pipeCache.get(key)).addOverlay(quads, connectionMask, data, true); + // TODO bake this into the original quads + quads = quads.stream().map(RenderUtil::makeEmissive).collect(Collectors.toList()); + } else if (!emissiveActive && !bloomLayer) { + ((ActivableSQC) pipeCache.get(key)).addOverlay(quads, connectionMask, data, true); + } + } else if (!bloomLayer) { + ((ActivableSQC) pipeCache.get(key)).addOverlay(quads, connectionMask, data, false); + } + return quads; + } + + @Override + public SpriteInformation getParticleSprite(@Nullable Material material) { + return sideTex.get(); + } + + @Override + protected @NotNull ActivableCacheKey toKey(@NotNull IExtendedBlockState state) { + return ActivableCacheKey.of(state.getValue(PipeRenderProperties.THICKNESS_PROPERTY), state.getValue( + PipeRenderProperties.ACTIVE_PROPERTY)); + } + + @Override + protected StructureQuadCache constructForKey(ActivableCacheKey key) { + return ActivableSQC.create(PipeQuadHelper.create(key.getThickness()), inTex.get(), sideTex.get(), + overlayTex.get(), overlayActiveTex.get()); + } + + @Override + protected boolean shouldRenderInLayer(BlockRenderLayer layer) { + return layer == BlockRenderLayer.CUTOUT_MIPPED || + (allowActive() && emissiveActive && layer == BloomEffectUtil.getEffectiveBloomLayer()); + } + + public boolean allowActive() { + return !ConfigHolder.client.preventAnimatedCables; + } + + @Override + protected @Nullable PipeItemModel getItemModel(PipeModelRedirector redirector, + @NotNull ItemStack stack, World world, + EntityLivingBase entity) { + if (stack.getItem() instanceof ItemBlockPipei) { + return new PipeItemModel<>(redirector, this, + new ActivableCacheKey(i.getBlock().getPipeType().getThickness(), false), + new ColorData(0xFFFFFFFF)); + } else { + return null; + } + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/CableModel.java b/src/main/java/gregtech/client/renderer/pipe/CableModel.java new file mode 100644 index 00000000000..e5756399f57 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/CableModel.java @@ -0,0 +1,112 @@ +package gregtech.client.renderer.pipe; + +import gregtech.api.pipenet.block.ItemBlockPipe; +import gregtech.api.pipenet.block.material.BlockMaterialPipe; +import gregtech.api.unification.material.Material; +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.cache.ExtraCappedSQC; +import gregtech.client.renderer.pipe.cache.StructureQuadCache; +import gregtech.client.renderer.pipe.quad.ColorData; +import gregtech.client.renderer.pipe.quad.PipeQuadHelper; +import gregtech.client.renderer.pipe.util.CacheKey; +import gregtech.client.renderer.pipe.util.SpriteInformation; +import gregtech.client.renderer.texture.Textures; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import net.minecraftforge.common.property.IExtendedBlockState; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Supplier; + +@SideOnly(Side.CLIENT) +public class CableModel extends AbstractPipeModel { + + public static final int DEFAULT_INSULATION_COLOR = 0xFF404040; + + public static final CableModel INSTANCE = new CableModel(); + public static final CableModel[] INSULATED_INSTANCES = new CableModel[Textures.PipeTextures.INSULATION.length]; + + static { + for (int i = 0; i < INSULATED_INSTANCES.length; i++) { + INSULATED_INSTANCES[i] = new CableModel(Textures.PipeTextures.INSULATION[i], + Textures.PipeTextures.INSULATION_FULL); + } + } + + private final Supplier wireTex; + private final Supplier insulationTex; + private final Supplier fullInsulationTex; + + public CableModel(@NotNull Supplier wireTex, @Nullable Supplier insulationTex, + @Nullable Supplier fullInsulationTex) { + this.wireTex = wireTex; + this.insulationTex = insulationTex; + this.fullInsulationTex = fullInsulationTex; + } + + public CableModel(@Nullable Supplier insulationTex, + @Nullable Supplier fullInsulationTex) { + this(Textures.PipeTextures.WIRE, insulationTex, fullInsulationTex); + } + + public CableModel() { + this(null, null); + } + + @Override + protected ColorData computeColorData(@NotNull IExtendedBlockState ext) { + if (insulationTex == null) return super.computeColorData(ext); + Material material = ext.getValue(PipeRenderProperties.MATERIAL_PROPERTY); + int insulationColor = safeInt(ext.getValue(PipeRenderProperties.COLOR_PROPERTY)); + if (material != null) { + int matColor = GTUtility.convertRGBtoARGB(material.getMaterialRGB()); + if (insulationColor == 0 || insulationColor == matColor) { + // unpainted + insulationColor = DEFAULT_INSULATION_COLOR; + } + return new ColorData(matColor, insulationColor); + } + return new ColorData(0, 0); + } + + @Override + public SpriteInformation getParticleSprite(@Nullable Material material) { + return wireTex.get(); + } + + @Override + protected @NotNull CacheKey toKey(@NotNull IExtendedBlockState state) { + return defaultKey(state); + } + + @Override + protected StructureQuadCache constructForKey(CacheKey key) { + SpriteInformation sideTex = fullInsulationTex != null ? fullInsulationTex.get() : wireTex.get(); + if (insulationTex == null) { + return StructureQuadCache.create(PipeQuadHelper.create(key.getThickness()), wireTex.get(), sideTex); + } else { + return ExtraCappedSQC.create(PipeQuadHelper.create(key.getThickness()), wireTex.get(), sideTex, + insulationTex.get()); + } + } + + @Override + @Nullable + protected PipeItemModel getItemModel(PipeModelRedirector redirector, @NotNull ItemStack stack, + World world, EntityLivingBase entity) { + if (stack.getItem() instanceof ItemBlockPipei) { + Material mater = i.getBlock() instanceof BlockMaterialPipemat ? mat.getItemMaterial(stack) : null; + return new PipeItemModel<>(redirector, this, new CacheKey(i.getBlock().getPipeType().getThickness()), + new ColorData(mater != null ? GTUtility.convertRGBtoARGB(mater.getMaterialRGB()) : + 0xFFFFFFFF, DEFAULT_INSULATION_COLOR)); + } else { + return null; + } + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/CableRenderer.java b/src/main/java/gregtech/client/renderer/pipe/CableRenderer.java deleted file mode 100644 index 5c91a2f44cc..00000000000 --- a/src/main/java/gregtech/client/renderer/pipe/CableRenderer.java +++ /dev/null @@ -1,108 +0,0 @@ -package gregtech.client.renderer.pipe; - -import gregtech.api.pipenet.block.BlockPipe; -import gregtech.api.pipenet.block.IPipeType; -import gregtech.api.pipenet.block.material.TileEntityMaterialPipeBase; -import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.api.unification.material.Material; -import gregtech.api.util.GTUtility; -import gregtech.client.utils.RenderUtil; -import gregtech.common.pipelike.cable.Insulation; - -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.util.ResourceLocation; - -import codechicken.lib.render.pipeline.ColourMultiplier; -import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.vec.uv.IconTransformation; -import org.apache.commons.lang3.tuple.Pair; -import org.jetbrains.annotations.Nullable; - -public class CableRenderer extends PipeRenderer { - - public static final CableRenderer INSTANCE = new CableRenderer(); - private final TextureAtlasSprite[] insulationTextures = new TextureAtlasSprite[6]; - private TextureAtlasSprite wireTexture; - - private CableRenderer() { - super("gt_cable", GTUtility.gregtechId("cable")); - } - - @Override - public void registerIcons(TextureMap map) { - ResourceLocation wireLocation = GTUtility.gregtechId("blocks/cable/wire"); - this.wireTexture = map.registerSprite(wireLocation); - for (int i = 0; i < insulationTextures.length; i++) { - ResourceLocation location = GTUtility.gregtechId("blocks/cable/insulation_" + i); - this.insulationTextures[i] = map.registerSprite(location); - } - } - - @Override - public void buildRenderer(PipeRenderContext renderContext, BlockPipe blockPipe, IPipeTile pipeTile, - IPipeType pipeType, @Nullable Material material) { - if (material == null || !(pipeType instanceof Insulation)) { - return; - } - - int insulationLevel = ((Insulation) pipeType).insulationLevel; - IVertexOperation wireRender = new IconTransformation(wireTexture); - ColourMultiplier wireColor = new ColourMultiplier( - GTUtility.convertRGBtoOpaqueRGBA_CL(material.getMaterialRGB())); - ColourMultiplier insulationColor = new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(0x404040)); - if (pipeTile != null) { - if (pipeTile.getPaintingColor() != pipeTile.getDefaultPaintingColor()) { - wireColor.colour = GTUtility.convertRGBtoOpaqueRGBA_CL(pipeTile.getPaintingColor()); - } - insulationColor.colour = GTUtility.convertRGBtoOpaqueRGBA_CL(pipeTile.getPaintingColor()); - } - - if (insulationLevel != -1) { - - if ((renderContext.getConnections() & 63) == 0) { - // render only insulation when cable has no connections - renderContext.addOpenFaceRender(false, new IconTransformation(insulationTextures[5]), insulationColor); - return; - } - - renderContext.addOpenFaceRender(false, wireRender, wireColor) - .addOpenFaceRender(false, new IconTransformation(insulationTextures[insulationLevel]), - insulationColor) - .addSideRender(false, new IconTransformation(insulationTextures[5]), insulationColor); - } else { - renderContext.addOpenFaceRender(false, wireRender, wireColor) - .addSideRender(false, wireRender, wireColor); - } - } - - @Override - public TextureAtlasSprite getParticleTexture(IPipeType pipeType, @Nullable Material material) { - return null; - } - - @Override - public Pair getParticleTexture(IPipeTile pipeTile) { - if (pipeTile == null) { - return Pair.of(RenderUtil.getMissingSprite(), 0xFFFFFF); - } - IPipeType pipeType = pipeTile.getPipeType(); - if (!(pipeType instanceof Insulation)) { - return Pair.of(RenderUtil.getMissingSprite(), 0xFFFFFF); - } - Material material = pipeTile instanceof TileEntityMaterialPipeBase ? - ((TileEntityMaterialPipeBase) pipeTile).getPipeMaterial() : null; - - TextureAtlasSprite atlasSprite; - int particleColor; - int insulationLevel = ((Insulation) pipeType).insulationLevel; - if (insulationLevel == -1) { - atlasSprite = wireTexture; - particleColor = material == null ? 0xFFFFFF : material.getMaterialRGB(); - } else { - atlasSprite = insulationTextures[5]; - particleColor = pipeTile.getPaintingColor(); - } - return Pair.of(atlasSprite, particleColor); - } -} diff --git a/src/main/java/gregtech/client/renderer/pipe/FluidPipeRenderer.java b/src/main/java/gregtech/client/renderer/pipe/FluidPipeRenderer.java deleted file mode 100644 index f729afb3b57..00000000000 --- a/src/main/java/gregtech/client/renderer/pipe/FluidPipeRenderer.java +++ /dev/null @@ -1,69 +0,0 @@ -package gregtech.client.renderer.pipe; - -import gregtech.api.pipenet.block.BlockPipe; -import gregtech.api.pipenet.block.IPipeType; -import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.api.recipes.ModHandler; -import gregtech.api.unification.material.Material; -import gregtech.api.util.GTUtility; -import gregtech.client.renderer.texture.Textures; -import gregtech.common.pipelike.fluidpipe.FluidPipeType; - -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.texture.TextureMap; - -import codechicken.lib.vec.uv.IconTransformation; -import org.jetbrains.annotations.Nullable; - -import java.util.EnumMap; - -public class FluidPipeRenderer extends PipeRenderer { - - public static final FluidPipeRenderer INSTANCE = new FluidPipeRenderer(); - private final EnumMap pipeTextures = new EnumMap<>(FluidPipeType.class); - private final EnumMap pipeTexturesWood = new EnumMap<>(FluidPipeType.class); - - private FluidPipeRenderer() { - super("gt_fluid_pipe", GTUtility.gregtechId("fluid_pipe")); - } - - @Override - public void registerIcons(TextureMap map) { - pipeTextures.put(FluidPipeType.TINY, Textures.PIPE_TINY); - pipeTextures.put(FluidPipeType.SMALL, Textures.PIPE_SMALL); - pipeTextures.put(FluidPipeType.NORMAL, Textures.PIPE_NORMAL); - pipeTextures.put(FluidPipeType.LARGE, Textures.PIPE_LARGE); - pipeTextures.put(FluidPipeType.HUGE, Textures.PIPE_HUGE); - pipeTextures.put(FluidPipeType.QUADRUPLE, Textures.PIPE_QUADRUPLE); - pipeTextures.put(FluidPipeType.NONUPLE, Textures.PIPE_NONUPLE); - - pipeTexturesWood.put(FluidPipeType.SMALL, Textures.PIPE_SMALL_WOOD); - pipeTexturesWood.put(FluidPipeType.NORMAL, Textures.PIPE_NORMAL_WOOD); - pipeTexturesWood.put(FluidPipeType.LARGE, Textures.PIPE_LARGE_WOOD); - } - - @Override - public void buildRenderer(PipeRenderContext renderContext, BlockPipe blockPipe, IPipeTile pipeTile, - IPipeType pipeType, @Nullable Material material) { - if (material == null || !(pipeType instanceof FluidPipeType)) { - return; - } - if (ModHandler.isMaterialWood(material)) { - TextureAtlasSprite sprite = pipeTexturesWood.get(pipeType); - if (sprite != null) { - renderContext.addOpenFaceRender(new IconTransformation(sprite)); - } else { - renderContext.addOpenFaceRender(new IconTransformation(pipeTextures.get(pipeType))); - } - renderContext.addSideRender(new IconTransformation(Textures.PIPE_SIDE_WOOD)); - } else { - renderContext.addOpenFaceRender(new IconTransformation(pipeTextures.get(pipeType))) - .addSideRender(new IconTransformation(Textures.PIPE_SIDE)); - } - } - - @Override - public TextureAtlasSprite getParticleTexture(IPipeType pipeType, @Nullable Material material) { - return Textures.PIPE_SIDE; - } -} diff --git a/src/main/java/gregtech/client/renderer/pipe/ItemPipeRenderer.java b/src/main/java/gregtech/client/renderer/pipe/ItemPipeRenderer.java deleted file mode 100644 index e6d7604b3b4..00000000000 --- a/src/main/java/gregtech/client/renderer/pipe/ItemPipeRenderer.java +++ /dev/null @@ -1,58 +0,0 @@ -package gregtech.client.renderer.pipe; - -import gregtech.api.pipenet.block.BlockPipe; -import gregtech.api.pipenet.block.IPipeType; -import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.api.unification.material.Material; -import gregtech.api.util.GTUtility; -import gregtech.client.renderer.texture.Textures; -import gregtech.common.pipelike.itempipe.ItemPipeType; - -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.texture.TextureMap; - -import codechicken.lib.vec.uv.IconTransformation; -import org.jetbrains.annotations.Nullable; - -import java.util.EnumMap; - -public class ItemPipeRenderer extends PipeRenderer { - - public static final ItemPipeRenderer INSTANCE = new ItemPipeRenderer(); - private final EnumMap pipeTextures = new EnumMap<>(ItemPipeType.class); - - private ItemPipeRenderer() { - super("gt_item_pipe", GTUtility.gregtechId("item_pipe")); - } - - @Override - public void registerIcons(TextureMap map) { - pipeTextures.put(ItemPipeType.SMALL, Textures.PIPE_SMALL); - pipeTextures.put(ItemPipeType.NORMAL, Textures.PIPE_NORMAL); - pipeTextures.put(ItemPipeType.LARGE, Textures.PIPE_LARGE); - pipeTextures.put(ItemPipeType.HUGE, Textures.PIPE_HUGE); - pipeTextures.put(ItemPipeType.RESTRICTIVE_SMALL, Textures.PIPE_SMALL); - pipeTextures.put(ItemPipeType.RESTRICTIVE_NORMAL, Textures.PIPE_NORMAL); - pipeTextures.put(ItemPipeType.RESTRICTIVE_LARGE, Textures.PIPE_LARGE); - pipeTextures.put(ItemPipeType.RESTRICTIVE_HUGE, Textures.PIPE_HUGE); - } - - @Override - public void buildRenderer(PipeRenderContext renderContext, BlockPipe blockPipe, IPipeTile pipeTile, - IPipeType pipeType, @Nullable Material material) { - if (material == null || !(pipeType instanceof ItemPipeType)) { - return; - } - renderContext.addOpenFaceRender(new IconTransformation(pipeTextures.get(pipeType))) - .addSideRender(new IconTransformation(Textures.PIPE_SIDE)); - - if (((ItemPipeType) pipeType).isRestrictive()) { - renderContext.addSideRender(false, new IconTransformation(Textures.RESTRICTIVE_OVERLAY)); - } - } - - @Override - public TextureAtlasSprite getParticleTexture(IPipeType pipeType, @Nullable Material material) { - return Textures.PIPE_SIDE; - } -} diff --git a/src/main/java/gregtech/client/renderer/pipe/LaserPipeRenderer.java b/src/main/java/gregtech/client/renderer/pipe/LaserPipeRenderer.java deleted file mode 100644 index adc2fda4af4..00000000000 --- a/src/main/java/gregtech/client/renderer/pipe/LaserPipeRenderer.java +++ /dev/null @@ -1,102 +0,0 @@ -package gregtech.client.renderer.pipe; - -import gregtech.api.pipenet.block.BlockPipe; -import gregtech.api.pipenet.block.IPipeType; -import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.api.unification.material.Material; -import gregtech.api.util.GTUtility; -import gregtech.client.renderer.texture.Textures; -import gregtech.client.utils.BloomEffectUtil; -import gregtech.common.ConfigHolder; -import gregtech.common.pipelike.laser.LaserPipeType; -import gregtech.common.pipelike.laser.tile.TileEntityLaserPipe; - -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.EnumFacing; - -import codechicken.lib.render.CCRenderState; -import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.vec.Cuboid6; -import codechicken.lib.vec.uv.IconTransformation; -import org.apache.commons.lang3.ArrayUtils; -import org.jetbrains.annotations.Nullable; - -import java.util.EnumMap; - -public class LaserPipeRenderer extends PipeRenderer { - - public static final LaserPipeRenderer INSTANCE = new LaserPipeRenderer(); - private final EnumMap pipeTextures = new EnumMap<>(LaserPipeType.class); - private boolean active = false; - - public LaserPipeRenderer() { - super("gt_laser_pipe", GTUtility.gregtechId("laser_pipe")); - } - - @Override - public void registerIcons(TextureMap map) { - pipeTextures.put(LaserPipeType.NORMAL, Textures.LASER_PIPE_IN); - } - - @Override - public void buildRenderer(PipeRenderContext renderContext, BlockPipe blockPipe, - @Nullable IPipeTile pipeTile, IPipeType pipeType, @Nullable Material material) { - if (pipeType instanceof LaserPipeType) { - renderContext.addOpenFaceRender(new IconTransformation(pipeTextures.get(pipeType))) - .addSideRender(false, new IconTransformation(Textures.LASER_PIPE_SIDE)); - if (pipeTile != null && pipeTile.isPainted()) { - renderContext.addSideRender(new IconTransformation(Textures.LASER_PIPE_OVERLAY)); - } - - active = !ConfigHolder.client.preventAnimatedCables && pipeTile instanceof TileEntityLaserPipe laserPipe && - laserPipe.isActive(); - } - } - - @Override - protected void renderOtherLayers(BlockRenderLayer layer, CCRenderState renderState, - PipeRenderContext renderContext) { - if (active && layer == BloomEffectUtil.getEffectiveBloomLayer() && - (renderContext.getConnections() & 0b111111) != 0) { - Cuboid6 innerCuboid = BlockPipe.getSideBox(null, renderContext.getPipeThickness()); - if ((renderContext.getConnections() & 0b111111) != 0) { - for (EnumFacing side : EnumFacing.VALUES) { - if ((renderContext.getConnections() & (1 << side.getIndex())) == 0) { - int oppositeIndex = side.getOpposite().getIndex(); - if ((renderContext.getConnections() & (1 << oppositeIndex)) <= 0 || - (renderContext.getConnections() & 0b111111 & ~(1 << oppositeIndex)) != 0) { - // render pipe side - IVertexOperation[] ops = renderContext.getBaseVertexOperation(); - ops = ArrayUtils.addAll(ops, new IconTransformation(Textures.LASER_PIPE_OVERLAY_EMISSIVE)); - renderFace(renderState, ops, side, innerCuboid); - } - } else { - // render connection cuboid - Cuboid6 sideCuboid = BlockPipe.getSideBox(side, renderContext.getPipeThickness()); - for (EnumFacing connectionSide : EnumFacing.VALUES) { - if (connectionSide.getAxis() != side.getAxis()) { - // render side textures - IVertexOperation[] ops = renderContext.getBaseVertexOperation(); - ops = ArrayUtils.addAll(ops, - new IconTransformation(Textures.LASER_PIPE_OVERLAY_EMISSIVE)); - renderFace(renderState, ops, connectionSide, sideCuboid); - } - } - } - } - } - } - } - - @Override - protected boolean canRenderInLayer(BlockRenderLayer layer) { - return super.canRenderInLayer(layer) || layer == BloomEffectUtil.getEffectiveBloomLayer(); - } - - @Override - public TextureAtlasSprite getParticleTexture(IPipeType pipeType, @Nullable Material material) { - return Textures.LASER_PIPE_SIDE; - } -} diff --git a/src/main/java/gregtech/client/renderer/pipe/OpticalPipeRenderer.java b/src/main/java/gregtech/client/renderer/pipe/OpticalPipeRenderer.java deleted file mode 100644 index ab63a9560a4..00000000000 --- a/src/main/java/gregtech/client/renderer/pipe/OpticalPipeRenderer.java +++ /dev/null @@ -1,56 +0,0 @@ -package gregtech.client.renderer.pipe; - -import gregtech.api.pipenet.block.BlockPipe; -import gregtech.api.pipenet.block.IPipeType; -import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.api.unification.material.Material; -import gregtech.api.util.GTUtility; -import gregtech.client.renderer.texture.Textures; -import gregtech.common.ConfigHolder; -import gregtech.common.pipelike.optical.OpticalPipeType; -import gregtech.common.pipelike.optical.tile.TileEntityOpticalPipe; - -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.texture.TextureMap; - -import codechicken.lib.vec.uv.IconTransformation; -import org.jetbrains.annotations.Nullable; - -import java.util.EnumMap; - -public final class OpticalPipeRenderer extends PipeRenderer { - - public static final OpticalPipeRenderer INSTANCE = new OpticalPipeRenderer(); - private final EnumMap pipeTextures = new EnumMap<>(OpticalPipeType.class); - - private OpticalPipeRenderer() { - super("gt_optical_pipe", GTUtility.gregtechId("optical_pipe")); - } - - @Override - public void registerIcons(TextureMap map) { - pipeTextures.put(OpticalPipeType.NORMAL, Textures.OPTICAL_PIPE_IN); - } - - @Override - public void buildRenderer(PipeRenderContext renderContext, BlockPipe blockPipe, - @Nullable IPipeTile pipeTile, IPipeType pipeType, @Nullable Material material) { - if (pipeType instanceof OpticalPipeType) { - renderContext.addOpenFaceRender(new IconTransformation(pipeTextures.get(pipeType))) - .addSideRender(false, new IconTransformation(Textures.OPTICAL_PIPE_SIDE)); - - if (ConfigHolder.client.preventAnimatedCables) { - renderContext.addSideRender(new IconTransformation(Textures.OPTICAL_PIPE_SIDE_OVERLAY)); - } else if (pipeTile instanceof TileEntityOpticalPipe opticalPipe && opticalPipe.isActive()) { - renderContext.addSideRender(new IconTransformation(Textures.OPTICAL_PIPE_SIDE_OVERLAY_ACTIVE)); - } else { - renderContext.addSideRender(new IconTransformation(Textures.OPTICAL_PIPE_SIDE_OVERLAY)); - } - } - } - - @Override - public TextureAtlasSprite getParticleTexture(IPipeType pipeType, @Nullable Material material) { - return Textures.OPTICAL_PIPE_SIDE; - } -} diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeItemModel.java b/src/main/java/gregtech/client/renderer/pipe/PipeItemModel.java new file mode 100644 index 00000000000..6868489f456 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/PipeItemModel.java @@ -0,0 +1,105 @@ +package gregtech.client.renderer.pipe; + +import gregtech.client.renderer.pipe.quad.ColorData; +import gregtech.client.renderer.pipe.util.CacheKey; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemOverrideList; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.common.model.TRSRTransformation; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; + +import java.util.EnumMap; +import java.util.List; + +import javax.vecmath.Matrix4f; +import javax.vecmath.Quat4f; +import javax.vecmath.Vector3f; + +@SideOnly(Side.CLIENT) +public class PipeItemModel implements IBakedModel { + + private static final EnumMap CAMERA_TRANSFORMS = new EnumMap<>( + ItemCameraTransforms.TransformType.class); + + static { + CAMERA_TRANSFORMS.put(ItemCameraTransforms.TransformType.NONE, TRSRTransformation.mul(null, null, null, null)); + CAMERA_TRANSFORMS.put(ItemCameraTransforms.TransformType.GUI, + TRSRTransformation.mul(null, rotDegrees(30, -45, 0), scale(0.625f), null)); + CAMERA_TRANSFORMS.put(ItemCameraTransforms.TransformType.GROUND, + TRSRTransformation.mul(null, null, scale(0.25f), null)); + CAMERA_TRANSFORMS.put(ItemCameraTransforms.TransformType.FIXED, + TRSRTransformation.mul(null, rotDegrees(0, 90, 0), scale(0.5f), null)); + Matrix4f matrix4f = TRSRTransformation.mul(null, rotDegrees(75, 45, 0), scale(0.375f), null); + CAMERA_TRANSFORMS.put(ItemCameraTransforms.TransformType.THIRD_PERSON_RIGHT_HAND, matrix4f); + CAMERA_TRANSFORMS.put(ItemCameraTransforms.TransformType.THIRD_PERSON_LEFT_HAND, matrix4f); + matrix4f = TRSRTransformation.mul(null, rotDegrees(0, 45, 0), scale(0.4f), null); + CAMERA_TRANSFORMS.put(ItemCameraTransforms.TransformType.FIRST_PERSON_RIGHT_HAND, matrix4f); + CAMERA_TRANSFORMS.put(ItemCameraTransforms.TransformType.FIRST_PERSON_LEFT_HAND, matrix4f); + } + + private static Vector3f scale(float scale) { + return new Vector3f(scale, scale, scale); + } + + private static Quat4f rotDegrees(float x, float y, float z) { + return TRSRTransformation.quatFromXYZDegrees(new Vector3f(x, y, z)); + } + + private final PipeModelRedirector redirector; + private final AbstractPipeModel basis; + private final K key; + private final ColorData data; + + public PipeItemModel(PipeModelRedirector redirector, AbstractPipeModel basis, K key, ColorData data) { + this.redirector = redirector; + this.basis = basis; + this.key = key; + this.data = data; + } + + @Override + public @NotNull List getQuads(IBlockState state, EnumFacing side, long rand) { + byte z = 0; + return basis.getQuads(key, (byte) 0b1100, z, z, data, null, z, z); + } + + @Override + public boolean isAmbientOcclusion() { + return redirector.isAmbientOcclusion(); + } + + @Override + public boolean isGui3d() { + return redirector.isGui3d(); + } + + @Override + public boolean isBuiltInRenderer() { + return false; + } + + @Override + public @NotNull Pair handlePerspective(ItemCameraTransforms.@NotNull TransformType cameraTransformType) { + return ImmutablePair.of(this, CAMERA_TRANSFORMS.get(cameraTransformType)); + } + + @Override + public @NotNull TextureAtlasSprite getParticleTexture() { + return redirector.getParticleTexture(); + } + + @Override + public @NotNull ItemOverrideList getOverrides() { + return ItemOverrideList.NONE; + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeModel.java b/src/main/java/gregtech/client/renderer/pipe/PipeModel.java new file mode 100644 index 00000000000..779da1a54e2 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/PipeModel.java @@ -0,0 +1,85 @@ +package gregtech.client.renderer.pipe; + +import gregtech.api.pipenet.block.ItemBlockPipe; +import gregtech.api.pipenet.block.material.BlockMaterialPipe; +import gregtech.api.unification.material.Material; +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.cache.BlockableSQC; +import gregtech.client.renderer.pipe.cache.RestrictiveSQC; +import gregtech.client.renderer.pipe.cache.StructureQuadCache; +import gregtech.client.renderer.pipe.quad.ColorData; +import gregtech.client.renderer.pipe.quad.PipeQuadHelper; +import gregtech.client.renderer.pipe.util.CacheKey; +import gregtech.client.renderer.pipe.util.SpriteInformation; +import gregtech.client.renderer.texture.Textures; + +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import net.minecraftforge.common.property.IExtendedBlockState; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Supplier; + +@SideOnly(Side.CLIENT) +public class PipeModel extends AbstractPipeModel { + + private final @NotNull Supplier inTex; + private final @NotNull Supplier sideTex; + private final @Nullable Supplier restrictiveTex; + private final @NotNull Supplier blockedTex; + + public PipeModel(@NotNull Supplier inTex, @NotNull Supplier sideTex, + @Nullable Supplier restrictiveTex, + @NotNull Supplier blockedTex) { + this.inTex = inTex; + this.sideTex = sideTex; + this.restrictiveTex = restrictiveTex; + this.blockedTex = blockedTex; + } + + public PipeModel(@NotNull Supplier inTex, @NotNull Supplier sideTex, + boolean restrictive) { + this(inTex, sideTex, restrictive ? Textures.PipeTextures.RESTRICTIVE_OVERLAY : null, + Textures.PipeTextures.PIPE_BLOCKED_OVERLAY); + } + + @Override + public SpriteInformation getParticleSprite(@Nullable Material material) { + return sideTex.get(); + } + + @Override + protected @NotNull CacheKey toKey(@NotNull IExtendedBlockState state) { + return defaultKey(state); + } + + @Override + protected StructureQuadCache constructForKey(CacheKey key) { + if (restrictiveTex != null) { + return RestrictiveSQC.create(PipeQuadHelper.create(key.getThickness()), inTex.get(), sideTex.get(), + blockedTex.get(), restrictiveTex.get()); + } else { + return BlockableSQC.create(PipeQuadHelper.create(key.getThickness()), inTex.get(), sideTex.get(), + blockedTex.get()); + } + } + + @Override + @Nullable + protected PipeItemModel getItemModel(PipeModelRedirector redirector, @NotNull ItemStack stack, + World world, EntityLivingBase entity) { + if (stack.getItem() instanceof ItemBlockPipei) { + Material mater = i.getBlock() instanceof BlockMaterialPipemat ? mat.getItemMaterial(stack) : null; + return new PipeItemModel<>(redirector, this, new CacheKey(i.getBlock().getPipeType().getThickness()), + new ColorData(mater != null ? GTUtility.convertRGBtoARGB(mater.getMaterialRGB()) : + 0xFFFFFFFF)); + } else { + return null; + } + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeModelRedirector.java b/src/main/java/gregtech/client/renderer/pipe/PipeModelRedirector.java new file mode 100644 index 00000000000..d48ed46369c --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/PipeModelRedirector.java @@ -0,0 +1,123 @@ +package gregtech.client.renderer.pipe; + +import gregtech.api.unification.material.Material; +import gregtech.client.renderer.pipe.util.MaterialModelSupplier; +import gregtech.client.renderer.texture.Textures; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemOverrideList; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import net.minecraftforge.common.property.IExtendedBlockState; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +@SideOnly(Side.CLIENT) +public class PipeModelRedirector implements IBakedModel { + + private final boolean ambientOcclusion; + private final boolean gui3d; + + public final MaterialModelSupplier supplier; + public final Function stackMaterialFunction; + + private final ModelResourceLocation loc; + + private final FakeItemOverrideList fakeItemOverrideList = new FakeItemOverrideList(); + + public PipeModelRedirector(ModelResourceLocation loc, MaterialModelSupplier supplier, + Function stackMaterialFunction) { + this(loc, supplier, stackMaterialFunction, true, true); + } + + public PipeModelRedirector(ModelResourceLocation loc, MaterialModelSupplier supplier, + Function stackMaterialFunction, + boolean ambientOcclusion, boolean gui3d) { + this.loc = loc; + this.supplier = supplier; + this.stackMaterialFunction = stackMaterialFunction; + this.ambientOcclusion = ambientOcclusion; + this.gui3d = gui3d; + } + + @Override + public @NotNull List getQuads(IBlockState state, EnumFacing side, long rand) { + if (state instanceof IExtendedBlockState ext) { + Optional mat = (Optional) ext.getUnlistedProperties() + .get(PipeRenderProperties.MATERIAL_PROPERTY); + // noinspection OptionalAssignedToNull + return supplier.getModel(mat == null ? null : mat.orElse(null)).getQuads(ext, side, rand); + } + return Collections.emptyList(); + } + + @Override + public boolean isAmbientOcclusion() { + return ambientOcclusion; + } + + @Override + public boolean isGui3d() { + return gui3d; + } + + @Override + public boolean isBuiltInRenderer() { + return false; + } + + public Pair getParticleTexture(int paintColor, @Nullable Material material) { + return supplier.getModel(material).getParticleTexture(paintColor, material); + } + + @Override + public @NotNull TextureAtlasSprite getParticleTexture() { + return Textures.PipeTextures.WIRE.get().sprite(); + } + + @Override + public @NotNull ItemOverrideList getOverrides() { + return fakeItemOverrideList; + } + + public ModelResourceLocation getLoc() { + return loc; + } + + @FunctionalInterface + public interface ModelRedirectorSupplier { + + PipeModelRedirector create(ModelResourceLocation loc, MaterialModelSupplier supplier, + Function stackMaterialFunction); + } + + protected class FakeItemOverrideList extends ItemOverrideList { + + @Override + public @NotNull IBakedModel handleItemState(@NotNull IBakedModel originalModel, @NotNull ItemStack stack, + World world, EntityLivingBase entity) { + if (originalModel instanceof PipeModelRedirector model) { + + PipeItemModel item = model.supplier.getModel(model.stackMaterialFunction.apply(stack)) + .getItemModel(PipeModelRedirector.this, stack, world, entity); + if (item != null) return item; + } + return originalModel; + } + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeModelRegistry.java b/src/main/java/gregtech/client/renderer/pipe/PipeModelRegistry.java new file mode 100644 index 00000000000..88f98c48611 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/PipeModelRegistry.java @@ -0,0 +1,235 @@ +package gregtech.client.renderer.pipe; + +import gregtech.api.pipenet.block.material.ItemBlockMaterialPipe; +import gregtech.api.unification.material.Material; +import gregtech.api.unification.material.properties.PropertyKey; +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.util.MaterialModelOverride; +import gregtech.client.renderer.pipe.util.MaterialModelSupplier; +import gregtech.client.renderer.texture.Textures; + +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.registry.IRegistry; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.Range; + +@SideOnly(Side.CLIENT) +public final class PipeModelRegistry { + + public static final int PIPE_MODEL_COUNT = 7; + private static final Object2ObjectOpenHashMap PIPE = new Object2ObjectOpenHashMap<>(); + private static final PipeModelRedirector[] PIPE_MODELS = new PipeModelRedirector[PIPE_MODEL_COUNT]; + private static final ObjectLinkedOpenHashSet> PIPE_OVERRIDES = new ObjectLinkedOpenHashSet<>(); + private static final Object2ObjectOpenHashMap PIPE_RESTRICTIVE = new Object2ObjectOpenHashMap<>(); + private static final PipeModelRedirector[] PIPE_RESTRICTIVE_MODELS = new PipeModelRedirector[PIPE_MODEL_COUNT]; + private static final ObjectLinkedOpenHashSet> PIPE_RESTRICTIVE_OVERRIDES = new ObjectLinkedOpenHashSet<>(); + + public static final int CABLE_MODEL_COUNT = 6; + private static final Object2ObjectOpenHashMap CABLE = new Object2ObjectOpenHashMap<>(); + private static final PipeModelRedirector[] CABLE_MODELS = new PipeModelRedirector[CABLE_MODEL_COUNT]; + private static final ObjectLinkedOpenHashSet> CABLE_OVERRIDES = new ObjectLinkedOpenHashSet<>(); + + private static final ActivablePipeModel OPTICAL; + private static final PipeModelRedirector OPTICAL_MODEL; + + private static final ActivablePipeModel LASER; + private static final PipeModelRedirector LASER_MODEL; + + static { + initPipes(); + initCables(); + ResourceLocation loc = GTUtility.gregtechId("block/pipe_activable"); + OPTICAL = new ActivablePipeModel( + Textures.PipeTextures.OPTICAL_PIPE_IN, Textures.PipeTextures.OPTICAL_PIPE_SIDE, + Textures.PipeTextures.OPTICAL_PIPE_SIDE_OVERLAY, Textures.PipeTextures.OPTICAL_PIPE_SIDE_OVERLAY_ACTIVE, + false); + OPTICAL_MODEL = new PipeModelRedirector(new ModelResourceLocation(loc, "optical"), m -> OPTICAL, s -> null); + LASER = new ActivablePipeModel(Textures.PipeTextures.LASER_PIPE_IN, Textures.PipeTextures.LASER_PIPE_SIDE, + Textures.PipeTextures.LASER_PIPE_OVERLAY, + Textures.PipeTextures.LASER_PIPE_OVERLAY_EMISSIVE, true); + LASER_MODEL = new PipeModelRedirector(new ModelResourceLocation(loc, "laser"), m -> LASER, s -> null); + } + + public static void registerPipeOverride(@NotNull MaterialModelOverride override) { + PIPE_OVERRIDES.addAndMoveToFirst(override); + PIPE.clear(); + PIPE.trim(16); + } + + public static void registerPipeRestrictiveOverride(@NotNull MaterialModelOverride override) { + PIPE_RESTRICTIVE_OVERRIDES.addAndMoveToFirst(override); + PIPE_RESTRICTIVE.clear(); + PIPE_RESTRICTIVE.trim(16); + } + + public static void registerCableOverride(@NotNull MaterialModelOverride override) { + CABLE_OVERRIDES.addAndMoveToFirst(override); + CABLE.clear(); + CABLE.trim(16); + } + + public static PipeModelRedirector getPipeModel(@Range(from = 0, to = PIPE_MODEL_COUNT - 1) int i) { + return PIPE_MODELS[i]; + } + + public static PipeModelRedirector getPipeRestrictiveModel(@Range(from = 0, to = PIPE_MODEL_COUNT - 1) int i) { + return PIPE_RESTRICTIVE_MODELS[i]; + } + + public static PipeModelRedirector getCableModel(@Range(from = 0, to = CABLE_MODEL_COUNT - 1) int i) { + return CABLE_MODELS[i]; + } + + public static PipeModelRedirector getOpticalModel() { + return OPTICAL_MODEL; + } + + public static PipeModelRedirector getLaserModel() { + return LASER_MODEL; + } + + public static void registerModels(@NotNull IRegistry registry) { + for (PipeModelRedirector redirector : PIPE_MODELS) { + registry.putObject(redirector.getLoc(), redirector); + } + for (PipeModelRedirector redirector : PIPE_RESTRICTIVE_MODELS) { + registry.putObject(redirector.getLoc(), redirector); + } + for (PipeModelRedirector redirector : CABLE_MODELS) { + registry.putObject(redirector.getLoc(), redirector); + } + registry.putObject(OPTICAL_MODEL.getLoc(), OPTICAL_MODEL); + registry.putObject(LASER_MODEL.getLoc(), LASER_MODEL); + } + + public static PipeModelRedirector materialModel(@NotNull ResourceLocation loc, MaterialModelSupplier supplier, + @NotNull String variant, + PipeModelRedirector.@NotNull ModelRedirectorSupplier redirectorSupplier) { + return redirectorSupplier.create(new ModelResourceLocation(loc, variant), supplier, + stack -> { + if (stack.getItem() instanceof ItemBlockMaterialPipepipe) { + return pipe.getBlock().getItemMaterial(stack); + } else { + return null; + } + }); + } + + public static PipeModelRedirector materialModel(@NotNull ResourceLocation loc, MaterialModelSupplier supplier, + @NotNull String variant) { + return new PipeModelRedirector(new ModelResourceLocation(loc, variant), supplier, + stack -> { + if (stack.getItem() instanceof ItemBlockMaterialPipepipe) { + return pipe.getBlock().getItemMaterial(stack); + } else { + return null; + } + }); + } + + private static void initPipes() { + PipeModel[] array = new PipeModel[PIPE_MODEL_COUNT]; + // standard + array[0] = new PipeModel(Textures.PipeTextures.PIPE_TINY, Textures.PipeTextures.PIPE_SIDE, false); + array[1] = new PipeModel(Textures.PipeTextures.PIPE_SMALL, Textures.PipeTextures.PIPE_SIDE, false); + array[2] = new PipeModel(Textures.PipeTextures.PIPE_NORMAL, Textures.PipeTextures.PIPE_SIDE, false); + array[3] = new PipeModel(Textures.PipeTextures.PIPE_LARGE, Textures.PipeTextures.PIPE_SIDE, false); + array[4] = new PipeModel(Textures.PipeTextures.PIPE_HUGE, Textures.PipeTextures.PIPE_SIDE, false); + array[5] = new PipeModel(Textures.PipeTextures.PIPE_QUADRUPLE, Textures.PipeTextures.PIPE_SIDE, false); + array[6] = new PipeModel(Textures.PipeTextures.PIPE_NONUPLE, Textures.PipeTextures.PIPE_SIDE, false); + PIPE_OVERRIDES.addAndMoveToLast(new MaterialModelOverride.StandardOverride<>(array, m -> true)); + + array = new PipeModel[PIPE_MODEL_COUNT]; + array[1] = new PipeModel(Textures.PipeTextures.PIPE_SMALL_WOOD, Textures.PipeTextures.PIPE_SIDE_WOOD, false); + array[2] = new PipeModel(Textures.PipeTextures.PIPE_NORMAL_WOOD, Textures.PipeTextures.PIPE_SIDE_WOOD, false); + array[3] = new PipeModel(Textures.PipeTextures.PIPE_LARGE_WOOD, Textures.PipeTextures.PIPE_SIDE_WOOD, false); + registerPipeOverride( + new MaterialModelOverride.StandardOverride<>(array, m -> m != null && m.hasProperty(PropertyKey.WOOD))); + + array = new PipeModel[PIPE_MODEL_COUNT]; + array[0] = new PipeModel(Textures.PipeTextures.PIPE_TINY, Textures.PipeTextures.PIPE_SIDE, true); + array[1] = new PipeModel(Textures.PipeTextures.PIPE_SMALL, Textures.PipeTextures.PIPE_SIDE, true); + array[2] = new PipeModel(Textures.PipeTextures.PIPE_NORMAL, Textures.PipeTextures.PIPE_SIDE, true); + array[3] = new PipeModel(Textures.PipeTextures.PIPE_LARGE, Textures.PipeTextures.PIPE_SIDE, true); + array[4] = new PipeModel(Textures.PipeTextures.PIPE_HUGE, Textures.PipeTextures.PIPE_SIDE, true); + array[5] = new PipeModel(Textures.PipeTextures.PIPE_QUADRUPLE, Textures.PipeTextures.PIPE_SIDE, true); + array[6] = new PipeModel(Textures.PipeTextures.PIPE_NONUPLE, Textures.PipeTextures.PIPE_SIDE, true); + PIPE_RESTRICTIVE_OVERRIDES.addAndMoveToLast(new MaterialModelOverride.StandardOverride<>(array, m -> true)); + + ResourceLocation loc = GTUtility.gregtechId("block/pipe_material"); + for (int i = 0; i < PIPE_MODEL_COUNT; i++) { + int finalI = i; + PIPE_MODELS[i] = materialModel(loc, m -> getOrCachePipeModel(m, finalI), String.valueOf(i)); + PIPE_RESTRICTIVE_MODELS[i] = materialModel(loc, m -> getOrCachePipeRestrictiveModel(m, finalI), + "restrictive_" + i); + } + } + + private static PipeModel getOrCachePipeModel(@Nullable Material m, int i) { + if (m == null) return PIPE_OVERRIDES.last().getModel(null, i); + PipeModel[] cached = PIPE.computeIfAbsent(m, k -> new PipeModel[PIPE_MODEL_COUNT]); + PipeModel selected = cached[i]; + if (selected == null) { + for (MaterialModelOverride override : PIPE_OVERRIDES) { + selected = override.getModel(m, i); + if (selected != null) break; + } + cached[i] = selected; + } + return selected; + } + + private static PipeModel getOrCachePipeRestrictiveModel(Material m, int i) { + if (m == null) return PIPE_RESTRICTIVE_OVERRIDES.last().getModel(null, i); + PipeModel[] cached = PIPE_RESTRICTIVE.computeIfAbsent(m, k -> new PipeModel[PIPE_MODEL_COUNT]); + PipeModel selected = cached[i]; + if (selected == null) { + for (MaterialModelOverride override : PIPE_RESTRICTIVE_OVERRIDES) { + selected = override.getModel(m, i); + if (selected != null) break; + } + cached[i] = selected; + } + return selected; + } + + private static void initCables() { + CableModel[] array = new CableModel[CABLE_MODEL_COUNT]; + for (int i = 0; i < CABLE_MODEL_COUNT; i++) { + if (i == 0) { + array[i] = new CableModel(); + continue; + } + array[i] = new CableModel(Textures.PipeTextures.INSULATION[i - 1], Textures.PipeTextures.INSULATION_FULL); + } + CABLE_OVERRIDES.addAndMoveToLast(new MaterialModelOverride.StandardOverride<>(array, m -> true)); + + ResourceLocation loc = GTUtility.gregtechId("block/cable"); + for (int i = 0; i < CABLE_MODEL_COUNT; i++) { + int finalI = i; + CABLE_MODELS[i] = materialModel(loc, m -> getOrCacheCableModel(m, finalI), String.valueOf(i)); + } + } + + private static CableModel getOrCacheCableModel(@Nullable Material m, int i) { + if (m == null) return CABLE_OVERRIDES.last().getModel(null, i); + CableModel[] cached = CABLE.computeIfAbsent(m, k -> new CableModel[CABLE_MODEL_COUNT]); + CableModel selected = cached[i]; + if (selected == null) { + for (MaterialModelOverride override : CABLE_OVERRIDES) { + selected = override.getModel(m, i); + if (selected != null) break; + } + cached[i] = selected; + } + return selected; + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeRenderProperties.java b/src/main/java/gregtech/client/renderer/pipe/PipeRenderProperties.java new file mode 100644 index 00000000000..b5e96001628 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/PipeRenderProperties.java @@ -0,0 +1,24 @@ +package gregtech.client.renderer.pipe; + +import gregtech.api.block.UnlistedBooleanProperty; +import gregtech.api.block.UnlistedByteProperty; +import gregtech.api.block.UnlistedFloatProperty; +import gregtech.api.block.UnlistedIntegerProperty; +import gregtech.api.block.UnlistedPropertyMaterial; + +// holder class for render-required blockstate properties that also exists on server. +public final class PipeRenderProperties { + + // AbstractPipeModel + public static final UnlistedPropertyMaterial MATERIAL_PROPERTY = new UnlistedPropertyMaterial("material"); + public static UnlistedFloatProperty THICKNESS_PROPERTY = new UnlistedFloatProperty("thickness"); + public static UnlistedPropertyMaterial FRAME_MATERIAL_PROPERTY = new UnlistedPropertyMaterial("frame_material"); + public static UnlistedByteProperty FRAME_MASK_PROPERTY = new UnlistedByteProperty("frame_mask"); + public static UnlistedByteProperty CLOSED_MASK_PROPERTY = new UnlistedByteProperty("closed_mask"); + public static UnlistedByteProperty BLOCKED_MASK_PROPERTY = new UnlistedByteProperty("blocked_mask"); + public static UnlistedIntegerProperty COLOR_PROPERTY = new UnlistedIntegerProperty("color"); + // ActivablePipeModel + public static final UnlistedBooleanProperty ACTIVE_PROPERTY = new UnlistedBooleanProperty("active"); + + private PipeRenderProperties() {} +} diff --git a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java b/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java deleted file mode 100644 index 563f780c26a..00000000000 --- a/src/main/java/gregtech/client/renderer/pipe/PipeRenderer.java +++ /dev/null @@ -1,570 +0,0 @@ -package gregtech.client.renderer.pipe; - -import gregtech.api.cover.CoverHolder; -import gregtech.api.pipenet.block.BlockPipe; -import gregtech.api.pipenet.block.IPipeType; -import gregtech.api.pipenet.block.ItemBlockPipe; -import gregtech.api.pipenet.block.material.BlockMaterialPipe; -import gregtech.api.pipenet.block.material.TileEntityMaterialPipeBase; -import gregtech.api.pipenet.tile.IPipeTile; -import gregtech.api.pipenet.tile.TileEntityPipeBase; -import gregtech.api.unification.material.Material; -import gregtech.api.unification.material.info.MaterialIconType; -import gregtech.api.util.GTUtility; -import gregtech.client.renderer.CubeRendererState; -import gregtech.client.renderer.texture.Textures; -import gregtech.client.utils.ItemRenderCompat; -import gregtech.client.utils.RenderUtil; - -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType; -import net.minecraft.client.renderer.block.model.ModelResourceLocation; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.renderer.texture.TextureMap; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.item.ItemStack; -import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.EnumBlockRenderType; -import net.minecraft.util.EnumFacing; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.IBlockAccess; -import net.minecraftforge.client.MinecraftForgeClient; -import net.minecraftforge.client.event.ModelBakeEvent; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.common.model.IModelState; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; - -import codechicken.lib.lighting.LightMatrix; -import codechicken.lib.render.BlockRenderer; -import codechicken.lib.render.CCRenderState; -import codechicken.lib.render.block.BlockRenderingRegistry; -import codechicken.lib.render.block.ICCBlockRenderer; -import codechicken.lib.render.item.IItemRenderer; -import codechicken.lib.render.pipeline.ColourMultiplier; -import codechicken.lib.render.pipeline.IVertexOperation; -import codechicken.lib.util.TransformUtils; -import codechicken.lib.vec.Cuboid6; -import codechicken.lib.vec.Matrix4; -import codechicken.lib.vec.Translation; -import codechicken.lib.vec.Vector3; -import codechicken.lib.vec.uv.IconTransformation; -import it.unimi.dsi.fastutil.ints.Int2ObjectMap; -import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.tuple.Pair; -import org.jetbrains.annotations.Nullable; -import org.lwjgl.opengl.GL11; - -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.List; - -@SideOnly(Side.CLIENT) -public abstract class PipeRenderer implements ICCBlockRenderer, IItemRenderer { - - public final ModelResourceLocation modelLocation; - private final String name; - private EnumBlockRenderType blockRenderType; - protected static final ThreadLocal blockFaces = ThreadLocal - .withInitial(BlockRenderer.BlockFace::new); - private static final Cuboid6 FRAME_RENDER_CUBOID = new Cuboid6(0.001, 0.001, 0.001, 0.999, 0.999, 0.999); - private static final EnumMap> FACE_BORDER_MAP = new EnumMap<>( - EnumFacing.class); - private static final Int2ObjectMap RESTRICTOR_MAP = new Int2ObjectOpenHashMap<>(); - - @SuppressWarnings("unused") - public static void initializeRestrictor(TextureMap map) { - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_UP, Border.TOP); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_DOWN, Border.BOTTOM); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_UD, Border.TOP, Border.BOTTOM); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_LEFT, Border.LEFT); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_UL, Border.TOP, Border.LEFT); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_DL, Border.BOTTOM, Border.LEFT); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_NR, Border.TOP, Border.BOTTOM, Border.LEFT); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_RIGHT, Border.RIGHT); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_UR, Border.TOP, Border.RIGHT); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_DR, Border.BOTTOM, Border.RIGHT); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_NL, Border.TOP, Border.BOTTOM, Border.RIGHT); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_LR, Border.LEFT, Border.RIGHT); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_ND, Border.TOP, Border.LEFT, Border.RIGHT); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY_NU, Border.BOTTOM, Border.LEFT, Border.RIGHT); - addRestrictor(Textures.PIPE_BLOCKED_OVERLAY, Border.TOP, Border.BOTTOM, Border.LEFT, Border.RIGHT); - } - - static { - FACE_BORDER_MAP.put(EnumFacing.DOWN, - borderMap(EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.WEST, EnumFacing.EAST)); - FACE_BORDER_MAP.put(EnumFacing.UP, - borderMap(EnumFacing.NORTH, EnumFacing.SOUTH, EnumFacing.WEST, EnumFacing.EAST)); - FACE_BORDER_MAP.put(EnumFacing.NORTH, - borderMap(EnumFacing.UP, EnumFacing.DOWN, EnumFacing.EAST, EnumFacing.WEST)); - FACE_BORDER_MAP.put(EnumFacing.SOUTH, - borderMap(EnumFacing.UP, EnumFacing.DOWN, EnumFacing.WEST, EnumFacing.EAST)); - FACE_BORDER_MAP.put(EnumFacing.WEST, - borderMap(EnumFacing.UP, EnumFacing.DOWN, EnumFacing.NORTH, EnumFacing.SOUTH)); - FACE_BORDER_MAP.put(EnumFacing.EAST, - borderMap(EnumFacing.UP, EnumFacing.DOWN, EnumFacing.SOUTH, EnumFacing.NORTH)); - } - - public PipeRenderer(String name, ModelResourceLocation modelLocation) { - this.name = name; - this.modelLocation = modelLocation; - } - - public PipeRenderer(String name, ResourceLocation modelLocation) { - this(name, new ModelResourceLocation(modelLocation, "normal")); - } - - public void preInit() { - blockRenderType = BlockRenderingRegistry.createRenderType(name); - BlockRenderingRegistry.registerRenderer(blockRenderType, this); - MinecraftForge.EVENT_BUS.register(this); - } - - public ModelResourceLocation getModelLocation() { - return modelLocation; - } - - public EnumBlockRenderType getBlockRenderType() { - return blockRenderType; - } - - public abstract void registerIcons(TextureMap map); - - @SubscribeEvent - public void onModelsBake(ModelBakeEvent event) { - event.getModelRegistry().putObject(modelLocation, this); - } - - public abstract void buildRenderer(PipeRenderContext renderContext, BlockPipe blockPipe, - @Nullable IPipeTile pipeTile, IPipeType pipeType, - @Nullable Material material); - - @Override - public void renderItem(ItemStack rawItemStack, TransformType transformType) { - ItemStack stack = ItemRenderCompat.getRepresentedStack(rawItemStack); - if (!(stack.getItem() instanceof ItemBlockPipe)) { - return; - } - CCRenderState renderState = CCRenderState.instance(); - GlStateManager.enableBlend(); - renderState.reset(); - renderState.startDrawing(GL11.GL_QUADS, DefaultVertexFormats.ITEM); - BlockPipe blockFluidPipe = (BlockPipe) ((ItemBlockPipe) stack.getItem()).getBlock(); - IPipeType pipeType = blockFluidPipe.getItemPipeType(stack); - Material material = blockFluidPipe instanceof BlockMaterialPipe blockMaterialPipe ? - blockMaterialPipe.getItemMaterial(stack) : null; - if (pipeType != null) { - // 12 == 0b1100 is North and South connection (index 2 & 3) - PipeRenderContext renderContext = new PipeRenderContext(12, 0, pipeType.getThickness()); - renderContext.color = GTUtility.convertRGBtoOpaqueRGBA_CL(getPipeColor(material, -1)); - buildRenderer(renderContext, blockFluidPipe, null, pipeType, material); - renderPipeBlock(renderState, renderContext); - } - renderState.draw(); - GlStateManager.disableBlend(); - } - - @Override - public boolean renderBlock(IBlockAccess world, BlockPos pos, IBlockState state, BufferBuilder buffer) { - CCRenderState renderState = CCRenderState.instance(); - renderState.reset(); - renderState.bind(buffer); - renderState.setBrightness(world, pos); - - BlockPipe blockPipe = (BlockPipe) state.getBlock(); - IPipeTile pipeTile = blockPipe.getPipeTileEntity(world, pos); - - if (pipeTile == null) { - return false; - } - - IPipeType pipeType = pipeTile.getPipeType(); - Material pipeMaterial = pipeTile instanceof TileEntityMaterialPipeBase ? - ((TileEntityMaterialPipeBase) pipeTile).getPipeMaterial() : null; - int paintingColor = pipeTile.getPaintingColor(); - int connectedSidesMap = pipeTile.getVisualConnections(); - int blockedConnections = pipeTile.getBlockedConnections(); - - if (pipeType != null) { - BlockRenderLayer renderLayer = MinecraftForgeClient.getRenderLayer(); - boolean[] sideMask = new boolean[EnumFacing.VALUES.length]; - for (EnumFacing side : EnumFacing.VALUES) { - sideMask[side.getIndex()] = state.shouldSideBeRendered(world, pos, side); - } - Textures.RENDER_STATE.set(new CubeRendererState(renderLayer, sideMask, world)); - if (canRenderInLayer(renderLayer)) { - renderState.lightMatrix.locate(world, pos); - PipeRenderContext renderContext = new PipeRenderContext(pos, renderState.lightMatrix, connectedSidesMap, - blockedConnections, pipeType.getThickness()); - renderContext.color = GTUtility.convertRGBtoOpaqueRGBA_CL(getPipeColor(pipeMaterial, paintingColor)); - buildRenderer(renderContext, blockPipe, pipeTile, pipeType, pipeMaterial); - if (renderLayer == BlockRenderLayer.CUTOUT) { - renderPipeBlock(renderState, renderContext); - renderFrame(pipeTile, pos, renderState, connectedSidesMap); - } else { - renderOtherLayers(renderLayer, renderState, renderContext); - } - } - - CoverHolder coverHolder = pipeTile.getCoverableImplementation(); - coverHolder.renderCovers(renderState, new Matrix4().translate(pos.getX(), pos.getY(), pos.getZ()), - renderLayer); - Textures.RENDER_STATE.remove(); - } - return true; - } - - private static void renderFrame(IPipeTile pipeTile, BlockPos pos, CCRenderState renderState, - int connections) { - Material frameMaterial = pipeTile.getFrameMaterial(); - if (frameMaterial != null) { - ResourceLocation rl = MaterialIconType.frameGt.getBlockTexturePath(frameMaterial.getMaterialIconSet()); - TextureAtlasSprite sprite = Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(rl.toString()); - IVertexOperation[] pipeline = { - new Translation(pos), - renderState.lightMatrix, - new IconTransformation(sprite), - new ColourMultiplier(GTUtility.convertRGBtoOpaqueRGBA_CL(frameMaterial.getMaterialRGB())) - }; - - for (EnumFacing side : EnumFacing.VALUES) { - // only render frame if it doesn't have a cover - if ((connections & 1 << (12 + side.getIndex())) == 0) { - BlockRenderer.BlockFace blockFace = blockFaces.get(); - blockFace.loadCuboidFace(FRAME_RENDER_CUBOID, side.getIndex()); - renderState.setPipeline(blockFace, 0, blockFace.verts.length, pipeline); - renderState.render(); - } - } - } - } - - private static int getPipeColor(Material material, int paintingColor) { - if (paintingColor == -1) { - return material == null ? 0xFFFFFF : material.getMaterialRGB(); - } - return paintingColor; - } - - public void renderPipeBlock(CCRenderState renderState, PipeRenderContext renderContext) { - Cuboid6 cuboid6 = BlockPipe.getSideBox(null, renderContext.pipeThickness); - if ((renderContext.connections & 63) == 0) { - // base pipe without connections - for (EnumFacing renderedSide : EnumFacing.VALUES) { - renderOpenFace(renderState, renderContext, renderedSide, cuboid6); - } - } else { - for (EnumFacing renderedSide : EnumFacing.VALUES) { - // if connection is blocked - if ((renderContext.connections & 1 << renderedSide.getIndex()) == 0) { - int oppositeIndex = renderedSide.getOpposite().getIndex(); - if ((renderContext.connections & 1 << oppositeIndex) > 0 && - (renderContext.connections & 63 & ~(1 << oppositeIndex)) == 0) { - // render open texture if opposite is open and no other - renderOpenFace(renderState, renderContext, renderedSide, cuboid6); - } else { - // else render pipe side - renderPipeSide(renderState, renderContext, renderedSide, cuboid6); - } - } else { - // else render connection cuboid - renderPipeCube(renderState, renderContext, renderedSide); - } - } - } - } - - protected void renderPipeCube(CCRenderState renderState, PipeRenderContext renderContext, EnumFacing side) { - Cuboid6 cuboid = BlockPipe.getSideBox(side, renderContext.pipeThickness); - boolean doRenderBlockedOverlay = (renderContext.blockedConnections & (1 << side.getIndex())) > 0; - // render connection cuboid - for (EnumFacing renderedSide : EnumFacing.VALUES) { - if (renderedSide.getAxis() != side.getAxis()) { - // render side textures - renderPipeSide(renderState, renderContext, renderedSide, cuboid); - if (doRenderBlockedOverlay) { - // render blocked connections - renderFace(renderState, renderContext.blockedOverlay, renderedSide, cuboid); - } - } - } - if ((renderContext.connections & 1 << (6 + side.getIndex())) > 0) { - // if neighbour pipe is smaller, render closed texture - renderPipeSide(renderState, renderContext, side, cuboid); - } else { - if ((renderContext.connections & 1 << (12 + side.getIndex())) > 0) { - // if face has a cover offset face by 0.001 to avoid z fighting - cuboid = BlockPipe.getCoverSideBox(side, renderContext.pipeThickness); - } - renderOpenFace(renderState, renderContext, side, cuboid); - } - } - - protected void renderOpenFace(CCRenderState renderState, PipeRenderContext renderContext, EnumFacing side, - Cuboid6 cuboid6) { - for (IVertexOperation[] vertexOperations : renderContext.openFaceRenderer) { - renderFace(renderState, vertexOperations, side, cuboid6); - } - } - - protected void renderPipeSide(CCRenderState renderState, PipeRenderContext renderContext, EnumFacing side, - Cuboid6 cuboid6) { - for (IVertexOperation[] vertexOperations : renderContext.pipeSideRenderer) { - renderFace(renderState, vertexOperations, side, cuboid6); - } - int blockedConnections = renderContext.getBlockedConnections(); - int connections = renderContext.getConnections(); - if (blockedConnections != 0) { - int borderMask = 0; - for (Border border : Border.VALUES) { - EnumFacing borderSide = getSideAtBorder(side, border); - if (TileEntityPipeBase.isFaceBlocked(blockedConnections, borderSide) && - TileEntityPipeBase.isConnected(connections, borderSide)) { - // only render when the side is blocked *and* connected - borderMask |= border.mask; - } - } - if (borderMask != 0) { - IVertexOperation[] pipeline = ArrayUtils.addAll(renderContext.getBaseVertexOperation(), - RESTRICTOR_MAP.get(borderMask)); - renderFace(renderState, pipeline, side, cuboid6); - } - } - } - - protected void renderFace(CCRenderState renderState, IVertexOperation[] pipeline, EnumFacing side, - Cuboid6 cuboid6) { - BlockRenderer.BlockFace blockFace = blockFaces.get(); - blockFace.loadCuboidFace(cuboid6, side.getIndex()); - renderState.setPipeline(blockFace, 0, blockFace.verts.length, pipeline); - renderState.render(); - } - - @Override - public void renderBrightness(IBlockState state, float brightness) {} - - /** - * Override to render in other layers, e.g. emissive stuff - * {@link #canRenderInLayer} also need to be overridden - */ - protected void renderOtherLayers(BlockRenderLayer layer, CCRenderState renderState, - PipeRenderContext renderContext) {} - - /** - * What layers can be rendered in. - * See also {@link #renderOtherLayers} - * - * @param layer the current layer being rendered too - * @return true if this should render in {@code layer} - */ - protected boolean canRenderInLayer(BlockRenderLayer layer) { - return layer == BlockRenderLayer.CUTOUT; - } - - @Override - public void handleRenderBlockDamage(IBlockAccess world, BlockPos pos, IBlockState state, TextureAtlasSprite sprite, - BufferBuilder buffer) { - CCRenderState renderState = CCRenderState.instance(); - renderState.reset(); - renderState.bind(buffer); - renderState.setPipeline(new Vector3(new Vec3d(pos)).translation(), new IconTransformation(sprite)); - BlockPipe blockPipe = (BlockPipe) state.getBlock(); - IPipeTile pipeTile = blockPipe.getPipeTileEntity(world, pos); - if (pipeTile == null) { - return; - } - IPipeType pipeType = pipeTile.getPipeType(); - if (pipeType == null) { - return; - } - float thickness = pipeType.getThickness(); - int connectedSidesMask = pipeTile.getConnections(); - Cuboid6 baseBox = BlockPipe.getSideBox(null, thickness); - BlockRenderer.renderCuboid(renderState, baseBox, 0); - for (EnumFacing renderSide : EnumFacing.VALUES) { - if ((connectedSidesMask & (1 << renderSide.getIndex())) > 0) { - Cuboid6 sideBox = BlockPipe.getSideBox(renderSide, thickness); - BlockRenderer.renderCuboid(renderState, sideBox, 0); - } - } - } - - @Override - public void registerTextures(TextureMap map) {} - - @Override - public IModelState getTransforms() { - return TransformUtils.DEFAULT_BLOCK; - } - - @Override - public boolean isBuiltInRenderer() { - return true; - } - - @Override - public boolean isAmbientOcclusion() { - return true; - } - - @Override - public boolean isGui3d() { - return true; - } - - public Pair getParticleTexture(IPipeTile pipeTile) { - if (pipeTile == null) { - return Pair.of(RenderUtil.getMissingSprite(), 0xFFFFFF); - } - IPipeType pipeType = pipeTile.getPipeType(); - Material material = pipeTile instanceof TileEntityMaterialPipeBase ? - ((TileEntityMaterialPipeBase) pipeTile).getPipeMaterial() : null; - if (pipeType == null) { - return Pair.of(RenderUtil.getMissingSprite(), 0xFFFFFF); - } - TextureAtlasSprite atlasSprite = getParticleTexture(pipeType, material); - int pipeColor = getPipeColor(material, pipeTile.getPaintingColor()); - return Pair.of(atlasSprite, pipeColor); - } - - public abstract TextureAtlasSprite getParticleTexture(IPipeType pipeType, @Nullable Material material); - - public static class PipeRenderContext { - - private final BlockPos pos; - private final LightMatrix lightMatrix; - protected final List openFaceRenderer = new ArrayList<>(); - protected final List pipeSideRenderer = new ArrayList<>(); - // Blocked overlay is used for the pipe connector cube, not the main cube - private final IVertexOperation[] blockedOverlay; - private final float pipeThickness; - private int color; - private final int connections; - private final int blockedConnections; - - public PipeRenderContext(BlockPos pos, LightMatrix lightMatrix, int connections, int blockedConnections, - float thickness) { - this.pos = pos; - this.lightMatrix = lightMatrix; - this.connections = connections; - this.blockedConnections = blockedConnections; - this.pipeThickness = thickness; - if (pos != null && lightMatrix != null) { - blockedOverlay = new IVertexOperation[] { new Translation(pos), lightMatrix, - new IconTransformation(Textures.PIPE_BLOCKED_OVERLAY) }; - } else { - blockedOverlay = new IVertexOperation[] { new IconTransformation(Textures.PIPE_BLOCKED_OVERLAY) }; - } - } - - public PipeRenderContext(int connections, int blockedConnections, float thickness) { - this(null, null, connections, blockedConnections, thickness); - } - - public PipeRenderContext addOpenFaceRender(IVertexOperation... vertexOperations) { - return addOpenFaceRender(true, vertexOperations); - } - - public PipeRenderContext addOpenFaceRender(boolean applyDefaultColor, IVertexOperation... vertexOperations) { - IVertexOperation[] baseVertexOperation = getBaseVertexOperation(); - baseVertexOperation = ArrayUtils.addAll(baseVertexOperation, vertexOperations); - if (applyDefaultColor) { - baseVertexOperation = ArrayUtils.addAll(baseVertexOperation, getColorOperation()); - } - openFaceRenderer.add(baseVertexOperation); - return this; - } - - public PipeRenderContext addSideRender(IVertexOperation... vertexOperations) { - return addSideRender(true, vertexOperations); - } - - public PipeRenderContext addSideRender(boolean applyDefaultColor, IVertexOperation... vertexOperations) { - IVertexOperation[] baseVertexOperation = getBaseVertexOperation(); - baseVertexOperation = ArrayUtils.addAll(baseVertexOperation, vertexOperations); - if (applyDefaultColor) { - baseVertexOperation = ArrayUtils.addAll(baseVertexOperation, getColorOperation()); - } - pipeSideRenderer.add(baseVertexOperation); - return this; - } - - public ColourMultiplier getColorOperation() { - return new ColourMultiplier(color); - } - - protected IVertexOperation[] getBaseVertexOperation() { - if (pos == null) { - return lightMatrix == null ? new IVertexOperation[0] : new IVertexOperation[] { lightMatrix }; - } - return lightMatrix == null ? new IVertexOperation[] { new Translation(pos) } : - new IVertexOperation[] { new Translation(pos), lightMatrix }; - } - - public int getConnections() { - return connections; - } - - public int getBlockedConnections() { - return blockedConnections; - } - - public List getPipeSideRenderer() { - return pipeSideRenderer; - } - - public List getOpenFaceRenderer() { - return openFaceRenderer; - } - - public float getPipeThickness() { - return pipeThickness; - } - } - - private static EnumMap borderMap(EnumFacing topSide, EnumFacing bottomSide, EnumFacing leftSide, - EnumFacing rightSide) { - EnumMap sideMap = new EnumMap<>(Border.class); - sideMap.put(Border.TOP, topSide); - sideMap.put(Border.BOTTOM, bottomSide); - sideMap.put(Border.LEFT, leftSide); - sideMap.put(Border.RIGHT, rightSide); - return sideMap; - } - - private static void addRestrictor(TextureAtlasSprite sprite, Border... borders) { - int mask = 0; - for (Border border : borders) { - mask |= border.mask; - } - RESTRICTOR_MAP.put(mask, new IVertexOperation[] { new IconTransformation(sprite) }); - } - - protected static EnumFacing getSideAtBorder(EnumFacing side, Border border) { - return FACE_BORDER_MAP.get(side).get(border); - } - - public enum Border { - - TOP, - BOTTOM, - LEFT, - RIGHT; - - public static final Border[] VALUES = values(); - - public final int mask; - - Border() { - mask = 1 << this.ordinal(); - } - } -} diff --git a/src/main/java/gregtech/client/renderer/pipe/cache/ActivableSQC.java b/src/main/java/gregtech/client/renderer/pipe/cache/ActivableSQC.java new file mode 100644 index 00000000000..4b213b6f847 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/cache/ActivableSQC.java @@ -0,0 +1,86 @@ +package gregtech.client.renderer.pipe.cache; + +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.quad.ColorData; +import gregtech.client.renderer.pipe.quad.PipeQuadHelper; +import gregtech.client.renderer.pipe.quad.QuadHelper; +import gregtech.client.renderer.pipe.quad.RecolorableBakedQuad; +import gregtech.client.renderer.pipe.util.SpriteInformation; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +import java.util.EnumMap; +import java.util.List; + +@SideOnly(Side.CLIENT) +public class ActivableSQC extends StructureQuadCache { + + protected final EnumMap overlayCoords = new EnumMap<>(EnumFacing.class); + protected final EnumMap overlayActiveCoords = new EnumMap<>(EnumFacing.class); + + protected final SpriteInformation overlayTex; + protected final SpriteInformation overlayActiveTex; + + protected ActivableSQC(PipeQuadHelper helper, SpriteInformation endTex, SpriteInformation sideTex, + SpriteInformation overlayTex, SpriteInformation overlayActiveTex) { + super(helper, endTex, sideTex); + this.overlayTex = overlayTex; + this.overlayActiveTex = overlayActiveTex; + if (helper.getLayerCount() < 2) throw new IllegalStateException( + "Cannot create an ActivableSQC without 2 or more layers present on the helper!"); + } + + public static @NotNull ActivableSQC create(PipeQuadHelper helper, SpriteInformation endTex, + SpriteInformation sideTex, SpriteInformation overlayTex, + SpriteInformation overlayActiveTex) { + helper.initialize((facing, x1, y1, z1, x2, y2, z2) -> QuadHelper.tubeOverlay(facing, x1, y1, z1, x2, y2, z2, + OVERLAY_DIST_1)); + ActivableSQC cache = new ActivableSQC(helper, endTex, sideTex, overlayTex, overlayActiveTex); + cache.buildPrototype(); + return cache; + } + + @Override + protected List buildPrototypeInternal() { + List quads = super.buildPrototypeInternal(); + buildOverlay(quads); + buildOverlayActive(quads); + return quads; + } + + protected void buildOverlay(List list) { + helper.setTargetSprite(overlayTex); + for (EnumFacing facing : EnumFacing.VALUES) { + int start = list.size(); + list.addAll(helper.visitTube(facing, 1)); + overlayCoords.put(facing, new SubListAddress(start, list.size())); + } + } + + protected void buildOverlayActive(List list) { + helper.setTargetSprite(overlayActiveTex); + for (EnumFacing facing : EnumFacing.VALUES) { + int start = list.size(); + list.addAll(helper.visitTube(facing, 1)); + overlayActiveCoords.put(facing, new SubListAddress(start, list.size())); + } + } + + public void addOverlay(List list, byte overlayMask, ColorData data, boolean active) { + List quads = cache.getQuads(data); + for (EnumFacing facing : EnumFacing.VALUES) { + if (GTUtility.evalMask(facing, overlayMask)) { + if (active) { + list.addAll(overlayActiveCoords.get(facing).getSublist(quads)); + } else { + list.addAll(overlayCoords.get(facing).getSublist(quads)); + } + } + } + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/cache/BlockableSQC.java b/src/main/java/gregtech/client/renderer/pipe/cache/BlockableSQC.java new file mode 100644 index 00000000000..59977d2b57a --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/cache/BlockableSQC.java @@ -0,0 +1,100 @@ +package gregtech.client.renderer.pipe.cache; + +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.quad.ColorData; +import gregtech.client.renderer.pipe.quad.PipeQuadHelper; +import gregtech.client.renderer.pipe.quad.QuadHelper; +import gregtech.client.renderer.pipe.quad.RecolorableBakedQuad; +import gregtech.client.renderer.pipe.util.SpriteInformation; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.EnumMap; +import java.util.List; + +import javax.vecmath.Vector3f; + +@SideOnly(Side.CLIENT) +public class BlockableSQC extends StructureQuadCache { + + protected final EnumMap blockedCoords = new EnumMap<>(EnumFacing.class); + + protected final SpriteInformation blockedTex; + + protected BlockableSQC(PipeQuadHelper helper, SpriteInformation endTex, SpriteInformation sideTex, + SpriteInformation blockedTex) { + super(helper, endTex, sideTex); + this.blockedTex = blockedTex; + if (helper.getLayerCount() < 2) throw new IllegalStateException( + "Cannot create a BlockableSQC without 2 or more layers present on the helper!"); + } + + public static @NotNull BlockableSQC create(PipeQuadHelper helper, SpriteInformation endTex, + SpriteInformation sideTex, SpriteInformation blockedTex) { + helper.initialize((facing, x1, y1, z1, x2, y2, z2) -> minLengthTube(facing, x1, y1, z1, x2, y2, z2, + OVERLAY_DIST_1, 4)); + BlockableSQC cache = new BlockableSQC(helper, endTex, sideTex, blockedTex); + cache.buildPrototype(); + return cache; + } + + public static ImmutablePair minLengthTube(@Nullable EnumFacing facing, float x1, float y1, + float z1, float x2, + float y2, float z2, float g, float minLength) { + if (facing == null) return QuadHelper.tubeOverlay(facing, x1, y1, z1, x2, y2, z2, g); + return switch (facing) { + case UP -> QuadHelper.tubeOverlay(facing, x1, Math.min(y1, y2 - minLength), z1, x2, y2, z2, g); + case DOWN -> QuadHelper.tubeOverlay(facing, x1, y1, z1, x2, Math.max(y2, y1 + minLength), z2, g); + case EAST -> QuadHelper.tubeOverlay(facing, Math.min(x1, x2 - minLength), y1, z1, x2, y2, z2, g); + case WEST -> QuadHelper.tubeOverlay(facing, x1, y1, z1, Math.max(x2, x1 + minLength), y2, z2, g); + case SOUTH -> QuadHelper.tubeOverlay(facing, x1, y1, Math.min(z1, z2 - minLength), x2, y2, z2, g); + case NORTH -> QuadHelper.tubeOverlay(facing, x1, y1, z1, x2, y2, Math.max(z2, z1 + minLength), g); + }; + } + + @Override + protected List buildPrototypeInternal() { + List quads = super.buildPrototypeInternal(); + buildBlocked(quads); + return quads; + } + + protected void buildBlocked(List list) { + helper.setTargetSprite(blockedTex); + for (EnumFacing facing : EnumFacing.VALUES) { + int start = list.size(); + list.addAll(helper.visitTube(facing, 1)); + blockedCoords.put(facing, new SubListAddress(start, list.size())); + } + } + + @Override + public void addToList(List list, byte connectionMask, byte closedMask, byte blockedMask, ColorData data, + byte coverMask) { + List quads = cache.getQuads(data); + for (EnumFacing facing : EnumFacing.VALUES) { + if (GTUtility.evalMask(facing, connectionMask)) { + list.addAll(tubeCoords.get(facing).getSublist(quads)); + if (!GTUtility.evalMask(facing, coverMask)) { + if (GTUtility.evalMask(facing, closedMask)) { + list.addAll(capperClosedCoords.get(facing).getSublist(quads)); + } else { + list.addAll(capperCoords.get(facing).getSublist(quads)); + } + } + if (GTUtility.evalMask(facing, blockedMask)) { + list.addAll(blockedCoords.get(facing).getSublist(quads)); + } + } else { + list.addAll(coreCoords.get(facing).getSublist(quads)); + } + } + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/cache/ColorQuadCache.java b/src/main/java/gregtech/client/renderer/pipe/cache/ColorQuadCache.java new file mode 100644 index 00000000000..4795aae2d26 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/cache/ColorQuadCache.java @@ -0,0 +1,39 @@ +package gregtech.client.renderer.pipe.cache; + +import gregtech.client.renderer.pipe.quad.ColorData; +import gregtech.client.renderer.pipe.quad.RecolorableBakedQuad; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; + +import java.util.List; + +@SideOnly(Side.CLIENT) +public final class ColorQuadCache { + + private final List prototypes; + + private final Object2ObjectLinkedOpenHashMap> cache; + + public ColorQuadCache(List prototypes) { + this.prototypes = prototypes; + this.cache = new Object2ObjectLinkedOpenHashMap<>(); + } + + public List getQuads(ColorData data) { + List existing = cache.get(data); + if (existing == null) { + existing = new ObjectArrayList<>(); + for (RecolorableBakedQuad quad : prototypes) { + existing.add(quad.withColor(data)); + } + cache.put(data, existing); + // if (cache.size() > 20) cache.removeLast(); + } + return existing; + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/cache/ExtraCappedSQC.java b/src/main/java/gregtech/client/renderer/pipe/cache/ExtraCappedSQC.java new file mode 100644 index 00000000000..762ce21bb87 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/cache/ExtraCappedSQC.java @@ -0,0 +1,80 @@ +package gregtech.client.renderer.pipe.cache; + +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.quad.ColorData; +import gregtech.client.renderer.pipe.quad.PipeQuadHelper; +import gregtech.client.renderer.pipe.quad.QuadHelper; +import gregtech.client.renderer.pipe.quad.RecolorableBakedQuad; +import gregtech.client.renderer.pipe.util.SpriteInformation; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +import java.util.EnumMap; +import java.util.List; + +@SideOnly(Side.CLIENT) +public class ExtraCappedSQC extends StructureQuadCache { + + protected final EnumMap extraCapperCoords = new EnumMap<>(EnumFacing.class); + + protected final SpriteInformation extraEndTex; + + protected ExtraCappedSQC(PipeQuadHelper helper, SpriteInformation endTex, SpriteInformation sideTex, + SpriteInformation extraEndTex) { + super(helper, endTex, sideTex); + this.extraEndTex = extraEndTex; + if (helper.getLayerCount() < 2) throw new IllegalStateException( + "Cannot create an ExtraCappedSQC without 2 or more layers present on the helper!"); + } + + public static @NotNull ExtraCappedSQC create(PipeQuadHelper helper, SpriteInformation endTex, + SpriteInformation sideTex, SpriteInformation extraEndTex) { + helper.initialize((facing, x1, y1, z1, x2, y2, z2) -> QuadHelper.capOverlay(facing, x1, y1, z1, x2, y2, z2, + OVERLAY_DIST_1)); + ExtraCappedSQC cache = new ExtraCappedSQC(helper, endTex, sideTex, extraEndTex); + cache.buildPrototype(); + return cache; + } + + @Override + protected List buildPrototypeInternal() { + List quads = super.buildPrototypeInternal(); + buildExtraCapper(quads); + return quads; + } + + protected void buildExtraCapper(List list) { + helper.setTargetSprite(extraEndTex); + for (EnumFacing facing : EnumFacing.VALUES) { + int start = list.size(); + list.add(helper.visitCapper(facing, 1)); + extraCapperCoords.put(facing, new SubListAddress(start, list.size())); + } + } + + @Override + public void addToList(List list, byte connectionMask, byte closedMask, byte blockedMask, ColorData data, + byte coverMask) { + List quads = cache.getQuads(data); + for (EnumFacing facing : EnumFacing.VALUES) { + if (GTUtility.evalMask(facing, connectionMask)) { + list.addAll(tubeCoords.get(facing).getSublist(quads)); + if (!GTUtility.evalMask(facing, coverMask)) { + if (GTUtility.evalMask(facing, closedMask)) { + list.addAll(capperClosedCoords.get(facing).getSublist(quads)); + } else { + list.addAll(capperCoords.get(facing).getSublist(quads)); + list.addAll(extraCapperCoords.get(facing).getSublist(quads)); + } + } + } else { + list.addAll(coreCoords.get(facing).getSublist(quads)); + } + } + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/cache/RestrictiveSQC.java b/src/main/java/gregtech/client/renderer/pipe/cache/RestrictiveSQC.java new file mode 100644 index 00000000000..8d986a0323e --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/cache/RestrictiveSQC.java @@ -0,0 +1,86 @@ +package gregtech.client.renderer.pipe.cache; + +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.quad.ColorData; +import gregtech.client.renderer.pipe.quad.PipeQuadHelper; +import gregtech.client.renderer.pipe.quad.RecolorableBakedQuad; +import gregtech.client.renderer.pipe.util.SpriteInformation; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; + +import java.util.EnumMap; +import java.util.List; + +@SideOnly(Side.CLIENT) +public class RestrictiveSQC extends BlockableSQC { + + protected final EnumMap restrictiveCoords = new EnumMap<>(EnumFacing.class); + + private final SpriteInformation restrictiveTex; + + protected RestrictiveSQC(PipeQuadHelper helper, SpriteInformation endTex, SpriteInformation sideTex, + SpriteInformation blockedTex, SpriteInformation restrictiveTex) { + super(helper, endTex, sideTex, blockedTex); + this.restrictiveTex = restrictiveTex; + if (helper.getLayerCount() < 3) throw new IllegalStateException( + "Cannot create a RestrictiveSQC without 3 or more layers present on the helper!"); + } + + public static @NotNull RestrictiveSQC create(PipeQuadHelper helper, SpriteInformation endTex, + SpriteInformation sideTex, + SpriteInformation blockedTex, SpriteInformation restrictiveTex) { + helper.initialize( + (facing, x1, y1, z1, x2, y2, z2) -> minLengthTube(facing, x1, y1, z1, x2, y2, z2, + OVERLAY_DIST_2, 4), + (facing, x1, y1, z1, x2, y2, z2) -> minLengthTube(facing, x1, y1, z1, x2, y2, z2, + OVERLAY_DIST_1, 2)); + RestrictiveSQC sqc = new RestrictiveSQC(helper, endTex, sideTex, blockedTex, restrictiveTex); + sqc.buildPrototype(); + return sqc; + } + + @Override + protected List buildPrototypeInternal() { + List quads = super.buildPrototypeInternal(); + buildRestrictive(quads); + return quads; + } + + protected void buildRestrictive(List list) { + helper.setTargetSprite(restrictiveTex); + for (EnumFacing facing : EnumFacing.VALUES) { + int start = list.size(); + list.addAll(helper.visitTube(facing, 2)); + restrictiveCoords.put(facing, new SubListAddress(start, list.size())); + } + } + + @Override + public void addToList(List list, byte connectionMask, byte closedMask, byte blockedMask, ColorData data, + byte coverMask) { + List quads = cache.getQuads(data); + for (EnumFacing facing : EnumFacing.VALUES) { + if (GTUtility.evalMask(facing, connectionMask)) { + list.addAll(tubeCoords.get(facing).getSublist(quads)); + list.addAll(restrictiveCoords.get(facing).getSublist(quads)); + if (!GTUtility.evalMask(facing, coverMask)) { + if (GTUtility.evalMask(facing, closedMask)) { + list.addAll(capperClosedCoords.get(facing).getSublist(quads)); + } else { + list.addAll(capperCoords.get(facing).getSublist(quads)); + } + } + if (GTUtility.evalMask(facing, blockedMask)) { + list.addAll(blockedCoords.get(facing).getSublist(quads)); + } + } else { + list.addAll(coreCoords.get(facing).getSublist(quads)); + } + } + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/cache/StructureQuadCache.java b/src/main/java/gregtech/client/renderer/pipe/cache/StructureQuadCache.java new file mode 100644 index 00000000000..8bedc13581e --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/cache/StructureQuadCache.java @@ -0,0 +1,119 @@ +package gregtech.client.renderer.pipe.cache; + +import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.quad.*; +import gregtech.client.renderer.pipe.util.SpriteInformation; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.jetbrains.annotations.NotNull; + +import java.util.EnumMap; +import java.util.List; + +@SideOnly(Side.CLIENT) +public class StructureQuadCache { + + public static final float OVERLAY_DIST_1 = 0.003f; + public static final float OVERLAY_DIST_2 = 0.006f; + + protected final PipeQuadHelper helper; + + protected ColorQuadCache cache; + + protected final EnumMap tubeCoords = new EnumMap<>(EnumFacing.class); + + protected final EnumMap coreCoords = new EnumMap<>(EnumFacing.class); + protected final EnumMap capperCoords = new EnumMap<>(EnumFacing.class); + protected final EnumMap capperClosedCoords = new EnumMap<>(EnumFacing.class); + + protected final SpriteInformation endTex; + protected final SpriteInformation sideTex; + + protected StructureQuadCache(PipeQuadHelper helper, SpriteInformation endTex, SpriteInformation sideTex) { + this.helper = helper; + this.endTex = endTex; + this.sideTex = sideTex; + if (helper.getLayerCount() < 1) + throw new IllegalStateException("Cannot create an SQC without at least one layer present on the helper!"); + } + + public static @NotNull StructureQuadCache create(PipeQuadHelper helper, SpriteInformation endTex, + SpriteInformation sideTex) { + StructureQuadCache cache = new StructureQuadCache(helper.initialize(), endTex, sideTex); + cache.buildPrototype(); + return cache; + } + + protected void buildPrototype() { + this.cache = new ColorQuadCache(this.buildPrototypeInternal()); + } + + protected List buildPrototypeInternal() { + List quads = new ObjectArrayList<>(); + buildTube(quads); + buildCore(quads); + buildCapper(quads); + buildCapperClosed(quads); + return quads; + } + + protected void buildTube(List list) { + helper.setTargetSprite(sideTex); + for (EnumFacing facing : EnumFacing.VALUES) { + int start = list.size(); + list.addAll(helper.visitTube(facing)); + tubeCoords.put(facing, new SubListAddress(start, list.size())); + } + } + + protected void buildCore(List list) { + helper.setTargetSprite(sideTex); + for (EnumFacing facing : EnumFacing.VALUES) { + int start = list.size(); + list.add(helper.visitCore(facing)); + coreCoords.put(facing, new SubListAddress(start, start + 1)); + } + } + + protected void buildCapper(List list) { + helper.setTargetSprite(endTex); + for (EnumFacing facing : EnumFacing.VALUES) { + int start = list.size(); + list.add(helper.visitCapper(facing)); + capperCoords.put(facing, new SubListAddress(start, start + 1)); + } + } + + protected void buildCapperClosed(List list) { + helper.setTargetSprite(sideTex); + for (EnumFacing facing : EnumFacing.VALUES) { + int start = list.size(); + list.add(helper.visitCapper(facing)); + capperClosedCoords.put(facing, new SubListAddress(start, start + 1)); + } + } + + public void addToList(List list, byte connectionMask, byte closedMask, byte blockedMask, ColorData data, + byte coverMask) { + List quads = cache.getQuads(data); + for (EnumFacing facing : EnumFacing.VALUES) { + if (GTUtility.evalMask(facing, connectionMask)) { + list.addAll(tubeCoords.get(facing).getSublist(quads)); + if (!GTUtility.evalMask(facing, coverMask)) { + if (GTUtility.evalMask(facing, closedMask)) { + list.addAll(capperClosedCoords.get(facing).getSublist(quads)); + } else { + list.addAll(capperCoords.get(facing).getSublist(quads)); + } + } + } else { + list.addAll(coreCoords.get(facing).getSublist(quads)); + } + } + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/cache/SubListAddress.java b/src/main/java/gregtech/client/renderer/pipe/cache/SubListAddress.java new file mode 100644 index 00000000000..23453222ce8 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/cache/SubListAddress.java @@ -0,0 +1,14 @@ +package gregtech.client.renderer.pipe.cache; + +import com.github.bsideup.jabel.Desugar; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +@Desugar +public record SubListAddress(int startInclusive, int endExclusive) { + + public @NotNull List getSublist(@NotNull List list) { + return list.subList(startInclusive, endExclusive); + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/cover/CoverRenderer.java b/src/main/java/gregtech/client/renderer/pipe/cover/CoverRenderer.java new file mode 100644 index 00000000000..2b4400991e0 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/cover/CoverRenderer.java @@ -0,0 +1,17 @@ +package gregtech.client.renderer.pipe.cover; + +import gregtech.client.renderer.pipe.quad.ColorData; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; + +import java.util.EnumSet; +import java.util.List; + +@FunctionalInterface +public interface CoverRenderer { + + void addQuads(List quads, EnumFacing facing, EnumSet renderPlate, boolean renderBackside, + BlockRenderLayer renderLayer, ColorData data); +} diff --git a/src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererBuilder.java b/src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererBuilder.java new file mode 100644 index 00000000000..20999ca9b83 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererBuilder.java @@ -0,0 +1,148 @@ +package gregtech.client.renderer.pipe.cover; + +import gregtech.client.renderer.pipe.cache.ColorQuadCache; +import gregtech.client.renderer.pipe.cache.SubListAddress; +import gregtech.client.renderer.pipe.quad.ColorData; +import gregtech.client.renderer.pipe.quad.QuadHelper; +import gregtech.client.renderer.pipe.quad.RecolorableBakedQuad; +import gregtech.client.renderer.pipe.quad.UVMapper; +import gregtech.client.renderer.pipe.util.SpriteInformation; +import gregtech.client.renderer.texture.Textures; +import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; +import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; +import gregtech.client.utils.BloomEffectUtil; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.List; + +import javax.vecmath.Vector3f; + +@SideOnly(Side.CLIENT) +public class CoverRendererBuilder { + + private static final ColorQuadCache[] PLATE_QUADS; + private static final EnumMap PLATE_COORDS = new EnumMap<>(EnumFacing.class); + + private static final UVMapper defaultMapper = UVMapper.standard(0); + + static { + PLATE_QUADS = new ColorQuadCache[Textures.VOLTAGE_CASINGS.length]; + for (int i = 0; i < Textures.VOLTAGE_CASINGS.length; i++) { + if (Textures.VOLTAGE_CASINGS[i] == null) break; + PLATE_QUADS[i] = buildPlates(new SpriteInformation(plateSprite(i), 0)); + } + } + + private static @NotNull TextureAtlasSprite plateSprite(int i) { + return Textures.VOLTAGE_CASINGS[i].getSpriteOnSide(SimpleSidedCubeRenderer.RenderSide.SIDE); + } + + public static ColorQuadCache buildPlates(SpriteInformation sprite) { + List quads = new ObjectArrayList<>(); + for (EnumFacing facing : EnumFacing.VALUES) { + PLATE_COORDS.put(facing, buildPlates(quads, facing, sprite)); + } + return new ColorQuadCache(quads); + } + + protected static SubListAddress buildPlates(List quads, EnumFacing facing, + SpriteInformation sprite) { + int start = quads.size(); + Pair box = CoverRendererValues.PLATE_BOXES.get(facing); + for (EnumFacing dir : EnumFacing.values()) { + quads.add(QuadHelper.buildQuad(dir, box, CoverRendererBuilder.defaultMapper, sprite)); + } + return new SubListAddress(start, quads.size()); + } + + protected static void addPlates(List quads, List plateQuads, EnumSet plates) { + for (EnumFacing facing : plates) { + quads.add(plateQuads.get(facing.ordinal())); + } + } + + protected final TextureAtlasSprite sprite; + protected final TextureAtlasSprite spriteEmissive; + + protected UVMapper mapper = defaultMapper; + protected UVMapper mapperEmissive = defaultMapper; + + protected ColorQuadCache plateQuads = PLATE_QUADS[1]; + + public CoverRendererBuilder(@NotNull SimpleOverlayRenderer overlay) { + this(overlay.getSprite(), overlay.getSpriteEmissive()); + } + + public CoverRendererBuilder(@NotNull TextureAtlasSprite sprite, @Nullable TextureAtlasSprite spriteEmissive) { + this.sprite = sprite; + this.spriteEmissive = spriteEmissive; + } + + public CoverRendererBuilder setMapper(@NotNull UVMapper mapper) { + this.mapper = mapper; + return this; + } + + public CoverRendererBuilder setMapperEmissive(@NotNull UVMapper mapperEmissive) { + this.mapperEmissive = mapperEmissive; + return this; + } + + public CoverRendererBuilder setPlateQuads(ColorQuadCache cache) { + this.plateQuads = cache; + return this; + } + + public CoverRendererBuilder setPlateQuads(int index) { + this.plateQuads = PLATE_QUADS[index]; + return this; + } + + protected static List getPlates(EnumFacing facing, ColorData data, ColorQuadCache plateQuads) { + return PLATE_COORDS.get(facing).getSublist(plateQuads.getQuads(data)); + } + + public CoverRenderer build() { + EnumMap> spriteQuads = new EnumMap<>(EnumFacing.class); + EnumMap> spriteEmissiveQuads = spriteEmissive != null ? + new EnumMap<>(EnumFacing.class) : null; + for (EnumFacing facing : EnumFacing.VALUES) { + spriteQuads.put(facing, ImmutablePair.of( + QuadHelper.buildQuad(facing, CoverRendererValues.OVERLAY_BOXES_1.get(facing), mapper, sprite), + QuadHelper.buildQuad(facing.getOpposite(), CoverRendererValues.OVERLAY_BOXES_1.get(facing), mapper, + sprite))); + if (spriteEmissive != null) spriteEmissiveQuads.put(facing, ImmutablePair.of( + QuadHelper.buildQuad(facing, CoverRendererValues.OVERLAY_BOXES_2.get(facing), mapperEmissive, + spriteEmissive), + QuadHelper.buildQuad(facing.getOpposite(), CoverRendererValues.OVERLAY_BOXES_2.get(facing), + mapperEmissive, + spriteEmissive))); + } + + return (quads, facing, renderPlate, renderBackside, renderLayer, data) -> { + if (renderLayer == BlockRenderLayer.CUTOUT_MIPPED) { + addPlates(quads, getPlates(facing, data, plateQuads), renderPlate); + quads.add(spriteQuads.get(facing).getLeft()); + if (renderBackside) quads.add(spriteQuads.get(facing).getRight()); + } + if (spriteEmissiveQuads != null && renderLayer == BloomEffectUtil.getEffectiveBloomLayer()) { + quads.add(spriteEmissiveQuads.get(facing).getLeft()); + if (renderBackside) quads.add(spriteEmissiveQuads.get(facing).getRight()); + } + }; + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererPackage.java b/src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererPackage.java new file mode 100644 index 00000000000..b5d81bd807c --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererPackage.java @@ -0,0 +1,82 @@ +package gregtech.client.renderer.pipe.cover; + +import gregtech.client.renderer.pipe.quad.ColorData; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.common.property.IUnlistedProperty; + +import org.jetbrains.annotations.NotNull; + +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.List; + +public final class CoverRendererPackage { + + public static final CoverRendererPackage EMPTY = new CoverRendererPackage(false); + public static final UnlistedCRPProperty CRP_PROPERTY = new UnlistedCRPProperty("CRP"); + + private final EnumMap renderers = new EnumMap<>(EnumFacing.class); + private final EnumSet plates = EnumSet.allOf(EnumFacing.class); + + private final boolean renderBackside; + + public CoverRendererPackage(boolean renderBackside) { + this.renderBackside = renderBackside; + } + + public void addRenderer(CoverRenderer renderer, @NotNull EnumFacing facing) { + renderers.put(facing, renderer); + plates.remove(facing); + } + + public void addQuads(List quads, BlockRenderLayer renderLayer, ColorData data) { + for (var renderer : renderers.entrySet()) { + EnumSet plates = EnumSet.copyOf(this.plates); + // force front and back plates to render + plates.add(renderer.getKey()); + plates.add(renderer.getKey().getOpposite()); + renderer.getValue().addQuads(quads, renderer.getKey(), plates, renderBackside, renderLayer, data); + } + } + + public byte getMask() { + byte mask = 0; + for (EnumFacing facing : renderers.keySet()) { + mask |= 1 << facing.ordinal(); + } + return mask; + } + + public static class UnlistedCRPProperty implements IUnlistedProperty { + + private final String name; + + public UnlistedCRPProperty(@NotNull String name) { + this.name = name; + } + + @NotNull + @Override + public String getName() { + return name; + } + + @Override + public boolean isValid(CoverRendererPackage value) { + return true; + } + + @Override + public Class getType() { + return CoverRendererPackage.class; + } + + @Override + public String valueToString(CoverRendererPackage value) { + return value.toString(); + } + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererValues.java b/src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererValues.java new file mode 100644 index 00000000000..6e9d51d5385 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererValues.java @@ -0,0 +1,38 @@ +package gregtech.client.renderer.pipe.cover; + +import gregtech.api.cover.CoverUtil; +import gregtech.client.renderer.pipe.quad.QuadHelper; + +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; + +import org.apache.commons.lang3.tuple.Pair; + +import java.util.EnumMap; + +import javax.vecmath.Vector3f; + +public class CoverRendererValues { + + private static final float OVERLAY_DIST_1 = 0.003f; + private static final float OVERLAY_DIST_2 = 0.006f; + + public static final EnumMap PLATE_AABBS = new EnumMap<>(EnumFacing.class); + static final EnumMap> PLATE_BOXES = new EnumMap<>(EnumFacing.class); + static final EnumMap> OVERLAY_BOXES_1 = new EnumMap<>(EnumFacing.class); + static final EnumMap> OVERLAY_BOXES_2 = new EnumMap<>(EnumFacing.class); + + static { + for (EnumFacing facing : EnumFacing.VALUES) { + PLATE_AABBS.put(facing, CoverUtil.getCoverPlateBox(facing, 1d / 16).aabb()); + } + for (var value : PLATE_AABBS.entrySet()) { + // make sure that plates render slightly below any normal block quad + PLATE_BOXES.put(value.getKey(), QuadHelper.fullOverlay(value.getKey(), value.getValue(), -OVERLAY_DIST_1)); + OVERLAY_BOXES_1.put(value.getKey(), + QuadHelper.fullOverlay(value.getKey(), value.getValue(), OVERLAY_DIST_1)); + OVERLAY_BOXES_2.put(value.getKey(), + QuadHelper.fullOverlay(value.getKey(), value.getValue(), OVERLAY_DIST_2)); + } + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/quad/ColorData.java b/src/main/java/gregtech/client/renderer/pipe/quad/ColorData.java new file mode 100644 index 00000000000..1862e3122f5 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/quad/ColorData.java @@ -0,0 +1,21 @@ +package gregtech.client.renderer.pipe.quad; + +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import com.github.bsideup.jabel.Desugar; + +import java.util.Arrays; + +@Desugar +@SideOnly(Side.CLIENT) +public record ColorData(int... colorsARGB) { + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + var that = (ColorData) obj; + return Arrays.equals(this.colorsARGB, that.colorsARGB); + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/quad/OverlayLayerDefinition.java b/src/main/java/gregtech/client/renderer/pipe/quad/OverlayLayerDefinition.java new file mode 100644 index 00000000000..130c8f90fae --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/quad/OverlayLayerDefinition.java @@ -0,0 +1,18 @@ +package gregtech.client.renderer.pipe.quad; + +import net.minecraft.util.EnumFacing; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.jetbrains.annotations.Nullable; + +import javax.vecmath.Vector3f; + +@FunctionalInterface +@SideOnly(Side.CLIENT) +public interface OverlayLayerDefinition { + + ImmutablePair computeBox(@Nullable EnumFacing facing, float x1, float y1, float z1, float x2, + float y2, float z2); +} diff --git a/src/main/java/gregtech/client/renderer/pipe/quad/PipeQuadHelper.java b/src/main/java/gregtech/client/renderer/pipe/quad/PipeQuadHelper.java new file mode 100644 index 00000000000..eade467e4c7 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/quad/PipeQuadHelper.java @@ -0,0 +1,151 @@ +package gregtech.client.renderer.pipe.quad; + +import gregtech.client.renderer.pipe.util.SpriteInformation; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + +import java.util.EnumMap; +import java.util.List; + +import javax.vecmath.Vector3f; + +@SideOnly(Side.CLIENT) +public final class PipeQuadHelper { + + private SpriteInformation targetSprite; + + private final List> coreBoxList = new ObjectArrayList<>(); + private final List>> sideBoxesList = new ObjectArrayList<>(); + + private float[] definition; + + public PipeQuadHelper(float x, float y, float z, float small, float large) { + float xS = (x + small) * 16; + float xL = (x + large) * 16; + float yS = (y + small) * 16; + float yL = (y + large) * 16; + float zS = (z + small) * 16; + float zL = (z + large) * 16; + definition = new float[] { xS, xL, yS, yL, zS, zL }; + } + + @Contract("_ -> this") + public PipeQuadHelper initialize(OverlayLayerDefinition... overlayLayers) { + if (definition != null) { + float xS = definition[0]; + float xL = definition[1]; + float yS = definition[2]; + float yL = definition[3]; + float zS = definition[4]; + float zL = definition[5]; + definition = null; + generateBox(xS, xL, yS, yL, zS, zL, + (facing, x1, y1, z1, x2, y2, z2) -> QuadHelper.toPair(x1, y1, z1, x2, y2, z2)); + for (OverlayLayerDefinition definition : overlayLayers) { + generateBox(xS, xL, yS, yL, zS, zL, definition); + } + } + return this; + } + + public int getLayerCount() { + return coreBoxList.size(); + } + + private void generateBox(float xS, float xL, float yS, float yL, float zS, float zL, + @NotNull OverlayLayerDefinition definition) { + coreBoxList.add(definition.computeBox(null, xS, yS, zS, xL, yL, zL)); + EnumMap> sideBoxes = new EnumMap<>(EnumFacing.class); + sideBoxes.put(EnumFacing.DOWN, definition.computeBox(EnumFacing.DOWN, xS, 0, zS, xL, yS, zL)); + sideBoxes.put(EnumFacing.UP, definition.computeBox(EnumFacing.UP, xS, yL, zS, xL, 16, zL)); + sideBoxes.put(EnumFacing.NORTH, definition.computeBox(EnumFacing.NORTH, xS, yS, 0, xL, yL, zS)); + sideBoxes.put(EnumFacing.SOUTH, definition.computeBox(EnumFacing.SOUTH, xS, yS, zL, xL, yL, 16)); + sideBoxes.put(EnumFacing.WEST, definition.computeBox(EnumFacing.WEST, 0, yS, zS, xS, yL, zL)); + sideBoxes.put(EnumFacing.EAST, definition.computeBox(EnumFacing.EAST, xL, yS, zS, 16, yL, zL)); + sideBoxesList.add(sideBoxes); + } + + @Contract("_, _, _, _ -> new") + public static @NotNull PipeQuadHelper create(float thickness, double x, double y, double z) { + float small = 0.5f - thickness / 2; + float large = 0.5f + thickness / 2; + return new PipeQuadHelper((float) x, (float) y, (float) z, small, large); + } + + @Contract("_ -> new") + public static @NotNull PipeQuadHelper create(float thickness) { + return create(thickness, 0, 0, 0); + } + + public void setTargetSprite(SpriteInformation sprite) { + this.targetSprite = sprite; + } + + public @NotNull RecolorableBakedQuad visitCore(EnumFacing facing) { + return visitCore(facing, 0); + } + + public @NotNull RecolorableBakedQuad visitCore(EnumFacing facing, int overlayLayer) { + return visitQuad(facing, coreBoxList.get(overlayLayer), UVMapper.standard(0)); + } + + public @NotNull List visitTube(EnumFacing facing) { + return visitTube(facing, 0); + } + + public @NotNull List visitTube(EnumFacing facing, int overlayLayer) { + List list = new ObjectArrayList<>(); + Pair box = sideBoxesList.get(overlayLayer).get(facing); + switch (facing.getAxis()) { + case X -> { + list.add(visitQuad(EnumFacing.UP, box, UVMapper.standard(0))); + list.add(visitQuad(EnumFacing.DOWN, box, UVMapper.standard(0))); + list.add(visitQuad(EnumFacing.SOUTH, box, UVMapper.standard(0))); + list.add(visitQuad(EnumFacing.NORTH, box, UVMapper.flipped(0))); + } + case Y -> { + list.add(visitQuad(EnumFacing.EAST, box, UVMapper.standard(0))); + list.add(visitQuad(EnumFacing.WEST, box, UVMapper.standard(0))); + list.add(visitQuad(EnumFacing.SOUTH, box, UVMapper.standard(0))); + list.add(visitQuad(EnumFacing.NORTH, box, UVMapper.standard(0))); + } + case Z -> { + list.add(visitQuad(EnumFacing.UP, box, UVMapper.flipped(0))); + list.add(visitQuad(EnumFacing.DOWN, box, UVMapper.standard(0))); + list.add(visitQuad(EnumFacing.EAST, box, UVMapper.flipped(0))); + list.add(visitQuad(EnumFacing.WEST, box, UVMapper.standard(0))); + } + } + return list; + } + + public @NotNull RecolorableBakedQuad visitCapper(EnumFacing facing) { + return visitCapper(facing, 0); + } + + public @NotNull RecolorableBakedQuad visitCapper(EnumFacing facing, int overlayLayer) { + return visitQuad(facing, sideBoxesList.get(overlayLayer).get(facing), UVMapper.standard(0)); + } + + public @NotNull RecolorableBakedQuad visitQuad(EnumFacing normal, Pair box, UVMapper uv) { + return QuadHelper.buildQuad(normal, box, uv, targetSprite); + } + + public static @NotNull List createFrame(TextureAtlasSprite sprite) { + PipeQuadHelper helper = PipeQuadHelper.create(0.998f).initialize(); + helper.setTargetSprite(new SpriteInformation(sprite, 0)); + List list = new ObjectArrayList<>(); + for (EnumFacing facing : EnumFacing.VALUES) { + list.add(helper.visitCore(facing)); + } + return list; + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/quad/QuadHelper.java b/src/main/java/gregtech/client/renderer/pipe/quad/QuadHelper.java new file mode 100644 index 00000000000..f60a2b4b65d --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/quad/QuadHelper.java @@ -0,0 +1,117 @@ +package gregtech.client.renderer.pipe.quad; + +import gregtech.client.model.ModelFactory; +import gregtech.client.renderer.pipe.util.SpriteInformation; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.BlockPartFace; +import net.minecraft.client.renderer.block.model.ModelRotation; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.util.EnumFacing; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Pair; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.vecmath.Vector3f; + +public final class QuadHelper { + + private QuadHelper() {} + + @SideOnly(Side.CLIENT) + public static @NotNull RecolorableBakedQuad buildQuad(EnumFacing normal, Pair box, + @NotNull UVMapper uv, + @NotNull SpriteInformation targetSprite) { + BlockPartFace face = new BlockPartFace(null, -1, targetSprite.sprite().getIconName(), uv.map(normal, box)); + BakedQuad quad = ModelFactory.getBakery().makeBakedQuad(of(box.getLeft()), of(box.getRight()), face, + targetSprite.sprite(), normal, + ModelRotation.X0_Y0, null, false, true); + return new RecolorableBakedQuad(quad, targetSprite); + } + + @SideOnly(Side.CLIENT) + public static @NotNull BakedQuad buildQuad(EnumFacing normal, Pair box, + @NotNull UVMapper uv, @NotNull TextureAtlasSprite targetSprite) { + BlockPartFace face = new BlockPartFace(null, -1, targetSprite.getIconName(), uv.map(normal, box)); + return ModelFactory.getBakery().makeBakedQuad(of(box.getLeft()), of(box.getRight()), face, targetSprite, normal, + ModelRotation.X0_Y0, null, false, true); + } + + @SideOnly(Side.CLIENT) + public static @NotNull org.lwjgl.util.vector.Vector3f of(@NotNull Vector3f vec) { + return new org.lwjgl.util.vector.Vector3f(vec.x, vec.y, vec.z); + } + + @Contract("_ -> new") + public static @NotNull ImmutablePair toPair(@NotNull AxisAlignedBB bb) { + return ImmutablePair.of(new Vector3f((float) bb.minX * 16, (float) bb.minY * 16, (float) bb.minZ * 16), + new Vector3f((float) bb.maxX * 16, (float) bb.maxY * 16, (float) bb.maxZ * 16)); + } + + @Contract("_, _, _, _, _, _ -> new") + public static @NotNull ImmutablePair toPair(float x1, float y1, float z1, float x2, float y2, + float z2) { + return ImmutablePair.of(new Vector3f(x1, y1, z1), new Vector3f(x2, y2, z2)); + } + + @Contract("_, _, _ -> new") + public static @NotNull ImmutablePair capOverlay(@Nullable EnumFacing facing, + @NotNull AxisAlignedBB bb, float g) { + return capOverlay(facing, (float) bb.minX * 16, (float) bb.minY * 16, (float) bb.minZ * 16, + (float) bb.maxX * 16, (float) bb.maxY * 16, + (float) bb.maxZ * 16, g); + } + + @Contract("_, _, _, _, _, _, _, _ -> new") + public static @NotNull ImmutablePair capOverlay(@Nullable EnumFacing facing, float x1, float y1, + float z1, float x2, float y2, float z2, + float g) { + if (facing == null) return toPair(x1 - g, y1 - g, z1 - g, x2 + g, y2 + g, z2 + g); + return switch (facing.getAxis()) { + case X -> toPair(x1 - g, y1, z1, x2 + g, y2, z2); + case Y -> toPair(x1, y1 - g, z1, x2, y2 + g, z2); + case Z -> toPair(x1, y1, z1 - g, x2, y2, z2 + g); + }; + } + + @Contract("_, _, _ -> new") + public static @NotNull ImmutablePair tubeOverlay(@Nullable EnumFacing facing, + @NotNull AxisAlignedBB bb, float g) { + return tubeOverlay(facing, (float) bb.minX * 16, (float) bb.minY * 16, (float) bb.minZ * 16, + (float) bb.maxX * 16, (float) bb.maxY * 16, + (float) bb.maxZ * 16, g); + } + + @Contract("_, _, _, _, _, _, _, _ -> new") + public static @NotNull ImmutablePair tubeOverlay(@Nullable EnumFacing facing, float x1, + float y1, float z1, float x2, float y2, + float z2, float g) { + if (facing == null) return toPair(x1, y1, z1, x2, y2, z2); + return switch (facing.getAxis()) { + case X -> toPair(x1, y1 - g, z1 - g, x2, y2 + g, z2 + g); + case Y -> toPair(x1 - g, y1, z1 - g, x2 + g, y2, z2 + g); + case Z -> toPair(x1 - g, y1 - g, z1, x2 + g, y2 + g, z2); + }; + } + + @Contract("_, _, _ -> new") + public static @NotNull ImmutablePair fullOverlay(@Nullable EnumFacing facing, + @NotNull AxisAlignedBB bb, float g) { + return fullOverlay(facing, (float) bb.minX * 16, (float) bb.minY * 16, (float) bb.minZ * 16, + (float) bb.maxX * 16, (float) bb.maxY * 16, + (float) bb.maxZ * 16, g); + } + + @Contract("_, _, _, _, _, _, _, _ -> new") + public static @NotNull ImmutablePair fullOverlay(@Nullable EnumFacing facing, float x1, + float y1, float z1, float x2, float y2, + float z2, float g) { + return toPair(x1 - g, y1 - g, z1 - g, x2 + g, y2 + g, z2 + g); + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/quad/RecolorableBakedQuad.java b/src/main/java/gregtech/client/renderer/pipe/quad/RecolorableBakedQuad.java new file mode 100644 index 00000000000..b275af86ae4 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/quad/RecolorableBakedQuad.java @@ -0,0 +1,48 @@ +package gregtech.client.renderer.pipe.quad; + +import gregtech.client.renderer.pipe.util.SpriteInformation; + +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; + +@SideOnly(Side.CLIENT) +public class RecolorableBakedQuad extends BakedQuad { + + private final Int2ObjectOpenHashMap cache; + private final SpriteInformation spriteInformation; + + /** + * Create a new recolorable quad based off of a baked quad prototype. + * + * @param prototype the prototype. + * @param spriteInformation the sprite information of this baked quad. + */ + public RecolorableBakedQuad(BakedQuad prototype, SpriteInformation spriteInformation) { + this(prototype, prototype.getTintIndex(), spriteInformation, new Int2ObjectOpenHashMap<>()); + } + + protected RecolorableBakedQuad(BakedQuad prototype, int tintIndex, + SpriteInformation spriteInformation, + Int2ObjectOpenHashMap cache) { + super(prototype.getVertexData(), tintIndex, prototype.getFace(), spriteInformation.sprite(), + prototype.shouldApplyDiffuseLighting(), prototype.getFormat()); + this.spriteInformation = spriteInformation; + this.cache = cache; + } + + /** + * Get a recolorable quad based off of this quad but aligned with the given color data. + * + * @param data the color data. + * @return a quad colored based on the color data. + */ + public RecolorableBakedQuad withColor(ColorData data) { + if (!spriteInformation.colorable()) return this; + int argb = data.colorsARGB()[spriteInformation.colorID()]; + return cache.computeIfAbsent(argb, + (c) -> new RecolorableBakedQuad(this, c, this.spriteInformation, this.cache)); + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/quad/UVMapper.java b/src/main/java/gregtech/client/renderer/pipe/quad/UVMapper.java new file mode 100644 index 00000000000..0d0be943037 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/quad/UVMapper.java @@ -0,0 +1,45 @@ +package gregtech.client.renderer.pipe.quad; + +import net.minecraft.client.renderer.block.model.BlockFaceUV; +import net.minecraft.util.EnumFacing; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap; +import org.apache.commons.lang3.tuple.Pair; + +import javax.vecmath.Vector3f; + +@FunctionalInterface +@SideOnly(Side.CLIENT) +public interface UVMapper { + + Int2ObjectArrayMap STANDARD = new Int2ObjectArrayMap<>(4); + Int2ObjectArrayMap FLIPPED = new Int2ObjectArrayMap<>(4); + + static UVMapper standard(int rot) { + return FLIPPED.computeIfAbsent(rot, (r) -> (normal, box) -> { + Vector3f small = box.getLeft(); + Vector3f large = box.getRight(); + return switch (normal.getAxis()) { + case X -> new BlockFaceUV(new float[] { small.z, 16 - large.y, large.z, 16 - small.y }, r); + case Y -> new BlockFaceUV(new float[] { small.x, 16 - large.z, large.x, 16 - small.z }, r); + case Z -> new BlockFaceUV(new float[] { small.x, 16 - large.y, large.x, 16 - small.y }, r); + }; + }); + } + + static UVMapper flipped(int rot) { + return STANDARD.computeIfAbsent(rot, (r) -> (normal, box) -> { + Vector3f small = box.getLeft(); + Vector3f large = box.getRight(); + return switch (normal.getAxis()) { + case X -> new BlockFaceUV(new float[] { 16 - large.z, small.y, 16 - small.z, large.y }, r); + case Y -> new BlockFaceUV(new float[] { 16 - large.x, small.z, 16 - small.x, large.z }, r); + case Z -> new BlockFaceUV(new float[] { 16 - large.x, small.y, 16 - small.x, large.y }, r); + }; + }); + } + + BlockFaceUV map(EnumFacing normal, Pair box); +} diff --git a/src/main/java/gregtech/client/renderer/pipe/util/ActivableCacheKey.java b/src/main/java/gregtech/client/renderer/pipe/util/ActivableCacheKey.java new file mode 100644 index 00000000000..3091ae3f28c --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/util/ActivableCacheKey.java @@ -0,0 +1,29 @@ +package gregtech.client.renderer.pipe.util; + +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.Nullable; + +@SideOnly(Side.CLIENT) +public class ActivableCacheKey extends CacheKey { + + private final boolean active; + + public ActivableCacheKey(float thickness, boolean active) { + super(thickness); + this.active = active; + } + + public static ActivableCacheKey of(@Nullable Float thickness, @Nullable Boolean active) { + float thick = thickness == null ? 0.5f : thickness; + boolean act = active != null && active; + return new ActivableCacheKey(thick, act); + } + + public boolean isActive() { + return active; + } + + // activeness is merely a way to pass information onwards, it does not result in separate mappings. +} diff --git a/src/main/java/gregtech/client/renderer/pipe/util/CacheKey.java b/src/main/java/gregtech/client/renderer/pipe/util/CacheKey.java new file mode 100644 index 00000000000..76e5667585c --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/util/CacheKey.java @@ -0,0 +1,54 @@ +package gregtech.client.renderer.pipe.util; + +import net.minecraft.util.IStringSerializable; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Objects; + +@SideOnly(Side.CLIENT) +public class CacheKey implements IStringSerializable { + + protected final float thickness; + + private final int hash; + + public CacheKey(float thickness) { + this.thickness = thickness; + this.hash = computeHash(); + } + + public static CacheKey of(@Nullable Float thickness) { + float thick = thickness == null ? 0.5f : thickness; + return new CacheKey(thick); + } + + public float getThickness() { + return thickness; + } + + protected int computeHash() { + return Objects.hash(thickness); + } + + @Override + public boolean equals(Object obj) { + if (obj == this) return true; + if (obj == null || obj.getClass() != this.getClass()) return false; + var that = (CacheKey) obj; + return Float.floatToIntBits(this.thickness) == Float.floatToIntBits(that.thickness); + } + + @Override + public final int hashCode() { + return hash; + } + + @Override + public @NotNull String getName() { + return String.valueOf(Float.floatToIntBits(thickness)); + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/util/MaterialModelOverride.java b/src/main/java/gregtech/client/renderer/pipe/util/MaterialModelOverride.java new file mode 100644 index 00000000000..6b4838856e1 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/util/MaterialModelOverride.java @@ -0,0 +1,28 @@ +package gregtech.client.renderer.pipe.util; + +import gregtech.api.unification.material.Material; +import gregtech.client.renderer.pipe.AbstractPipeModel; + +import com.github.bsideup.jabel.Desugar; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Predicate; + +public interface MaterialModelOverride> { + + @Nullable + T getModel(Material material, int i); + + @Desugar + record StandardOverride> (@NotNull T[] models, + @NotNull Predicate<@Nullable Material> predicate) + implements MaterialModelOverride { + + @Override + public @Nullable T getModel(Material material, int i) { + if (!predicate.test(material)) return null; + else return models[i]; + } + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/util/MaterialModelSupplier.java b/src/main/java/gregtech/client/renderer/pipe/util/MaterialModelSupplier.java new file mode 100644 index 00000000000..d1631a2dfce --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/util/MaterialModelSupplier.java @@ -0,0 +1,14 @@ +package gregtech.client.renderer.pipe.util; + +import gregtech.api.unification.material.Material; +import gregtech.client.renderer.pipe.AbstractPipeModel; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@FunctionalInterface +public interface MaterialModelSupplier { + + @NotNull + AbstractPipeModel getModel(@Nullable Material material); +} diff --git a/src/main/java/gregtech/client/renderer/pipe/util/SpriteInformation.java b/src/main/java/gregtech/client/renderer/pipe/util/SpriteInformation.java new file mode 100644 index 00000000000..ade1fd83d54 --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/util/SpriteInformation.java @@ -0,0 +1,16 @@ +package gregtech.client.renderer.pipe.util; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import com.github.bsideup.jabel.Desugar; + +@SideOnly(Side.CLIENT) +@Desugar +public record SpriteInformation(TextureAtlasSprite sprite, int colorID) { + + public boolean colorable() { + return colorID >= 0; + } +} diff --git a/src/main/java/gregtech/client/renderer/pipe/util/SpriteInformationWrapper.java b/src/main/java/gregtech/client/renderer/pipe/util/SpriteInformationWrapper.java new file mode 100644 index 00000000000..8ea4f1bbccf --- /dev/null +++ b/src/main/java/gregtech/client/renderer/pipe/util/SpriteInformationWrapper.java @@ -0,0 +1,39 @@ +package gregtech.client.renderer.pipe.util; + +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; + +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Supplier; + +@SideOnly(Side.CLIENT) +public class SpriteInformationWrapper implements Supplier, Consumer, + BiConsumer { + + private SpriteInformation sprite; + + @Override + public void accept(TextureAtlasSprite sprite, Integer colorID) { + accept(new SpriteInformation(sprite, colorID)); + } + + @Override + public void accept(SpriteInformation spriteInformation) { + this.sprite = spriteInformation; + } + + @Override + public SpriteInformation get() { + return this.sprite; + } + + public static SpriteInformationWrapper[] array(int size) { + SpriteInformationWrapper[] array = new SpriteInformationWrapper[size]; + for (int i = 0; i < size; i++) { + array[i] = new SpriteInformationWrapper(); + } + return array; + } +} diff --git a/src/main/java/gregtech/client/renderer/texture/Textures.java b/src/main/java/gregtech/client/renderer/texture/Textures.java index 76f91891093..e9814f3956a 100644 --- a/src/main/java/gregtech/client/renderer/texture/Textures.java +++ b/src/main/java/gregtech/client/renderer/texture/Textures.java @@ -7,6 +7,8 @@ import gregtech.client.renderer.CubeRendererState; import gregtech.client.renderer.ICubeRenderer; import gregtech.client.renderer.cclop.UVMirror; +import gregtech.client.renderer.pipe.PipeModelRegistry; +import gregtech.client.renderer.pipe.util.SpriteInformationWrapper; import gregtech.client.renderer.texture.cube.AlignedOrientedOverlayRenderer; import gregtech.client.renderer.texture.cube.LDPipeOverlayRenderer; import gregtech.client.renderer.texture.cube.OrientedOverlayRenderer; @@ -556,81 +558,37 @@ public class Textures { public static final ResourceLocation YELLOW_CAPE_TEXTURE = gregtechId("textures/capes/yellowcape.png"); @SideOnly(Side.CLIENT) - public static TextureAtlasSprite RESTRICTIVE_OVERLAY; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_TINY; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_SMALL; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_NORMAL; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_LARGE; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_HUGE; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_QUADRUPLE; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_NONUPLE; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_SIDE; - - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_SMALL_WOOD; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_NORMAL_WOOD; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_LARGE_WOOD; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_SIDE_WOOD; - - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite OPTICAL_PIPE_IN; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite OPTICAL_PIPE_SIDE; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite OPTICAL_PIPE_SIDE_OVERLAY; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite OPTICAL_PIPE_SIDE_OVERLAY_ACTIVE; - - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite LASER_PIPE_IN; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite LASER_PIPE_SIDE; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite LASER_PIPE_OVERLAY; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite LASER_PIPE_OVERLAY_EMISSIVE; - - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_UP; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_DOWN; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_LEFT; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_RIGHT; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_NU; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_ND; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_NL; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_NR; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_UD; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_UL; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_UR; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_DL; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_DR; - @SideOnly(Side.CLIENT) - public static TextureAtlasSprite PIPE_BLOCKED_OVERLAY_LR; + public static final class PipeTextures { + + public static final SpriteInformationWrapper RESTRICTIVE_OVERLAY = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper PIPE_TINY = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper PIPE_SMALL = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper PIPE_NORMAL = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper PIPE_LARGE = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper PIPE_HUGE = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper PIPE_QUADRUPLE = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper PIPE_NONUPLE = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper PIPE_SIDE = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper PIPE_SMALL_WOOD = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper PIPE_NORMAL_WOOD = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper PIPE_LARGE_WOOD = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper PIPE_SIDE_WOOD = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper OPTICAL_PIPE_IN = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper OPTICAL_PIPE_SIDE = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper OPTICAL_PIPE_SIDE_OVERLAY = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper OPTICAL_PIPE_SIDE_OVERLAY_ACTIVE = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper LASER_PIPE_IN = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper LASER_PIPE_SIDE = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper LASER_PIPE_OVERLAY = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper LASER_PIPE_OVERLAY_EMISSIVE = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper PIPE_BLOCKED_OVERLAY = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper WIRE = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper INSULATION_FULL = new SpriteInformationWrapper(); + public static final SpriteInformationWrapper[] INSULATION = SpriteInformationWrapper + .array(PipeModelRegistry.CABLE_MODEL_COUNT - 1); + + private PipeTextures() {} + } @SideOnly(Side.CLIENT) public static ThreadLocal RENDER_STATE; @@ -652,53 +610,49 @@ public static void register(TextureMap textureMap) { registrar.registerIcons(textureMap); } - RESTRICTIVE_OVERLAY = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_restrictive")); - PIPE_TINY = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_tiny_in")); - PIPE_SMALL = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_small_in")); - PIPE_NORMAL = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_normal_in")); - PIPE_LARGE = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_large_in")); - PIPE_HUGE = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_huge_in")); - PIPE_QUADRUPLE = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_quadruple_in")); - PIPE_NONUPLE = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_nonuple_in")); - PIPE_SIDE = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_side")); - PIPE_SMALL_WOOD = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_small_in_wood")); - PIPE_NORMAL_WOOD = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_normal_in_wood")); - PIPE_LARGE_WOOD = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_large_in_wood")); - PIPE_SIDE_WOOD = textureMap.registerSprite(gregtechId("blocks/pipe/pipe_side_wood")); - - // Fluid Pipe Blocked overlay textures - PIPE_BLOCKED_OVERLAY = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked")); - PIPE_BLOCKED_OVERLAY_UP = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_up")); - PIPE_BLOCKED_OVERLAY_DOWN = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_down")); - PIPE_BLOCKED_OVERLAY_LEFT = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_left")); - PIPE_BLOCKED_OVERLAY_RIGHT = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_right")); - PIPE_BLOCKED_OVERLAY_NU = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_nu")); - PIPE_BLOCKED_OVERLAY_ND = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_nd")); - PIPE_BLOCKED_OVERLAY_NL = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_nl")); - PIPE_BLOCKED_OVERLAY_NR = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_nr")); - PIPE_BLOCKED_OVERLAY_UD = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_ud")); - PIPE_BLOCKED_OVERLAY_UL = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_ul")); - PIPE_BLOCKED_OVERLAY_UR = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_ur")); - PIPE_BLOCKED_OVERLAY_DL = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_dl")); - PIPE_BLOCKED_OVERLAY_DR = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_dr")); - PIPE_BLOCKED_OVERLAY_LR = textureMap.registerSprite(gregtechId("blocks/pipe/blocked/pipe_blocked_lr")); - - OPTICAL_PIPE_IN = textureMap - .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_optical_in")); - OPTICAL_PIPE_SIDE = textureMap - .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_optical_side")); - OPTICAL_PIPE_SIDE_OVERLAY = textureMap - .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_optical_side_overlay")); - OPTICAL_PIPE_SIDE_OVERLAY_ACTIVE = textureMap - .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_optical_side_overlay_active")); - - LASER_PIPE_SIDE = textureMap - .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_laser_side")); - LASER_PIPE_IN = textureMap.registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_laser_in")); - LASER_PIPE_OVERLAY = textureMap - .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_laser_side_overlay")); - LASER_PIPE_OVERLAY_EMISSIVE = textureMap - .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_laser_side_overlay_emissive")); + PipeTextures.WIRE.accept(textureMap.registerSprite(gregtechId("blocks/cable/wire")), 0); + PipeTextures.INSULATION_FULL.accept(textureMap.registerSprite(gregtechId("blocks/cable/insulation_full")), 1); + for (int i = 0; i < PipeTextures.INSULATION.length; i++) { + PipeTextures.INSULATION[i].accept(textureMap.registerSprite(gregtechId("blocks/cable/insulation_" + i)), 1); + } + + PipeTextures.PIPE_BLOCKED_OVERLAY.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_blocked")), -1); + PipeTextures.RESTRICTIVE_OVERLAY.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_restrictive")), + -1); + + PipeTextures.PIPE_TINY.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_tiny_in")), 0); + PipeTextures.PIPE_SMALL.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_small_in")), 0); + PipeTextures.PIPE_NORMAL.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_normal_in")), 0); + PipeTextures.PIPE_LARGE.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_large_in")), 0); + PipeTextures.PIPE_HUGE.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_huge_in")), 0); + PipeTextures.PIPE_QUADRUPLE.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_quadruple_in")), 0); + PipeTextures.PIPE_NONUPLE.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_nonuple_in")), 0); + PipeTextures.PIPE_SIDE.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_side")), 0); + PipeTextures.PIPE_SMALL_WOOD.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_small_in_wood")), 0); + PipeTextures.PIPE_NORMAL_WOOD.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_normal_in_wood")), + 0); + PipeTextures.PIPE_LARGE_WOOD.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_large_in_wood")), 0); + PipeTextures.PIPE_SIDE_WOOD.accept(textureMap.registerSprite(gregtechId("blocks/pipe/pipe_side_wood")), 0); + + PipeTextures.OPTICAL_PIPE_IN.accept(textureMap + .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_optical_in")), -1); + PipeTextures.OPTICAL_PIPE_SIDE.accept(textureMap + .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_optical_side")), -1); + PipeTextures.OPTICAL_PIPE_SIDE_OVERLAY.accept(textureMap + .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_optical_side_overlay")), 0); + PipeTextures.OPTICAL_PIPE_SIDE_OVERLAY_ACTIVE.accept(textureMap + .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_optical_side_overlay_active")), + 0); + + PipeTextures.LASER_PIPE_IN.accept( + textureMap.registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_laser_in")), -1); + PipeTextures.LASER_PIPE_SIDE.accept(textureMap + .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_laser_side")), -1); + PipeTextures.LASER_PIPE_OVERLAY.accept(textureMap + .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_laser_side_overlay")), 0); + PipeTextures.LASER_PIPE_OVERLAY_EMISSIVE.accept(textureMap + .registerSprite(new ResourceLocation(GTValues.MODID, "blocks/pipe/pipe_laser_side_overlay_emissive")), + 0); for (MaterialIconSet iconSet : MaterialIconSet.ICON_SETS.values()) { textureMap.registerSprite(MaterialIconType.frameGt.getBlockTexturePath(iconSet)); diff --git a/src/main/java/gregtech/client/renderer/texture/cube/SimpleOverlayRenderer.java b/src/main/java/gregtech/client/renderer/texture/cube/SimpleOverlayRenderer.java index 768933b0da9..bfcaad3fb0b 100644 --- a/src/main/java/gregtech/client/renderer/texture/cube/SimpleOverlayRenderer.java +++ b/src/main/java/gregtech/client/renderer/texture/cube/SimpleOverlayRenderer.java @@ -79,4 +79,12 @@ public void renderOrientedState(CCRenderState renderState, Matrix4 translation, public TextureAtlasSprite getParticleSprite() { return sprite; } + + public TextureAtlasSprite getSprite() { + return sprite; + } + + public @Nullable TextureAtlasSprite getSpriteEmissive() { + return spriteEmissive; + } } diff --git a/src/main/java/gregtech/common/blocks/BlockFrame.java b/src/main/java/gregtech/common/blocks/BlockFrame.java index 88bbf3c2374..80cea547d04 100644 --- a/src/main/java/gregtech/common/blocks/BlockFrame.java +++ b/src/main/java/gregtech/common/blocks/BlockFrame.java @@ -124,7 +124,7 @@ public boolean canCreatureSpawn(@NotNull IBlockState state, @NotNull IBlockAcces public boolean replaceWithFramedPipe(World worldIn, BlockPos pos, IBlockState state, EntityPlayer playerIn, ItemStack stackInHand, EnumFacing facing) { BlockPipe blockPipe = (BlockPipe) ((ItemBlockPipe) stackInHand.getItem()).getBlock(); - if (blockPipe.getItemPipeType(stackInHand).getThickness() < 1) { + if (blockPipe.getPipeType().getThickness() < 1) { ItemBlock itemBlock = (ItemBlock) stackInHand.getItem(); IBlockState pipeState = blockPipe.getDefaultState(); // these 0 values are not actually used by forge diff --git a/src/main/java/gregtech/common/blocks/MetaBlocks.java b/src/main/java/gregtech/common/blocks/MetaBlocks.java index 56c10a73c3f..f857ddefd91 100644 --- a/src/main/java/gregtech/common/blocks/MetaBlocks.java +++ b/src/main/java/gregtech/common/blocks/MetaBlocks.java @@ -6,6 +6,7 @@ import gregtech.api.block.machines.BlockMachine; import gregtech.api.metatileentity.MetaTileEntityHolder; import gregtech.api.metatileentity.registry.MTERegistry; +import gregtech.api.pipenet.block.material.BlockMaterialPipe; import gregtech.api.pipenet.longdist.BlockLongDistancePipe; import gregtech.api.unification.OreDictUnifier; import gregtech.api.unification.material.Material; @@ -21,11 +22,6 @@ import gregtech.client.model.modelfactories.BakedModelHandler; import gregtech.client.renderer.handler.MetaTileEntityRenderer; import gregtech.client.renderer.handler.MetaTileEntityTESR; -import gregtech.client.renderer.pipe.CableRenderer; -import gregtech.client.renderer.pipe.FluidPipeRenderer; -import gregtech.client.renderer.pipe.ItemPipeRenderer; -import gregtech.client.renderer.pipe.LaserPipeRenderer; -import gregtech.client.renderer.pipe.OpticalPipeRenderer; import gregtech.common.ConfigHolder; import gregtech.common.blocks.explosive.BlockITNT; import gregtech.common.blocks.explosive.BlockPowderbarrel; @@ -74,15 +70,19 @@ import net.minecraft.block.properties.IProperty; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.ModelBakery; import net.minecraft.client.renderer.block.model.ModelResourceLocation; import net.minecraft.client.renderer.block.statemap.IStateMapper; import net.minecraft.client.renderer.block.statemap.StateMapperBase; import net.minecraft.client.renderer.color.BlockColors; +import net.minecraft.client.renderer.color.IBlockColor; +import net.minecraft.client.renderer.color.IItemColor; import net.minecraft.client.renderer.color.ItemColors; import net.minecraft.init.Blocks; import net.minecraft.item.EnumDyeColor; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.model.ModelLoader; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fluids.BlockFluidBase; @@ -447,17 +447,36 @@ public static void registerItemModels() { stack -> MetaTileEntityRenderer.MODEL_LOCATION); } + // prevent the loader from trying to locate the model files as only the IBakedModels exist, and + // they are created during runtime. + ResourceLocation decoy = new ResourceLocation("minecraft:builtin/generated"); for (MaterialRegistry registry : GregTechAPI.materialManager.getRegistries()) { - for (BlockCable cable : CABLES.get(registry.getModid())) cable.onModelRegister(); - for (BlockFluidPipe pipe : FLUID_PIPES.get(registry.getModid())) pipe.onModelRegister(); - for (BlockItemPipe pipe : ITEM_PIPES.get(registry.getModid())) pipe.onModelRegister(); + for (BlockCable cable : CABLES.get(registry.getModid())) { + Item item = Item.getItemFromBlock(cable); + ModelLoader.setCustomMeshDefinition(item, stack -> cable.getPipeType().getModel().getLoc()); + ModelBakery.registerItemVariants(item, decoy); + } + for (BlockFluidPipe pipe : FLUID_PIPES.get(registry.getModid())) { + Item item = Item.getItemFromBlock(pipe); + ModelLoader.setCustomMeshDefinition(item, stack -> pipe.getPipeType().getModel().getLoc()); + ModelBakery.registerItemVariants(item, decoy); + } + for (BlockItemPipe pipe : ITEM_PIPES.get(registry.getModid())) { + Item item = Item.getItemFromBlock(pipe); + ModelLoader.setCustomMeshDefinition(item, stack -> pipe.getPipeType().getModel().getLoc()); + ModelBakery.registerItemVariants(item, decoy); + } + } + for (BlockOpticalPipe pipe : OPTICAL_PIPES) { + Item item = Item.getItemFromBlock(pipe); + ModelLoader.setCustomMeshDefinition(item, stack -> pipe.getPipeType().getModel().getLoc()); + ModelBakery.registerItemVariants(item, decoy); + } + for (BlockLaserPipe pipe : LASER_PIPES) { + Item item = Item.getItemFromBlock(pipe); + ModelLoader.setCustomMeshDefinition(item, stack -> pipe.getPipeType().getModel().getLoc()); + ModelBakery.registerItemVariants(item, decoy); } - for (BlockOpticalPipe pipe : OPTICAL_PIPES) - ModelLoader.setCustomMeshDefinition(Item.getItemFromBlock(pipe), - stack -> OpticalPipeRenderer.INSTANCE.getModelLocation()); - for (BlockLaserPipe pipe : LASER_PIPES) - ModelLoader.setCustomMeshDefinition(Item.getItemFromBlock(pipe), - stack -> LaserPipeRenderer.INSTANCE.getModelLocation()); registerItemModel(BOILER_CASING); registerItemModel(METAL_CASING); @@ -555,30 +574,26 @@ public static void registerStateMappers() { new SimpleStateMapper(MetaTileEntityRenderer.MODEL_LOCATION)); } - IStateMapper normalStateMapper; for (MaterialRegistry registry : GregTechAPI.materialManager.getRegistries()) { - normalStateMapper = new SimpleStateMapper(CableRenderer.INSTANCE.getModelLocation()); for (BlockCable cable : CABLES.get(registry.getModid())) { - ModelLoader.setCustomStateMapper(cable, normalStateMapper); + ModelLoader.setCustomStateMapper(cable, + new SimpleStateMapper(cable.getPipeType().getModel().getLoc())); } - normalStateMapper = new SimpleStateMapper(FluidPipeRenderer.INSTANCE.getModelLocation()); for (BlockFluidPipe pipe : FLUID_PIPES.get(registry.getModid())) { - ModelLoader.setCustomStateMapper(pipe, normalStateMapper); + ModelLoader.setCustomStateMapper(pipe, new SimpleStateMapper(pipe.getPipeType().getModel().getLoc())); } - normalStateMapper = new SimpleStateMapper(ItemPipeRenderer.INSTANCE.getModelLocation()); for (BlockItemPipe pipe : ITEM_PIPES.get(registry.getModid())) { - ModelLoader.setCustomStateMapper(pipe, normalStateMapper); + ModelLoader.setCustomStateMapper(pipe, new SimpleStateMapper(pipe.getPipeType().getModel().getLoc())); } } - normalStateMapper = new SimpleStateMapper(OpticalPipeRenderer.INSTANCE.getModelLocation()); for (BlockOpticalPipe pipe : OPTICAL_PIPES) { - ModelLoader.setCustomStateMapper(pipe, normalStateMapper); + ModelLoader.setCustomStateMapper(pipe, new SimpleStateMapper(pipe.getPipeType().getModel().getLoc())); } - normalStateMapper = new SimpleStateMapper(LaserPipeRenderer.INSTANCE.getModelLocation()); for (BlockLaserPipe pipe : LASER_PIPES) { - ModelLoader.setCustomStateMapper(pipe, normalStateMapper); + ModelLoader.setCustomStateMapper(pipe, new SimpleStateMapper(pipe.getPipeType().getModel().getLoc())); } + IStateMapper normalStateMapper; normalStateMapper = new SimpleStateMapper(BlockSurfaceRock.MODEL_LOCATION); for (BlockSurfaceRock surfaceRock : SURFACE_ROCK_BLOCKS) { ModelLoader.setCustomStateMapper(surfaceRock, normalStateMapper); @@ -624,6 +639,25 @@ public static void registerColors() { itemColors.registerItemColorHandler((s, i) -> block.getGtMaterial(s).getMaterialRGB(), block); } + IBlockColor pipeBlockColor = (s, w, p, i) -> i; + IItemColor pipeItemColor = (s, i) -> i; + for (MaterialRegistry registry : GregTechAPI.materialManager.getRegistries()) { + BlockMaterialPipe[] itemPipes = ITEM_PIPES.get(registry.getModid()); + BlockMaterialPipe[] fluidPipes = FLUID_PIPES.get(registry.getModid()); + blockColors.registerBlockColorHandler(pipeBlockColor, itemPipes); + blockColors.registerBlockColorHandler(pipeBlockColor, fluidPipes); + itemColors.registerItemColorHandler(pipeItemColor, itemPipes); + itemColors.registerItemColorHandler(pipeItemColor, fluidPipes); + + BlockCable[] cables = CABLES.get(registry.getModid()); + blockColors.registerBlockColorHandler(pipeBlockColor, cables); + itemColors.registerItemColorHandler(pipeItemColor, cables); + } + blockColors.registerBlockColorHandler(pipeBlockColor, OPTICAL_PIPES); + itemColors.registerItemColorHandler(pipeItemColor, OPTICAL_PIPES); + blockColors.registerBlockColorHandler(pipeBlockColor, LASER_PIPES); + itemColors.registerItemColorHandler(pipeItemColor, LASER_PIPES); + for (BlockFrame block : FRAME_BLOCKS) { blockColors.registerBlockColorHandler((s, w, p, i) -> block.getGtMaterial(s).getMaterialRGB(), block); itemColors.registerItemColorHandler((s, i) -> block.getGtMaterial(s).getMaterialRGB(), block); diff --git a/src/main/java/gregtech/common/covers/CoverConveyor.java b/src/main/java/gregtech/common/covers/CoverConveyor.java index 7cdd1b9f85b..0e353f1f075 100644 --- a/src/main/java/gregtech/common/covers/CoverConveyor.java +++ b/src/main/java/gregtech/common/covers/CoverConveyor.java @@ -12,6 +12,8 @@ import gregtech.api.mui.GTGuis; import gregtech.api.util.GTTransferUtils; import gregtech.api.util.ItemStackHashStrategy; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; import gregtech.common.covers.filter.ItemFilterContainer; @@ -62,6 +64,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap; import it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collections; import java.util.Map; @@ -80,6 +83,8 @@ public class CoverConveyor extends CoverBase implements CoverWithUI, ITickable, private CoverableItemHandlerWrapper itemHandlerWrapper; protected boolean isWorkingAllowed = true; + protected @Nullable CoverRenderer rendererInverted; + public CoverConveyor(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, @NotNull EnumFacing attachedSide, int tier, int itemsPerSecond) { super(definition, coverableView, attachedSide); @@ -677,6 +682,26 @@ public void readFromNBT(@NotNull NBTTagCompound tagCompound) { } } + @Override + public @NotNull CoverRenderer getRenderer() { + if (conveyorMode == ConveyorMode.EXPORT) { + if (renderer == null) renderer = buildRenderer(); + return renderer; + } else { + if (rendererInverted == null) rendererInverted = buildRendererInverted(); + return rendererInverted; + } + } + + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.CONVEYOR_OVERLAY).setPlateQuads(tier).build(); + } + + protected CoverRenderer buildRendererInverted() { + return new CoverRendererBuilder(Textures.CONVEYOR_OVERLAY_INVERTED).setPlateQuads(tier).build(); + } + @Override @SideOnly(Side.CLIENT) protected @NotNull TextureAtlasSprite getPlateSprite() { diff --git a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java index 793e0eb50a3..a7b7f2d0065 100644 --- a/src/main/java/gregtech/common/covers/CoverDigitalInterface.java +++ b/src/main/java/gregtech/common/covers/CoverDigitalInterface.java @@ -16,6 +16,7 @@ import gregtech.api.mui.GTGuis; import gregtech.api.util.GTLog; import gregtech.api.util.TextFormattingUtil; +import gregtech.client.renderer.pipe.cover.CoverRenderer; import gregtech.client.renderer.texture.Textures; import gregtech.client.utils.RenderUtil; import gregtech.common.gui.widget.prospector.widget.WidgetOreList; @@ -1018,6 +1019,16 @@ public void renderCover(CCRenderState ccRenderState, Matrix4 translation, IVerte } } + @Override + public @NotNull CoverRenderer getRenderer() { + return (quads, facing, renderPlate, renderBackside, renderLayer, data) -> {}; + } + + @Override + protected CoverRenderer buildRenderer() { + return null; + } + @SideOnly(Side.CLIENT) @Override public void renderMetaTileEntityFast(CCRenderState renderState, Matrix4 translation, float partialTicks) {} diff --git a/src/main/java/gregtech/common/covers/CoverFacade.java b/src/main/java/gregtech/common/covers/CoverFacade.java index 9f458f8cec2..3f724be2eeb 100644 --- a/src/main/java/gregtech/common/covers/CoverFacade.java +++ b/src/main/java/gregtech/common/covers/CoverFacade.java @@ -7,6 +7,7 @@ import gregtech.api.cover.IFacadeCover; import gregtech.api.util.GTLog; import gregtech.client.renderer.handler.FacadeRenderer; +import gregtech.client.renderer.pipe.cover.CoverRenderer; import gregtech.common.covers.facade.FacadeHelper; import gregtech.common.items.behaviors.FacadeItem; @@ -22,6 +23,8 @@ import net.minecraft.util.EnumFacing; import net.minecraftforge.client.ForgeHooksClient; import net.minecraftforge.client.MinecraftForgeClient; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.pipeline.IVertexOperation; @@ -72,6 +75,12 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra ForgeHooksClient.setRenderLayer(oldLayer); } + @Override + @SideOnly(Side.CLIENT) + protected CoverRenderer buildRenderer() { + return FacadeRenderer.createRenderer(getWorld(), getPos(), facadeState); + } + @Override public boolean canRenderInLayer(@NotNull BlockRenderLayer renderLayer) { return true; diff --git a/src/main/java/gregtech/common/covers/CoverFluidFilter.java b/src/main/java/gregtech/common/covers/CoverFluidFilter.java index c0d9ff4c375..8b95ad07106 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidFilter.java +++ b/src/main/java/gregtech/common/covers/CoverFluidFilter.java @@ -8,6 +8,8 @@ import gregtech.api.mui.GTGuiTextures; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; import gregtech.common.covers.filter.BaseFilter; import gregtech.common.covers.filter.BaseFilterContainer; @@ -186,6 +188,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra this.texture.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(this.texture).build(); + } + @Override public T getCapability(@NotNull Capability capability, @Nullable T defaultValue) { if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { diff --git a/src/main/java/gregtech/common/covers/CoverFluidVoiding.java b/src/main/java/gregtech/common/covers/CoverFluidVoiding.java index b39ca770bf2..bace7085524 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidVoiding.java +++ b/src/main/java/gregtech/common/covers/CoverFluidVoiding.java @@ -4,6 +4,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; import gregtech.api.util.GTTransferUtils; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import gregtech.common.covers.filter.FluidFilterContainer; @@ -70,6 +72,17 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.FLUID_VOIDING.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + public @NotNull CoverRenderer getRenderer() { + if (renderer == null) renderer = buildRenderer(); + return renderer; + } + + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.FLUID_VOIDING).build(); + } + @Override public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { return super.buildUI(guiData, guiSyncManager, settings).height(192 - 22); diff --git a/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java b/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java index b8be41ff6d3..750fae22a85 100644 --- a/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java +++ b/src/main/java/gregtech/common/covers/CoverFluidVoidingAdvanced.java @@ -4,6 +4,8 @@ import gregtech.api.cover.CoverableView; import gregtech.api.mui.GTGuiTextures; import gregtech.api.util.GTTransferUtils; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import net.minecraft.nbt.NBTTagCompound; @@ -149,6 +151,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.FLUID_VOIDING_ADVANCED.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.FLUID_VOIDING_ADVANCED).build(); + } + @Override public void readInitialSyncData(@NotNull PacketBuffer packetBuffer) { super.readInitialSyncData(packetBuffer); diff --git a/src/main/java/gregtech/common/covers/CoverInfiniteWater.java b/src/main/java/gregtech/common/covers/CoverInfiniteWater.java index 808308ecabb..8966e361ecb 100644 --- a/src/main/java/gregtech/common/covers/CoverInfiniteWater.java +++ b/src/main/java/gregtech/common/covers/CoverInfiniteWater.java @@ -3,6 +3,8 @@ import gregtech.api.cover.CoverBase; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import net.minecraft.util.BlockRenderLayer; @@ -38,6 +40,11 @@ public void renderCover(@NotNull CCRenderState ccRenderState, @NotNull Matrix4 m Textures.INFINITE_WATER.renderSided(getAttachedSide(), cuboid6, ccRenderState, iVertexOperations, matrix4); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.INFINITE_WATER).build(); + } + @Override public void update() { if (!getWorld().isRemote && getOffsetTimer() % 20 == 0) { diff --git a/src/main/java/gregtech/common/covers/CoverItemFilter.java b/src/main/java/gregtech/common/covers/CoverItemFilter.java index b64c75a5ee1..88acab3a555 100644 --- a/src/main/java/gregtech/common/covers/CoverItemFilter.java +++ b/src/main/java/gregtech/common/covers/CoverItemFilter.java @@ -8,6 +8,8 @@ import gregtech.api.mui.GTGuiTextures; import gregtech.api.util.GTLog; import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.cube.SimpleOverlayRenderer; import gregtech.common.covers.filter.BaseFilter; import gregtech.common.covers.filter.BaseFilterContainer; @@ -188,6 +190,11 @@ public void renderCover(CCRenderState renderState, Matrix4 translation, IVertexO this.texture.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(this.texture).build(); + } + @Override public void writeToNBT(@NotNull NBTTagCompound tagCompound) { super.writeToNBT(tagCompound); diff --git a/src/main/java/gregtech/common/covers/CoverItemVoiding.java b/src/main/java/gregtech/common/covers/CoverItemVoiding.java index a69c9da98f8..2984c78fd22 100644 --- a/src/main/java/gregtech/common/covers/CoverItemVoiding.java +++ b/src/main/java/gregtech/common/covers/CoverItemVoiding.java @@ -3,6 +3,8 @@ import gregtech.api.capability.GregtechTileCapabilities; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import net.minecraft.entity.player.EntityPlayer; @@ -112,6 +114,17 @@ public void renderCover(CCRenderState renderState, Matrix4 translation, IVertexO Textures.ITEM_VOIDING.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + public @NotNull CoverRenderer getRenderer() { + if (renderer == null) renderer = buildRenderer(); + return renderer; + } + + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.ITEM_VOIDING).build(); + } + @Override public @NotNull EnumActionResult onSoftMalletClick(@NotNull EntityPlayer playerIn, @NotNull EnumHand hand, @NotNull CuboidRayTraceResult hitResult) { diff --git a/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java b/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java index d66e93c1a69..8b4c37e2911 100644 --- a/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java +++ b/src/main/java/gregtech/common/covers/CoverItemVoidingAdvanced.java @@ -3,6 +3,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; import gregtech.api.mui.GTGuiTextures; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import net.minecraft.item.ItemStack; @@ -132,6 +134,11 @@ public void renderCover(CCRenderState renderState, Matrix4 translation, IVertexO Textures.ITEM_VOIDING_ADVANCED.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.ITEM_VOIDING_ADVANCED).build(); + } + public void setVoidingMode(VoidingMode voidingMode) { this.voidingMode = voidingMode; this.itemFilterContainer.setMaxTransferSize(getMaxStackSize()); diff --git a/src/main/java/gregtech/common/covers/CoverMachineController.java b/src/main/java/gregtech/common/covers/CoverMachineController.java index 8f076c37319..ef5ce27705f 100644 --- a/src/main/java/gregtech/common/covers/CoverMachineController.java +++ b/src/main/java/gregtech/common/covers/CoverMachineController.java @@ -5,6 +5,8 @@ import gregtech.api.cover.*; import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import net.minecraft.entity.player.EntityPlayer; @@ -230,6 +232,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.MACHINE_CONTROLLER_OVERLAY).build(); + } + @Override public boolean canConnectRedstone() { return true; diff --git a/src/main/java/gregtech/common/covers/CoverPump.java b/src/main/java/gregtech/common/covers/CoverPump.java index c595a56774a..52621418448 100644 --- a/src/main/java/gregtech/common/covers/CoverPump.java +++ b/src/main/java/gregtech/common/covers/CoverPump.java @@ -11,6 +11,8 @@ import gregtech.api.mui.GTGuiTextures; import gregtech.api.mui.GTGuis; import gregtech.api.util.GTTransferUtils; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; import gregtech.common.covers.filter.FluidFilterContainer; @@ -71,6 +73,8 @@ public class CoverPump extends CoverBase implements CoverWithUI, ITickable, ICon protected FluidFilterContainer fluidFilterContainer; protected BucketMode bucketMode = BucketMode.MILLI_BUCKET; + protected @Nullable CoverRenderer rendererInverted; + public CoverPump(@NotNull CoverDefinition definition, @NotNull CoverableView coverableView, @NotNull EnumFacing attachedSide, int tier, int mbPerTick) { super(definition, coverableView, attachedSide); @@ -338,6 +342,26 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra } } + @Override + public @NotNull CoverRenderer getRenderer() { + if (pumpMode == PumpMode.EXPORT) { + if (renderer == null) renderer = buildRenderer(); + return renderer; + } else { + if (rendererInverted == null) rendererInverted = buildRendererInverted(); + return rendererInverted; + } + } + + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.PUMP_OVERLAY).setPlateQuads(tier).build(); + } + + protected CoverRenderer buildRendererInverted() { + return new CoverRendererBuilder(Textures.PUMP_OVERLAY_INVERTED).setPlateQuads(tier).build(); + } + @Override public T getCapability(@NotNull Capability capability, T defaultValue) { if (capability == CapabilityFluidHandler.FLUID_HANDLER_CAPABILITY) { diff --git a/src/main/java/gregtech/common/covers/CoverRoboticArm.java b/src/main/java/gregtech/common/covers/CoverRoboticArm.java index 159453207e7..ac2e0235607 100644 --- a/src/main/java/gregtech/common/covers/CoverRoboticArm.java +++ b/src/main/java/gregtech/common/covers/CoverRoboticArm.java @@ -4,6 +4,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; import gregtech.api.mui.GTGuiTextures; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import gregtech.common.covers.filter.SmartItemFilter; import gregtech.common.pipelike.itempipe.net.ItemNetHandler; @@ -56,6 +58,16 @@ public void renderCover(CCRenderState renderState, Matrix4 translation, IVertexO } } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.ARM_OVERLAY).setPlateQuads(tier).build(); + } + + @Override + protected CoverRenderer buildRendererInverted() { + return new CoverRendererBuilder(Textures.ARM_OVERLAY_INVERTED).setPlateQuads(tier).build(); + } + @Override protected int doTransferItems(IItemHandler itemHandler, IItemHandler myItemHandler, int maxTransferAmount) { if (conveyorMode == ConveyorMode.EXPORT && itemHandler instanceof ItemNetHandler && diff --git a/src/main/java/gregtech/common/covers/CoverScreen.java b/src/main/java/gregtech/common/covers/CoverScreen.java index 723741b006f..06ffa48143d 100644 --- a/src/main/java/gregtech/common/covers/CoverScreen.java +++ b/src/main/java/gregtech/common/covers/CoverScreen.java @@ -3,6 +3,8 @@ import gregtech.api.cover.CoverBase; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import net.minecraft.util.BlockRenderLayer; @@ -32,6 +34,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.DISPLAY.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.DISPLAY).build(); + } + @Override public boolean shouldAutoConnectToPipes() { return false; diff --git a/src/main/java/gregtech/common/covers/CoverShutter.java b/src/main/java/gregtech/common/covers/CoverShutter.java index 2a279b65cff..b7be80ccb61 100644 --- a/src/main/java/gregtech/common/covers/CoverShutter.java +++ b/src/main/java/gregtech/common/covers/CoverShutter.java @@ -5,6 +5,8 @@ import gregtech.api.cover.CoverBase; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import net.minecraft.entity.player.EntityPlayer; @@ -38,6 +40,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.SHUTTER.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.SHUTTER).build(); + } + @Override public boolean canAttach(@NotNull CoverableView coverable, @NotNull EnumFacing side) { return true; @@ -76,7 +83,7 @@ public boolean canPipePassThrough() { @Override public @NotNull EnumActionResult onSoftMalletClick(@NotNull EntityPlayer playerIn, @NotNull EnumHand hand, @NotNull CuboidRayTraceResult hitResult) { - this.isWorkingAllowed = !this.isWorkingAllowed; + setWorkingEnabled(!this.isWorkingAllowed); if (!playerIn.world.isRemote) { playerIn.sendMessage(new TextComponentTranslation(isWorkingEnabled() ? "cover.shutter.message.enabled" : "cover.shutter.message.disabled")); @@ -91,7 +98,10 @@ public boolean isWorkingEnabled() { @Override public void setWorkingEnabled(boolean isActivationAllowed) { - isWorkingAllowed = isActivationAllowed; + if (isActivationAllowed != isWorkingAllowed) { + isWorkingAllowed = isActivationAllowed; + markDirty(); + } } @Override diff --git a/src/main/java/gregtech/common/covers/CoverSolarPanel.java b/src/main/java/gregtech/common/covers/CoverSolarPanel.java index e972ef560ad..419212d89cc 100644 --- a/src/main/java/gregtech/common/covers/CoverSolarPanel.java +++ b/src/main/java/gregtech/common/covers/CoverSolarPanel.java @@ -6,6 +6,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; import gregtech.api.util.GTUtility; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import gregtech.client.renderer.texture.cube.SimpleSidedCubeRenderer; @@ -45,6 +47,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.SOLAR_PANEL.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.SOLAR_PANEL).build(); + } + @Override public void update() { CoverableView coverable = getCoverableView(); diff --git a/src/main/java/gregtech/common/covers/CoverStorage.java b/src/main/java/gregtech/common/covers/CoverStorage.java index 24dc4ac49d1..5a40bd475df 100644 --- a/src/main/java/gregtech/common/covers/CoverStorage.java +++ b/src/main/java/gregtech/common/covers/CoverStorage.java @@ -5,6 +5,8 @@ import gregtech.api.cover.CoverWithUI; import gregtech.api.cover.CoverableView; import gregtech.api.mui.GTGuis; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import net.minecraft.entity.player.EntityPlayer; @@ -58,6 +60,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.STORAGE.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.STORAGE).build(); + } + @Override public void onRemoval() { dropInventoryContents(storageHandler); diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorActivity.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorActivity.java index f4f6eb25a7b..001ffadc33d 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorActivity.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorActivity.java @@ -4,6 +4,8 @@ import gregtech.api.capability.IWorkable; import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import net.minecraft.util.BlockRenderLayer; @@ -34,6 +36,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.DETECTOR_ACTIVITY.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.DETECTOR_ACTIVITY).build(); + } + @Override public void update() { if (getOffsetTimer() % 20 != 0) return; diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorActivityAdvanced.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorActivityAdvanced.java index cd13c60c0c6..84b738c9515 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorActivityAdvanced.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorActivityAdvanced.java @@ -5,6 +5,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; import gregtech.api.util.RedstoneUtil; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import net.minecraft.util.BlockRenderLayer; @@ -30,6 +32,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.DETECTOR_ACTIVITY_ADVANCED).build(); + } + @Override public void update() { if (getOffsetTimer() % 20 != 0) return; diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergy.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergy.java index 286902aad32..72504900e6d 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergy.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergy.java @@ -5,6 +5,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; import gregtech.api.util.RedstoneUtil; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import gregtech.common.metatileentities.multi.electric.MetaTileEntityPowerSubstation; import gregtech.common.metatileentities.storage.MetaTileEntityCreativeEnergy; @@ -62,6 +64,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.DETECTOR_ENERGY.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.DETECTOR_ENERGY).build(); + } + @Override public void update() { if (getOffsetTimer() % 20 != 0) return; diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergyAdvanced.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergyAdvanced.java index d100e97289b..94bd4a518a4 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergyAdvanced.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorEnergyAdvanced.java @@ -5,6 +5,8 @@ import gregtech.api.cover.CoverableView; import gregtech.api.mui.GTGuis; import gregtech.api.util.RedstoneUtil; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import gregtech.common.mui.widget.GTTextFieldWidget; @@ -53,6 +55,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.DETECTOR_ENERGY_ADVANCED.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.DETECTOR_ENERGY_ADVANCED).build(); + } + @Override public @NotNull EnumActionResult onScrewdriverClick(@NotNull EntityPlayer playerIn, @NotNull EnumHand hand, @NotNull CuboidRayTraceResult hitResult) { diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorFluid.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorFluid.java index f40fc28746f..d7338f8e5f6 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorFluid.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorFluid.java @@ -3,6 +3,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; import gregtech.api.util.RedstoneUtil; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import gregtech.common.metatileentities.storage.MetaTileEntityCreativeTank; @@ -39,6 +41,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.DETECTOR_FLUID.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.DETECTOR_FLUID).build(); + } + @Override public void update() { if (getOffsetTimer() % 20 != 0) return; diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java index 0a05cb08ffb..8293bbc90fa 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorFluidAdvanced.java @@ -5,6 +5,8 @@ import gregtech.api.cover.CoverableView; import gregtech.api.mui.GTGuis; import gregtech.api.util.RedstoneUtil; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import gregtech.common.covers.filter.FluidFilterContainer; @@ -70,6 +72,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.DETECTOR_FLUID_ADVANCED.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.DETECTOR_FLUID_ADVANCED).build(); + } + @Override public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { return GTGuis.defaultPanel(this) diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorItem.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorItem.java index c9cfeb43bc1..1f4b4989045 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorItem.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorItem.java @@ -3,6 +3,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; import gregtech.api.util.RedstoneUtil; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import gregtech.common.metatileentities.storage.MetaTileEntityCreativeChest; @@ -37,6 +39,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.DETECTOR_ITEM.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.DETECTOR_ITEM).build(); + } + @Override public void update() { if (getOffsetTimer() % 20 != 0) return; diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java index e3368e8ddd5..caaf4d7cb9b 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorItemAdvanced.java @@ -5,6 +5,8 @@ import gregtech.api.cover.CoverableView; import gregtech.api.mui.GTGuis; import gregtech.api.util.RedstoneUtil; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import gregtech.common.covers.filter.ItemFilterContainer; @@ -58,6 +60,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.DETECTOR_ITEM_ADVANCED.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.DETECTOR_ITEM_ADVANCED).build(); + } + @Override public ModularPanel buildUI(SidedPosGuiData guiData, PanelSyncManager guiSyncManager, UISettings settings) { return GTGuis.defaultPanel(this) diff --git a/src/main/java/gregtech/common/covers/detector/CoverDetectorMaintenance.java b/src/main/java/gregtech/common/covers/detector/CoverDetectorMaintenance.java index 85bb2b17dce..22c09478ddd 100644 --- a/src/main/java/gregtech/common/covers/detector/CoverDetectorMaintenance.java +++ b/src/main/java/gregtech/common/covers/detector/CoverDetectorMaintenance.java @@ -3,6 +3,8 @@ import gregtech.api.cover.CoverDefinition; import gregtech.api.cover.CoverableView; import gregtech.api.metatileentity.multiblock.IMaintenance; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import gregtech.common.ConfigHolder; @@ -35,6 +37,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.DETECTOR_MAINTENANCE.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.DETECTOR_MAINTENANCE).build(); + } + @Override public void update() { if (getOffsetTimer() % 20 != 0) { diff --git a/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java b/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java index 0a3f14a990b..154277672aa 100644 --- a/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java +++ b/src/main/java/gregtech/common/covers/ender/CoverEnderFluidLink.java @@ -11,6 +11,8 @@ import gregtech.api.util.virtualregistry.EntryTypes; import gregtech.api.util.virtualregistry.VirtualEnderRegistry; import gregtech.api.util.virtualregistry.entries.VirtualTank; +import gregtech.client.renderer.pipe.cover.CoverRenderer; +import gregtech.client.renderer.pipe.cover.CoverRendererBuilder; import gregtech.client.renderer.texture.Textures; import gregtech.common.covers.CoverPump; import gregtech.common.covers.filter.FluidFilterContainer; @@ -85,6 +87,11 @@ public void renderCover(@NotNull CCRenderState renderState, @NotNull Matrix4 tra Textures.ENDER_FLUID_LINK.renderSided(getAttachedSide(), plateBox, renderState, pipeline, translation); } + @Override + protected CoverRenderer buildRenderer() { + return new CoverRendererBuilder(Textures.ENDER_FLUID_LINK).build(); + } + @Override public void onRemoval() { dropInventoryContents(fluidFilter); diff --git a/src/main/java/gregtech/common/pipelike/cable/BlockCable.java b/src/main/java/gregtech/common/pipelike/cable/BlockCable.java index f395a9ceedf..380b9abd805 100644 --- a/src/main/java/gregtech/common/pipelike/cable/BlockCable.java +++ b/src/main/java/gregtech/common/pipelike/cable/BlockCable.java @@ -12,8 +12,6 @@ import gregtech.api.unification.material.properties.WireProperties; import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.util.GTUtility; -import gregtech.client.renderer.pipe.CableRenderer; -import gregtech.client.renderer.pipe.PipeRenderer; import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.pipelike.cable.net.WorldENet; import gregtech.common.pipelike.cable.tile.TileEntityCable; @@ -22,22 +20,17 @@ import net.minecraft.block.ITileEntityProvider; import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; public class BlockCable extends BlockMaterialPipe @@ -51,7 +44,7 @@ public BlockCable(Insulation cableType, MaterialRegistry registry) { @Override public boolean isValidPipeMaterial(Material material) { - return super.isValidPipeMaterial(material) && !(getItemPipeType(null).isCable() && + return super.isValidPipeMaterial(material) && !(getPipeType().isCable() && material.getProperty(PropertyKey.WIRE).isSuperconductor()); } @@ -60,13 +53,6 @@ public Class getPipeTypeClass() { return Insulation.class; } - @SideOnly(Side.CLIENT) - @NotNull - @Override - public PipeRenderer getPipeRenderer() { - return CableRenderer.INSTANCE; - } - @Override public WorldENet getWorldPipeNet(World world) { return WorldENet.getWorldENet(world); @@ -151,22 +137,8 @@ public void onEntityCollision(World worldIn, @NotNull BlockPos pos, @NotNull IBl } } - @NotNull - @Override - @SideOnly(Side.CLIENT) - @SuppressWarnings("deprecation") - public EnumBlockRenderType getRenderType(@NotNull IBlockState state) { - return CableRenderer.INSTANCE.getBlockRenderType(); - } - @Override public TileEntityPipeBase createNewTileEntity(boolean supportsTicking) { return supportsTicking ? new TileEntityCableTickable() : new TileEntityCable(); } - - @Override - @SideOnly(Side.CLIENT) - protected Pair getParticleTexture(World world, BlockPos blockPos) { - return CableRenderer.INSTANCE.getParticleTexture((TileEntityCable) world.getTileEntity(blockPos)); - } } diff --git a/src/main/java/gregtech/common/pipelike/cable/Insulation.java b/src/main/java/gregtech/common/pipelike/cable/Insulation.java index c1312db34de..e9f34ba7947 100644 --- a/src/main/java/gregtech/common/pipelike/cable/Insulation.java +++ b/src/main/java/gregtech/common/pipelike/cable/Insulation.java @@ -3,6 +3,11 @@ import gregtech.api.pipenet.block.material.IMaterialPipeType; import gregtech.api.unification.material.properties.WireProperties; import gregtech.api.unification.ore.OrePrefix; +import gregtech.client.renderer.pipe.PipeModelRedirector; +import gregtech.client.renderer.pipe.PipeModelRegistry; + +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; @@ -73,4 +78,10 @@ public WireProperties modifyProperties(WireProperties baseProperties) { public boolean isPaintable() { return true; } + + @Override + @SideOnly(Side.CLIENT) + public PipeModelRedirector getModel() { + return PipeModelRegistry.getCableModel(insulationLevel + 1); + } } diff --git a/src/main/java/gregtech/common/pipelike/cable/tile/TileEntityCable.java b/src/main/java/gregtech/common/pipelike/cable/tile/TileEntityCable.java index befdf615466..f8f99ad247c 100644 --- a/src/main/java/gregtech/common/pipelike/cable/tile/TileEntityCable.java +++ b/src/main/java/gregtech/common/pipelike/cable/tile/TileEntityCable.java @@ -174,7 +174,7 @@ private void uninsulate() { TileEntityCable newCable = (TileEntityCable) world.getTileEntity(pos); if (newCable != null) { // should never be null // TODO: use transfer data method - newCable.setPipeData(newBlock, newBlock.getItemPipeType(null), getPipeMaterial()); + newCable.setPipeData(newBlock, newBlock.getPipeType(), getPipeMaterial()); for (EnumFacing facing : EnumFacing.VALUES) { if (isConnected(facing)) { newCable.setConnection(facing, true, true); diff --git a/src/main/java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java b/src/main/java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java index 2063119fe68..98074da54df 100644 --- a/src/main/java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java +++ b/src/main/java/gregtech/common/pipelike/fluidpipe/BlockFluidPipe.java @@ -7,30 +7,23 @@ import gregtech.api.unification.material.properties.FluidPipeProperties; import gregtech.api.unification.material.registry.MaterialRegistry; import gregtech.api.util.EntityDamageUtil; -import gregtech.client.renderer.pipe.FluidPipeRenderer; -import gregtech.client.renderer.pipe.PipeRenderer; import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.pipelike.fluidpipe.net.WorldFluidPipeNet; import gregtech.common.pipelike.fluidpipe.tile.TileEntityFluidPipe; import gregtech.common.pipelike.fluidpipe.tile.TileEntityFluidPipeTickable; import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraftforge.fluids.FluidTank; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; public class BlockFluidPipe extends BlockMaterialPipe { @@ -51,13 +44,6 @@ public WorldFluidPipeNet getWorldPipeNet(World world) { return WorldFluidPipeNet.getWorldPipeNet(world); } - @SideOnly(Side.CLIENT) - @NotNull - @Override - public PipeRenderer getPipeRenderer() { - return FluidPipeRenderer.INSTANCE; - } - @Override public void breakBlock(@NotNull World worldIn, @NotNull BlockPos pos, @NotNull IBlockState state) { super.breakBlock(worldIn, pos, state); @@ -131,18 +117,4 @@ public void onEntityCollision(@NotNull World worldIn, @NotNull BlockPos pos, @No public TileEntityPipeBase createNewTileEntity(boolean supportsTicking) { return new TileEntityFluidPipeTickable(); // fluid pipes are always ticking } - - @Override - @NotNull - @SideOnly(Side.CLIENT) - @SuppressWarnings("deprecation") - public EnumBlockRenderType getRenderType(@NotNull IBlockState state) { - return FluidPipeRenderer.INSTANCE.getBlockRenderType(); - } - - @Override - @SideOnly(Side.CLIENT) - protected Pair getParticleTexture(World world, BlockPos blockPos) { - return FluidPipeRenderer.INSTANCE.getParticleTexture((IPipeTile) world.getTileEntity(blockPos)); - } } diff --git a/src/main/java/gregtech/common/pipelike/fluidpipe/FluidPipeType.java b/src/main/java/gregtech/common/pipelike/fluidpipe/FluidPipeType.java index 2a99c200680..b4ff861ff6f 100644 --- a/src/main/java/gregtech/common/pipelike/fluidpipe/FluidPipeType.java +++ b/src/main/java/gregtech/common/pipelike/fluidpipe/FluidPipeType.java @@ -3,6 +3,11 @@ import gregtech.api.pipenet.block.material.IMaterialPipeType; import gregtech.api.unification.material.properties.FluidPipeProperties; import gregtech.api.unification.ore.OrePrefix; +import gregtech.client.renderer.pipe.PipeModelRedirector; +import gregtech.client.renderer.pipe.PipeModelRegistry; + +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; @@ -72,4 +77,18 @@ public FluidPipeProperties modifyProperties(FluidPipeProperties baseProperties) public boolean isPaintable() { return true; } + + @Override + @SideOnly(Side.CLIENT) + public PipeModelRedirector getModel() { + return switch (this) { + case TINY -> PipeModelRegistry.getPipeModel(0); + case SMALL -> PipeModelRegistry.getPipeModel(1); + case NORMAL -> PipeModelRegistry.getPipeModel(2); + case LARGE -> PipeModelRegistry.getPipeModel(3); + case HUGE -> PipeModelRegistry.getPipeModel(4); + case QUADRUPLE -> PipeModelRegistry.getPipeModel(5); + case NONUPLE -> PipeModelRegistry.getPipeModel(6); + }; + } } diff --git a/src/main/java/gregtech/common/pipelike/itempipe/BlockItemPipe.java b/src/main/java/gregtech/common/pipelike/itempipe/BlockItemPipe.java index eeadaa4ed16..cee5783fb05 100644 --- a/src/main/java/gregtech/common/pipelike/itempipe/BlockItemPipe.java +++ b/src/main/java/gregtech/common/pipelike/itempipe/BlockItemPipe.java @@ -6,29 +6,18 @@ import gregtech.api.pipenet.tile.TileEntityPipeBase; import gregtech.api.unification.material.properties.ItemPipeProperties; import gregtech.api.unification.material.registry.MaterialRegistry; -import gregtech.client.renderer.pipe.ItemPipeRenderer; -import gregtech.client.renderer.pipe.PipeRenderer; import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.pipelike.itempipe.net.WorldItemPipeNet; import gregtech.common.pipelike.itempipe.tile.TileEntityItemPipe; import gregtech.common.pipelike.itempipe.tile.TileEntityItemPipeTickable; -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumFacing; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; import net.minecraftforge.items.CapabilityItemHandler; -import org.apache.commons.lang3.tuple.Pair; -import org.jetbrains.annotations.NotNull; - public class BlockItemPipe extends BlockMaterialPipe { public BlockItemPipe(ItemPipeType itemPipeType, MaterialRegistry registry) { @@ -52,19 +41,6 @@ public WorldItemPipeNet getWorldPipeNet(World world) { return WorldItemPipeNet.getWorldPipeNet(world); } - @Override - @SideOnly(Side.CLIENT) - protected Pair getParticleTexture(World world, BlockPos blockPos) { - return ItemPipeRenderer.INSTANCE.getParticleTexture((TileEntityItemPipe) world.getTileEntity(blockPos)); - } - - @SideOnly(Side.CLIENT) - @NotNull - @Override - public PipeRenderer getPipeRenderer() { - return ItemPipeRenderer.INSTANCE; - } - @Override public boolean canPipesConnect(IPipeTile selfTile, EnumFacing side, IPipeTile sideTile) { @@ -86,12 +62,4 @@ public boolean isHoldingPipe(EntityPlayer player) { ItemStack stack = player.getHeldItemMainhand(); return stack != ItemStack.EMPTY && stack.getItem() instanceof ItemBlockItemPipe; } - - @Override - @NotNull - @SideOnly(Side.CLIENT) - @SuppressWarnings("deprecation") - public EnumBlockRenderType getRenderType(@NotNull IBlockState state) { - return ItemPipeRenderer.INSTANCE.getBlockRenderType(); - } } diff --git a/src/main/java/gregtech/common/pipelike/itempipe/ItemPipeType.java b/src/main/java/gregtech/common/pipelike/itempipe/ItemPipeType.java index cfbdcecb3f3..8dc64ab320b 100644 --- a/src/main/java/gregtech/common/pipelike/itempipe/ItemPipeType.java +++ b/src/main/java/gregtech/common/pipelike/itempipe/ItemPipeType.java @@ -3,6 +3,11 @@ import gregtech.api.pipenet.block.material.IMaterialPipeType; import gregtech.api.unification.material.properties.ItemPipeProperties; import gregtech.api.unification.ore.OrePrefix; +import gregtech.client.renderer.pipe.PipeModelRedirector; +import gregtech.client.renderer.pipe.PipeModelRegistry; + +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; @@ -76,4 +81,19 @@ public String getName() { public OrePrefix getOrePrefix() { return orePrefix; } + + @Override + @SideOnly(Side.CLIENT) + public PipeModelRedirector getModel() { + return switch (this) { + case SMALL -> PipeModelRegistry.getPipeModel(1); + case NORMAL -> PipeModelRegistry.getPipeModel(2); + case LARGE -> PipeModelRegistry.getPipeModel(3); + case HUGE -> PipeModelRegistry.getPipeModel(4); + case RESTRICTIVE_SMALL -> PipeModelRegistry.getPipeRestrictiveModel(1); + case RESTRICTIVE_NORMAL -> PipeModelRegistry.getPipeRestrictiveModel(2); + case RESTRICTIVE_LARGE -> PipeModelRegistry.getPipeRestrictiveModel(3); + case RESTRICTIVE_HUGE -> PipeModelRegistry.getPipeRestrictiveModel(4); + }; + } } diff --git a/src/main/java/gregtech/common/pipelike/laser/BlockLaserPipe.java b/src/main/java/gregtech/common/pipelike/laser/BlockLaserPipe.java index 1c3ac132b60..a67e43a2891 100644 --- a/src/main/java/gregtech/common/pipelike/laser/BlockLaserPipe.java +++ b/src/main/java/gregtech/common/pipelike/laser/BlockLaserPipe.java @@ -6,28 +6,23 @@ import gregtech.api.pipenet.block.BlockPipe; import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.pipenet.tile.TileEntityPipeBase; -import gregtech.client.renderer.pipe.LaserPipeRenderer; +import gregtech.client.renderer.pipe.PipeRenderProperties; import gregtech.client.utils.BloomEffectUtil; import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.pipelike.laser.net.WorldLaserPipeNet; import gregtech.common.pipelike.laser.tile.TileEntityLaserPipe; +import net.minecraft.block.state.BlockStateContainer; import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; -import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumFacing; import net.minecraft.util.NonNullList; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -43,12 +38,6 @@ public BlockLaserPipe(@NotNull LaserPipeType pipeType) { setHarvestLevel(ToolClasses.WIRE_CUTTER, 1); } - @Override - @SideOnly(Side.CLIENT) - protected Pair getParticleTexture(World world, BlockPos blockPos) { - return LaserPipeRenderer.INSTANCE.getParticleTexture((TileEntityLaserPipe) world.getTileEntity(blockPos)); - } - @Override public Class getPipeTypeClass() { return LaserPipeType.class; @@ -90,11 +79,8 @@ protected LaserPipeProperties getFallbackType() { } @Override - public LaserPipeType getItemPipeType(ItemStack itemStack) { - if (itemStack.getItem() instanceof ItemBlockLaserPipe pipe) { - return ((BlockLaserPipe) pipe.getBlock()).pipeType; - } - return null; + public LaserPipeType getPipeType() { + return pipeType; } @Override @@ -135,17 +121,14 @@ public boolean isHoldingPipe(EntityPlayer player) { return stack != ItemStack.EMPTY && stack.getItem() instanceof ItemBlockLaserPipe; } - @Override - @NotNull - @SideOnly(Side.CLIENT) - @SuppressWarnings("deprecation") - public EnumBlockRenderType getRenderType(@NotNull IBlockState state) { - return LaserPipeRenderer.INSTANCE.getBlockRenderType(); - } - @Override public boolean canRenderInLayer(@NotNull IBlockState state, @NotNull BlockRenderLayer layer) { if (layer == BlockRenderLayer.SOLID || layer == BlockRenderLayer.CUTOUT) return true; return layer == BloomEffectUtil.getEffectiveBloomLayer(); } + + @Override + protected @NotNull BlockStateContainer.Builder constructState(BlockStateContainer.@NotNull Builder builder) { + return super.constructState(builder).add(PipeRenderProperties.ACTIVE_PROPERTY); + } } diff --git a/src/main/java/gregtech/common/pipelike/laser/LaserPipeType.java b/src/main/java/gregtech/common/pipelike/laser/LaserPipeType.java index b524b392bb1..5dfc2dfba85 100644 --- a/src/main/java/gregtech/common/pipelike/laser/LaserPipeType.java +++ b/src/main/java/gregtech/common/pipelike/laser/LaserPipeType.java @@ -1,6 +1,11 @@ package gregtech.common.pipelike.laser; import gregtech.api.pipenet.block.IPipeType; +import gregtech.client.renderer.pipe.PipeModelRedirector; +import gregtech.client.renderer.pipe.PipeModelRegistry; + +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; public enum LaserPipeType implements IPipeType { @@ -25,4 +30,10 @@ public LaserPipeProperties modifyProperties(LaserPipeProperties baseProperties) public boolean isPaintable() { return true; } + + @Override + @SideOnly(Side.CLIENT) + public PipeModelRedirector getModel() { + return PipeModelRegistry.getLaserModel(); + } } diff --git a/src/main/java/gregtech/common/pipelike/laser/tile/TileEntityLaserPipe.java b/src/main/java/gregtech/common/pipelike/laser/tile/TileEntityLaserPipe.java index 759fa494152..6d54f23468a 100644 --- a/src/main/java/gregtech/common/pipelike/laser/tile/TileEntityLaserPipe.java +++ b/src/main/java/gregtech/common/pipelike/laser/tile/TileEntityLaserPipe.java @@ -6,6 +6,7 @@ import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.pipenet.tile.TileEntityPipeBase; import gregtech.api.util.TaskScheduler; +import gregtech.client.renderer.pipe.PipeRenderProperties; import gregtech.common.pipelike.laser.LaserPipeProperties; import gregtech.common.pipelike.laser.LaserPipeType; import gregtech.common.pipelike.laser.net.LaserNetHandler; @@ -17,7 +18,10 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.util.Constants; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -230,6 +234,12 @@ public void onChunkUnload() { this.handlers.clear(); } + @Override + @SideOnly(Side.CLIENT) + public IExtendedBlockState getRenderInformation(IExtendedBlockState state) { + return super.getRenderInformation(state).withProperty(PipeRenderProperties.ACTIVE_PROPERTY, isActive()); + } + private static class DefaultLaserContainer implements ILaserContainer { @Override diff --git a/src/main/java/gregtech/common/pipelike/optical/BlockOpticalPipe.java b/src/main/java/gregtech/common/pipelike/optical/BlockOpticalPipe.java index 597fc322801..29c0698f421 100644 --- a/src/main/java/gregtech/common/pipelike/optical/BlockOpticalPipe.java +++ b/src/main/java/gregtech/common/pipelike/optical/BlockOpticalPipe.java @@ -6,26 +6,20 @@ import gregtech.api.pipenet.block.BlockPipe; import gregtech.api.pipenet.tile.IPipeTile; import gregtech.api.pipenet.tile.TileEntityPipeBase; -import gregtech.client.renderer.pipe.OpticalPipeRenderer; +import gregtech.client.renderer.pipe.PipeRenderProperties; import gregtech.common.creativetab.GTCreativeTabs; import gregtech.common.pipelike.optical.net.WorldOpticalPipeNet; import gregtech.common.pipelike.optical.tile.TileEntityOpticalPipe; -import net.minecraft.block.state.IBlockState; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.block.state.BlockStateContainer; import net.minecraft.creativetab.CreativeTabs; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.EnumBlockRenderType; import net.minecraft.util.EnumFacing; import net.minecraft.util.NonNullList; -import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import net.minecraftforge.fml.relauncher.Side; -import net.minecraftforge.fml.relauncher.SideOnly; -import org.apache.commons.lang3.tuple.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -41,12 +35,6 @@ public BlockOpticalPipe(@NotNull OpticalPipeType pipeType) { setHarvestLevel(ToolClasses.WIRE_CUTTER, 1); } - @Override - @SideOnly(Side.CLIENT) - protected Pair getParticleTexture(@NotNull World world, BlockPos blockPos) { - return OpticalPipeRenderer.INSTANCE.getParticleTexture((TileEntityOpticalPipe) world.getTileEntity(blockPos)); - } - @Override public Class getPipeTypeClass() { return OpticalPipeType.class; @@ -88,11 +76,8 @@ protected OpticalPipeProperties getFallbackType() { } @Override - public OpticalPipeType getItemPipeType(@NotNull ItemStack itemStack) { - if (itemStack.getItem() instanceof ItemBlockOpticalPipe pipe) { - return ((BlockOpticalPipe) pipe.getBlock()).pipeType; - } - return null; + public OpticalPipeType getPipeType() { + return pipeType; } @Override @@ -135,10 +120,7 @@ public boolean isHoldingPipe(EntityPlayer player) { } @Override - @NotNull - @SideOnly(Side.CLIENT) - @SuppressWarnings("deprecation") - public EnumBlockRenderType getRenderType(@NotNull IBlockState state) { - return OpticalPipeRenderer.INSTANCE.getBlockRenderType(); + protected @NotNull BlockStateContainer.Builder constructState(BlockStateContainer.@NotNull Builder builder) { + return super.constructState(builder).add(PipeRenderProperties.ACTIVE_PROPERTY); } } diff --git a/src/main/java/gregtech/common/pipelike/optical/OpticalPipeType.java b/src/main/java/gregtech/common/pipelike/optical/OpticalPipeType.java index 18f02a3530c..2684a9e0d41 100644 --- a/src/main/java/gregtech/common/pipelike/optical/OpticalPipeType.java +++ b/src/main/java/gregtech/common/pipelike/optical/OpticalPipeType.java @@ -1,6 +1,11 @@ package gregtech.common.pipelike.optical; import gregtech.api.pipenet.block.IPipeType; +import gregtech.client.renderer.pipe.PipeModelRedirector; +import gregtech.client.renderer.pipe.PipeModelRegistry; + +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; @@ -28,4 +33,10 @@ public boolean isPaintable() { public String getName() { return "normal"; } + + @Override + @SideOnly(Side.CLIENT) + public PipeModelRedirector getModel() { + return PipeModelRegistry.getOpticalModel(); + } } diff --git a/src/main/java/gregtech/common/pipelike/optical/tile/TileEntityOpticalPipe.java b/src/main/java/gregtech/common/pipelike/optical/tile/TileEntityOpticalPipe.java index 43efe04cb56..0d0cf3210d5 100644 --- a/src/main/java/gregtech/common/pipelike/optical/tile/TileEntityOpticalPipe.java +++ b/src/main/java/gregtech/common/pipelike/optical/tile/TileEntityOpticalPipe.java @@ -8,6 +8,7 @@ import gregtech.api.pipenet.tile.TileEntityPipeBase; import gregtech.api.recipes.Recipe; import gregtech.api.util.TaskScheduler; +import gregtech.client.renderer.pipe.PipeRenderProperties; import gregtech.common.pipelike.optical.OpticalPipeProperties; import gregtech.common.pipelike.optical.OpticalPipeType; import gregtech.common.pipelike.optical.net.OpticalNetHandler; @@ -18,6 +19,9 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumFacing; import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.property.IExtendedBlockState; +import net.minecraftforge.fml.relauncher.Side; +import net.minecraftforge.fml.relauncher.SideOnly; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -200,6 +204,12 @@ public void onChunkUnload() { this.handlers.clear(); } + @Override + @SideOnly(Side.CLIENT) + public IExtendedBlockState getRenderInformation(IExtendedBlockState state) { + return super.getRenderInformation(state).withProperty(PipeRenderProperties.ACTIVE_PROPERTY, isActive()); + } + private static class DefaultDataHandler implements IDataAccessHatch { @Override diff --git a/src/main/resources/assets/gregtech/textures/blocks/cable/insulation_5.png b/src/main/resources/assets/gregtech/textures/blocks/cable/insulation_full.png similarity index 100% rename from src/main/resources/assets/gregtech/textures/blocks/cable/insulation_5.png rename to src/main/resources/assets/gregtech/textures/blocks/cable/insulation_full.png diff --git a/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_dl.png b/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_dl.png deleted file mode 100644 index e07a3ff04d74e6b5a2cb83af6c277fcad0d63c3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 283 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!Yyx~jT!AzzE31^0l$@NLo}QkC zg@vuHt)HJ?OiWC1adBN;U44ChV`JmgsZ(dpoH={;?3F85u3EKf-MV#Kwru(H_ZrAx z#*!evUVmd3!_heTTC`85UYU zM2(lv+%x0B+ZFZKcWXaWZ8A8mek|X-o=V^1Iiw2HQ(|Ob0rQ!PC{xWt~$(69A1{ZNLBk diff --git a/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_down.png b/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_down.png deleted file mode 100644 index 5b77df828cbe0754ade62096d75a765f31f034cf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!j01c^TqoGav$C>ENlD4c$?56o zSy))u+SuwQALtEn9ZH3s?Zu&R7!U7tG-B z>_!@p6YlBa7!q;#?d9Eq2Mjov17=#ZY25$2-1i}45qs*FDozas7cdB#HFG*wk4;_d z1uL;4=hr7+X8%w)e0=7eL(M8DU!S~ZApPm*&4824a$9XS-2e65Uw>W}Q!?A!DP2G- O7(8A5T-G@yGywqGuu{|j diff --git a/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_dr.png b/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_dr.png deleted file mode 100644 index 0bbdcfd783605d4a0ef4376850d13c980c4ed751..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 268 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!j01c^T)#g#!ph1jB_$;%C#R>U zXJKJsYik=56H{DVTvu0DUtizY*f?|M%-OSNuUxru)v8rnwro*;v{n_Uov|dyFPOpM z*^M+Hr`^-VF(l&f+bNbphaEUr7}tuKI352V|N21L8!fd>zRxdLi}ZM0Hu1guhr#Vx zX{n!ql1KC6oB-p^sf%(9_H@n_nG^o@>&%(a4A0NjDowwB@@cA!xnzopr0EF6Y`v3p{ diff --git a/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_left.png b/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_left.png deleted file mode 100644 index 5221719ca2f21070108fa48cdb68e8a8a9d9fdc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 224 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!%mREuTzCEd&&tXwB_*Y&r)Obd zVQXva=jRs_6H{DVTwh<`*w{FA>eQJtXU?8Id*#ZNt5&UAw{G2*EnA*WYY73Gz*rLG z7tG-B>_!@p6XEIN7!q;#?PY7R1_KV4z#e&zrp|Zun}c>RE&EvU>|4H;fTEJpuVqZ% zPG8$lColXuoBel|JLjx-@$;l2cx427TMH|9sP4V6(Kui;o8BB@8`tON!h#p&ZG0v& VIh{&WJqomg!PC{xWt~$(69BEBQo8^E diff --git a/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_lr.png b/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_lr.png deleted file mode 100644 index 2b304caed0ddfc2fe70d606a6e605ac8341bd390..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 281 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!Yyx~jT!AzzE31^0l$@NLo}QkC zg@vuHt)HJ?OiWC1adBN;U44ChV`JmgsZ(dpoH={;?3F85u3EKf-MV#Kwru(H_ZrAx z#*!evUO`J<^f>*3!0886DN{Q6nzaMmY$zpSa~iDR6Pw%?h`q#7?D5_%!{&HciYA7z8& z{HE?>nbYnz>4CWVnv>rgud>&wOl5g0@b{@!(zQ2^uk-zvdTwUF>>Rp$<%17jf##>2 ZVw)zw8vJyBha%8222WQ%mvv4FO#r8iZ;b!| diff --git a/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_nd.png b/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_nd.png deleted file mode 100644 index 4a9c81ee52d311ebe5dbf9b3ec58e03e41430b90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 331 zcmV-R0kr;!P)>%tP1IYRjB?+}(lJMy7PjEiZ0kK>X^(DlMnGlzH@5UjL z=rjI701#buo|WIi35%_d4B2_u`Y$uQGlbTY#h){4N*mMO{XehWK66YMG4@+g~n{@OQ dMNyP55{h+IE6uAj=zs@BJC z9{ICXS%j0{|2r2mW4x Rek%X~002ovPDHLkV1hughK&FK diff --git a/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_nr.png b/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_nr.png deleted file mode 100644 index 49ba54b4e664a6576c54d925697ab14f366dfc50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 322 zcmV-I0lof-P)bu_|Z7fG*=uXo@`imRq2N=Rs0ETe+^8{UEcOZ5@T8>b=Y``hC=ck}Rqn_~r z0Bh|%_Ic>Pq-=h#mCWzxoF6-#|C_3+rTt&!;$v|VAm%`vt>yE_oExHuxmS{Kbn+{< zvCTtIuFBbr8ZGU2Y|OwbeRSyRRsgqh5LpcXk*kA1$?2lg5V U`lo^QsQ>@~07*qoM6N<$g1SPDnE(I) diff --git a/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_nu.png b/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_nu.png deleted file mode 100644 index ff0957cd863680b97adc1b3b6aedd51d98492130..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 334 zcmV-U0kQsxP)*qTaRC6R_Vj2np_C0>0RNRIO2;Nkc;8Cc48?fY@>lq&t-gw&fhy zi&jlb3x=*f@muhU8C4n|=C1?z!e*t``0QIcv9hvCNlD4c$?56o zSy))u+SuwQALtEn9p##Lob=GnNGT1v5B2 zyO9Ruw0pWZhD02GJH=AyumcAR<61Ejr{n+QUmqxYqouaV_xa^&ksgoBCcc;dFt|M{ zE%h@{@@QV16JWeKby1GNp3b=Go)78&qol`;+09I>kp8x;= diff --git a/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_right.png b/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_right.png deleted file mode 100644 index 09307337abe5429a3555be76b8f394b0f8ce7137..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 220 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!j01c^Tql%VVP$2Nl9G~>lhf1F zv#_wRwY80ji775FuB)r7udi=xY@9iB=Iq(CSFT*SYSpSOTed`$HTM9uGnNGT1v5B2 zyO9RugnPO;hDb=hJ$O*CL4k+mfbybFLFK>U+VWBg^2c|^3J41RZB$tPrfW*pGLJy> zqqCF_m+hFH)cGStJgme2V?yh;hbG@&cm(wKwG_FyyY00ulIrN_*!Pn4NiI|J)}vQb QfL1Vgy85}Sb4q9e05;4}Qvd(} diff --git a/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_ud.png b/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_ud.png deleted file mode 100644 index d261c7db23d831732d46889f1339730965e26c0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 278 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!Yyx~jT!AzzE31^0l$@NLo}QkC zg@vuHt)HJ?OiWC1adBN;U44ChV`JmgsZ(dpoH={;?3F85u3EKf-MV#Kwru(H_ZrAx z#*!evUYXy6^8-I`}mt?m3+G8K^V6Xkx`K|i775FuCK3eY;2r5b?VHSGiT49y>jKsRjXF5Teoh@mMuL$m_>jlFqQ=Q z1v5B2yO9Ruw0XKXhD02GJH=3_Re{Gv@UI$o;Fo{XMct~?H(f3N)D`eH+rw<>gWgQF z&-S8v{040k(|OA8<)1hmC;B4Uc>cmITbPbl+)X*KBL7c=!eQJtXU?8Id*#ZNt5&UAw{G2*EnC*xaUKDhz*rLG z7tG-B>_!@p6XxmS7!q;#?PYJi1_c3@z$5%y`WAiPzeb2Z!DzGbSFsJRZV3b(nx4q> z?s-&FwPw(Z-yRR|{^qW<+NNcDJa6BjTbGpP{w+H_sde5*_Qs^LkMkLUhW@y7{V0=D TuH+|0Acw)z)z4*}Q$iB}v_V&P diff --git a/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_ur.png b/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked_ur.png deleted file mode 100644 index a72b0c98dcd1b5ceb2652a862a9ea519869bb487..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 279 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!Yyx~jTyu*9Sy@@7q@?8Jgww2>l+&zr%s(ZbLPz1vuCedxpLL2RqNKR+p=X#om=ez zpgD{sL4Lsu4$p3+0XdzXE{-7)hu=;;$k(F4+k2W7`&2>S6Gqeex~?C zQj6~IjYUn1yrfp`U%lCcEh(NuuSAh`_xd%_?lWtD?X%e7{^V2TqfaYya;`@C6brC8 behBc3_{bW(%HX>h&`}JYu6{1-oD!M<1}1Q7 diff --git a/src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked.png b/src/main/resources/assets/gregtech/textures/blocks/pipe/pipe_blocked.png similarity index 100% rename from src/main/resources/assets/gregtech/textures/blocks/pipe/blocked/pipe_blocked.png rename to src/main/resources/assets/gregtech/textures/blocks/pipe/pipe_blocked.png diff --git a/src/main/resources/assets/gregtech/textures/blocks/pipe/pipe_laser_in.png b/src/main/resources/assets/gregtech/textures/blocks/pipe/pipe_laser_in.png index 6277967a5fc29115d719ecd4f1c8d9c85ab543a9..39a0e835a712636cc122c31c630731001b9b0ff7 100644 GIT binary patch delta 191 zcmV;w06_ne0owtPB!2;OQb$4nuFf3k0001!Nkl%>wgS z_@x>Ce0++*MpgroWTct_Ad^9W7#AR`W1M^N72FFj&G@_kl7m@>;RTpRSePJ(0lFBB zj}ivxHp3LbXykx}8z5kt5BCDPE!e^Z-B1h{AV(>(V&w2a7C5Ke0IGWdTR`CrMC6o6 tRy0yAA(5Swsg{{wX`GnMgq$V-n&_ah-QBzK00000NkvXXu0mjf006HOP&WVo delta 117 zcmcc3IEitBN*-r{M`SSr1K$x4W}K?cC(XdX;Nt1x7-G?zoFKs}!t9pQWK*U1e`9C; z&Mj=tw!(Io)&1rjGbsFIvPbVgCc`GTnzjd}jD`%$8Gr7KjJWxt;gN$3YX}2_xwv4x T3`flkpm_|Qu6{1-oD!M Date: Wed, 17 Dec 2025 23:02:00 -0700 Subject: [PATCH 2/2] Yeet some things and clarify others --- src/main/java/gregtech/api/pipenet/block/BlockPipe.java | 1 - .../client/renderer/pipe/cover/CoverRendererBuilder.java | 8 ++++---- .../client/renderer/pipe/util/ActivableCacheKey.java | 3 ++- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java index afbee08526e..016b02d7600 100644 --- a/src/main/java/gregtech/api/pipenet/block/BlockPipe.java +++ b/src/main/java/gregtech/api/pipenet/block/BlockPipe.java @@ -175,7 +175,6 @@ public ItemStack getItem(@NotNull World world, @NotNull BlockPos pos, @NotNull I protected abstract NodeDataType getFallbackType(); - // TODO this has no reason to need an ItemStack parameter public abstract PipeType getPipeType(); public abstract void setTileEntityData(TileEntityPipeBase pipeTile, ItemStack itemStack); diff --git a/src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererBuilder.java b/src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererBuilder.java index 20999ca9b83..a7853be996c 100644 --- a/src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererBuilder.java +++ b/src/main/java/gregtech/client/renderer/pipe/cover/CoverRendererBuilder.java @@ -37,7 +37,7 @@ public class CoverRendererBuilder { private static final ColorQuadCache[] PLATE_QUADS; private static final EnumMap PLATE_COORDS = new EnumMap<>(EnumFacing.class); - private static final UVMapper defaultMapper = UVMapper.standard(0); + private static final UVMapper DEFAULT_MAPPER = UVMapper.standard(0); static { PLATE_QUADS = new ColorQuadCache[Textures.VOLTAGE_CASINGS.length]; @@ -64,7 +64,7 @@ protected static SubListAddress buildPlates(List quads, En int start = quads.size(); Pair box = CoverRendererValues.PLATE_BOXES.get(facing); for (EnumFacing dir : EnumFacing.values()) { - quads.add(QuadHelper.buildQuad(dir, box, CoverRendererBuilder.defaultMapper, sprite)); + quads.add(QuadHelper.buildQuad(dir, box, CoverRendererBuilder.DEFAULT_MAPPER, sprite)); } return new SubListAddress(start, quads.size()); } @@ -78,8 +78,8 @@ protected static void addPlates(List quads, List plateQuad protected final TextureAtlasSprite sprite; protected final TextureAtlasSprite spriteEmissive; - protected UVMapper mapper = defaultMapper; - protected UVMapper mapperEmissive = defaultMapper; + protected UVMapper mapper = DEFAULT_MAPPER; + protected UVMapper mapperEmissive = DEFAULT_MAPPER; protected ColorQuadCache plateQuads = PLATE_QUADS[1]; diff --git a/src/main/java/gregtech/client/renderer/pipe/util/ActivableCacheKey.java b/src/main/java/gregtech/client/renderer/pipe/util/ActivableCacheKey.java index 3091ae3f28c..d4f98a65095 100644 --- a/src/main/java/gregtech/client/renderer/pipe/util/ActivableCacheKey.java +++ b/src/main/java/gregtech/client/renderer/pipe/util/ActivableCacheKey.java @@ -25,5 +25,6 @@ public boolean isActive() { return active; } - // activeness is merely a way to pass information onwards, it does not result in separate mappings. + // activeness is merely a way to pass information onwards, it does not require a separate cache to be built. + // thus we do not override equals() and hashCode() to account for the active field. }