diff --git a/enderio-conduits/src/generated/resources/assets/enderio/models/item/conduit_facade.json b/enderio-conduits/src/generated/resources/assets/enderio/models/item/conduit_facade.json index 018fa944f..7abfddc49 100644 --- a/enderio-conduits/src/generated/resources/assets/enderio/models/item/conduit_facade.json +++ b/enderio-conduits/src/generated/resources/assets/enderio/models/item/conduit_facade.json @@ -1,4 +1,6 @@ { - "loader": "enderio:painted_block", - "reference": "minecraft:stone" + "loader": "enderio:facades_item", + "model": { + "parent": "enderio:block/conduit_facade" + } } \ No newline at end of file diff --git a/enderio-conduits/src/generated/resources/assets/enderio/models/item/hardened_conduit_facade.json b/enderio-conduits/src/generated/resources/assets/enderio/models/item/hardened_conduit_facade.json index 018fa944f..a37006b27 100644 --- a/enderio-conduits/src/generated/resources/assets/enderio/models/item/hardened_conduit_facade.json +++ b/enderio-conduits/src/generated/resources/assets/enderio/models/item/hardened_conduit_facade.json @@ -1,4 +1,6 @@ { - "loader": "enderio:painted_block", - "reference": "minecraft:stone" + "loader": "enderio:facades_item", + "model": { + "parent": "enderio:block/hardened_conduit_facade" + } } \ No newline at end of file diff --git a/enderio-conduits/src/generated/resources/assets/enderio/models/item/transparent_conduit_facade.json b/enderio-conduits/src/generated/resources/assets/enderio/models/item/transparent_conduit_facade.json index 018fa944f..b1b67883d 100644 --- a/enderio-conduits/src/generated/resources/assets/enderio/models/item/transparent_conduit_facade.json +++ b/enderio-conduits/src/generated/resources/assets/enderio/models/item/transparent_conduit_facade.json @@ -1,4 +1,6 @@ { - "loader": "enderio:painted_block", - "reference": "minecraft:stone" + "loader": "enderio:facades_item", + "model": { + "parent": "enderio:block/transparent_conduit_facade" + } } \ No newline at end of file diff --git a/enderio-conduits/src/generated/resources/assets/enderio/models/item/transparent_hardened_conduit_facade.json b/enderio-conduits/src/generated/resources/assets/enderio/models/item/transparent_hardened_conduit_facade.json index 018fa944f..fea175e99 100644 --- a/enderio-conduits/src/generated/resources/assets/enderio/models/item/transparent_hardened_conduit_facade.json +++ b/enderio-conduits/src/generated/resources/assets/enderio/models/item/transparent_hardened_conduit_facade.json @@ -1,4 +1,6 @@ { - "loader": "enderio:painted_block", - "reference": "minecraft:stone" + "loader": "enderio:facades_item", + "model": { + "parent": "enderio:block/transparent_hardened_conduit_facade" + } } \ No newline at end of file diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitClientSetup.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitClientSetup.java index 7e920fefb..4f2b979b3 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitClientSetup.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitClientSetup.java @@ -9,26 +9,17 @@ import com.enderio.conduits.client.gui.conduit.ItemConduitScreenExtension; import com.enderio.conduits.client.model.ConduitGeometry; import com.enderio.conduits.client.model.ConduitItemModelLoader; +import com.enderio.conduits.client.model.FacadeItemGeometry; import com.enderio.conduits.client.model.conduit.modifier.ConduitCoreModelModifiers; import com.enderio.conduits.client.model.conduit.modifier.FluidConduitCoreModelModifier; -import com.enderio.conduits.common.init.ConduitBlocks; import com.enderio.conduits.common.init.ConduitTypes; -import net.minecraft.client.Minecraft; -import net.minecraft.client.color.block.BlockColor; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; -import net.minecraft.core.BlockPos; -import net.minecraft.world.item.DyeColor; -import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; import net.neoforged.neoforge.client.event.ModelEvent; -import net.neoforged.neoforge.client.event.RegisterColorHandlersEvent; -import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.HashMap; @@ -42,8 +33,7 @@ public class ConduitClientSetup { private static final Map MODELS = new HashMap<>(); public static final ModelResourceLocation CONDUIT_CONNECTOR = loc("block/conduit_connector"); - public static final ModelResourceLocation CONDUIT_FACADE = loc("block/cube_all"); -// public static final ModelResourceLocation CONDUIT_FACADE = loc("block/conduit_facade"); + public static final ModelResourceLocation CONDUIT_FACADE_OVERLAY = loc("block/conduit_facade_overlay"); public static final ModelResourceLocation CONDUIT_CONNECTION = loc("block/conduit_connection"); public static final ModelResourceLocation CONDUIT_CORE = loc("block/conduit_core"); public static final ModelResourceLocation BOX = loc("block/box/1x1x1"); @@ -53,6 +43,12 @@ public class ConduitClientSetup { public static final ModelResourceLocation CONDUIT_IO_OUT = loc("block/io/output"); public static final ModelResourceLocation CONDUIT_IO_REDSTONE = loc("block/io/redstone"); + public static final ModelResourceLocation CONDUIT_FACADE = loc("block/conduit_facade"); + public static final ModelResourceLocation CONDUIT_FACADE_HARDENED = loc("block/conduit_facade_hardened"); + public static final ModelResourceLocation CONDUIT_FACADE_TRANSLUCENT = loc("block/conduit_facade_translucent"); + public static final ModelResourceLocation CONDUIT_FACADE_TRANSLUCENT_HARDENED = loc("block/conduit_facade_translucent_hardened"); + + private ConduitClientSetup() {} @SubscribeEvent @@ -75,6 +71,7 @@ public static void registerConduitScreenExtensions(RegisterConduitScreenExtensio public static void modelLoader(ModelEvent.RegisterGeometryLoaders event) { event.register(EnderIOBase.loc("conduit"), new ConduitGeometry.Loader()); event.register(EnderIOBase.loc("conduit_item"), new ConduitItemModelLoader()); + event.register(EnderIOBase.loc("facades_item"), new FacadeItemGeometry.Loader()); } @SubscribeEvent @@ -95,19 +92,6 @@ public static void bakingModelsFinished(ModelEvent.BakingCompleted event) { } } - @SubscribeEvent - public static void blockColors(RegisterColorHandlersEvent.Block block) { - block.register(new ConduitBlockColor(), ConduitBlocks.CONDUIT.get()); - } - - public static class ConduitBlockColor implements BlockColor { - - @Override - public int getColor(BlockState state, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos, int tintIndex) { - return DyeColor.values()[tintIndex].getTextureDiffuseColor(); - } - } - private static ModelResourceLocation loc(String modelName) { ModelResourceLocation loc = ModelResourceLocation.standalone(EnderIOBase.loc(modelName)); MODEL_LOCATIONS.add(loc); @@ -117,8 +101,4 @@ private static ModelResourceLocation loc(String modelName) { public static BakedModel modelOf(ModelResourceLocation location) { return MODELS.get(location); } - - public static Level getClientLevel() { - return Minecraft.getInstance().level; - } } diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeColor.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeColor.java new file mode 100644 index 000000000..93f75ce26 --- /dev/null +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeColor.java @@ -0,0 +1,67 @@ +package com.enderio.conduits.client; + +import com.enderio.base.common.init.EIODataComponents; +import com.enderio.conduits.client.model.conduit.facades.FacadeHelper; +import com.enderio.conduits.common.conduit.block.ConduitBundleBlockEntity; +import net.minecraft.client.Minecraft; +import net.minecraft.client.color.block.BlockColor; +import net.minecraft.client.color.item.ItemColor; +import net.minecraft.core.BlockPos; +import net.minecraft.world.item.DyeColor; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class ConduitFacadeColor implements BlockColor, ItemColor { + @Override + public int getColor(BlockState state, @Nullable BlockAndTintGetter level, @Nullable BlockPos pos, int tintIndex) { + if (tintIndex >= 0) { + return DyeColor.values()[tintIndex].getTextureDiffuseColor(); + } + tintIndex = unmoveTintIndex(tintIndex); + if (level != null && pos != null) { + BlockEntity entity = level.getBlockEntity(pos); + if (entity instanceof ConduitBundleBlockEntity conduitBundleBlock) { + + Optional facade = conduitBundleBlock.getBundle().facade(); + + if (facade.isPresent() && FacadeHelper.areFacadesVisible()) { + int color = Minecraft.getInstance().getBlockColors().getColor(facade.get().defaultBlockState(), level, pos, tintIndex); + if (color != -1) { + return color; + } + } + } + } + + return 0xFFFFFF; + } + + @Override + public int getColor(ItemStack stack, int tintIndex) { + var facadeData = stack.get(EIODataComponents.BLOCK_PAINT); + if (facadeData != null) { + var block = facadeData.paint(); + return Minecraft.getInstance().getItemColors().getColor(block.asItem().getDefaultInstance(), tintIndex); + } + + return 0; + } + + public static int moveTintIndex(int original) { + return -original - 2; + } + + public static int unmoveTintIndex(int original) { + if (original > 0) { + return original; + } else { + return -original - 2; + } + } +} diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java new file mode 100644 index 000000000..90758a16c --- /dev/null +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java @@ -0,0 +1,71 @@ +package com.enderio.conduits.client; + +import com.enderio.conduits.client.model.conduit.facades.FacadeHelper; +import com.enderio.conduits.common.conduit.block.ConduitBundleBlock; +import com.enderio.conduits.common.conduit.block.ConduitBundleBlockEntity; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.Minecraft; +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.client.renderer.Sheets; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.core.BlockPos; +import net.minecraft.util.FastColor; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.LightLayer; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.bus.api.SubscribeEvent; +import net.neoforged.fml.common.EventBusSubscriber; +import net.neoforged.neoforge.client.event.RenderLevelStageEvent; +import net.neoforged.neoforge.client.model.data.ModelData; +import net.neoforged.neoforge.client.model.pipeline.VertexConsumerWrapper; + +import java.util.Map; + +@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT) +public class ConduitFacadeRendering { + + @SubscribeEvent + static void renderFacade(RenderLevelStageEvent event) { + if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_TRIPWIRE_BLOCKS || FacadeHelper.areFacadesVisible()) { + return; + } + for (Map.Entry entry : ConduitBundleBlockEntity.FACADES.entrySet()) { + ClientLevel level = Minecraft.getInstance().level; + if (!level.isLoaded(entry.getKey())) { + return; + } + if (level.getBlockState(entry.getKey()).getBlock() instanceof ConduitBundleBlock) { + if (entry.getValue() == null) { + continue; + } + + var baseConsumer = Minecraft.getInstance().renderBuffers().bufferSource().getBuffer(Sheets.translucentCullBlockSheet()); + var wrappedConsumer = new VertexConsumerWrapper(baseConsumer) { + @Override + public VertexConsumer setColor(int r, int g, int b, int a) { + super.setColor(r, g, b, 85); + return this; + } + }; + + var cameraPos = event.getCamera().getPosition(); + event.getPoseStack().pushPose(); + event.getPoseStack().translate(entry.getKey().getX()-cameraPos.x, entry.getKey().getY()-cameraPos.y, entry.getKey().getZ()-cameraPos.z); + + var model = Minecraft.getInstance().getModelManager().getBlockModelShaper().getBlockModel(entry.getValue()); + int color = Minecraft.getInstance().getBlockColors().getColor(entry.getValue(), level, entry.getKey()); + for (var renderType : model.getRenderTypes(entry.getValue(), RandomSource.create(), ModelData.EMPTY)) { + Minecraft.getInstance().getBlockRenderer().getModelRenderer().renderModel(event.getPoseStack().last(), wrappedConsumer, entry.getValue(), + model, FastColor.ARGB32.red(color) / 255.0F, FastColor.ARGB32.green(color) / 255.0F, FastColor.ARGB32.blue(color) / 255.0F, + LightTexture.pack(level.getBrightness(LightLayer.BLOCK, entry.getKey()), level.getBrightness(LightLayer.SKY, entry.getKey())), + OverlayTexture.NO_OVERLAY, model.getModelData(level, entry.getKey(), entry.getValue(), ModelData.EMPTY), renderType + ); + } + Minecraft.getInstance().renderBuffers().bufferSource().endBatch(Sheets.translucentCullBlockSheet()); + event.getPoseStack().popPose(); + } + } + } +} diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/ConduitBlockModel.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/ConduitBlockModel.java index 0c51ee84f..1afb6a9e1 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/ConduitBlockModel.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/ConduitBlockModel.java @@ -4,7 +4,7 @@ import com.enderio.conduits.api.ConduitNode; import com.enderio.conduits.api.model.ConduitCoreModelModifier; import com.enderio.base.api.misc.RedstoneControl; -import com.enderio.base.client.paint.model.PaintingQuadTransformer; +import com.enderio.conduits.client.ConduitFacadeColor; import com.enderio.conduits.client.model.conduit.facades.FacadeHelper; import com.enderio.conduits.client.model.conduit.modifier.ConduitCoreModelModifiers; import com.enderio.conduits.common.Area; @@ -31,8 +31,10 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; import net.minecraft.world.inventory.InventoryMenu; +import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.SingleThreadedRandomSource; import net.neoforged.neoforge.client.ChunkRenderTypeSet; import net.neoforged.neoforge.client.model.IDynamicBakedModel; import net.neoforged.neoforge.client.model.IQuadTransformer; @@ -56,7 +58,6 @@ import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_CONNECTION_BOX; import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_CONNECTOR; import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_CORE; -import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_FACADE; import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_IO_IN; import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_IO_IN_OUT; import static com.enderio.conduits.client.ConduitClientSetup.CONDUIT_IO_OUT; @@ -71,17 +72,20 @@ public List getQuads(@Nullable BlockState state, @Nullable Direction List quads = new ArrayList<>(); ConduitBundle conduitBundle = extraData.get(ConduitBundleBlockEntity.BUNDLE_MODEL_PROPERTY); - BlockPos pos = extraData.get(ConduitBundleBlockEntity.POS); + ModelData data = extraData.get(ConduitBundleBlockEntity.FACADE_MODEL_DATA); - if (conduitBundle != null && pos != null) { + if (conduitBundle != null) { if (FacadeHelper.areFacadesVisible()) { + IQuadTransformer transformer = quad -> quad.tintIndex = ConduitFacadeColor.moveTintIndex(quad.getTintIndex()); Optional facadeOpt = conduitBundle.facade(); if (facadeOpt.isPresent()) { BlockState facade = facadeOpt.get().defaultBlockState(); + var model = Minecraft.getInstance().getBlockRenderer().getBlockModel(facade); + var facadeQuads = model.getQuads(facade, side, rand, data, renderType); - quads.addAll(/*new BlockColorQuadDataTransformer(pos, Minecraft.getInstance().level, facade) - .andThen(*/new PaintingQuadTransformer(facade, renderType)/*)*/ - .process(modelOf(CONDUIT_FACADE).getQuads(state, side, rand, ModelData.EMPTY, renderType))); + if (renderType != null && model.getRenderTypes(facade, rand, data).contains(renderType)) { + quads.addAll(transformer.process(facadeQuads)); + } } // If the facade should hide the conduits, escape early. @@ -294,6 +298,9 @@ public TextureAtlasSprite getParticleIcon(ModelData data) { if (conduitBundle == null || conduitBundle.getConduits().isEmpty()) { return ModelHelper.getMissingTexture(); } + if (conduitBundle.hasFacade()) { + return Minecraft.getInstance().getBlockRenderer().getBlockModel(conduitBundle.facade().get().defaultBlockState()).getParticleIcon(data.get(ConduitBundleBlockEntity.FACADE_MODEL_DATA)); + } return sprite(conduitBundle, conduitBundle.getConduits().getFirst()); } @@ -304,7 +311,27 @@ public ItemOverrides getOverrides() { @Override public ChunkRenderTypeSet getRenderTypes(@NotNull BlockState state, @NotNull RandomSource rand, @NotNull ModelData data) { - return ChunkRenderTypeSet.of(RenderType.cutout()); + ChunkRenderTypeSet facadeRenderTypes = data.get(ConduitBundleBlockEntity.FACADE_RENDERTYPE); + ChunkRenderTypeSet renderTypes = ChunkRenderTypeSet.of(RenderType.cutout()); + if (facadeRenderTypes != null) { + renderTypes = ChunkRenderTypeSet.union(renderTypes, facadeRenderTypes); + } + return renderTypes; + } + + @Override + public ModelData getModelData(BlockAndTintGetter level, BlockPos pos, BlockState state, ModelData modelData) { + ModelData data = IDynamicBakedModel.super.getModelData(level, pos, state, modelData); + ModelData.Builder builder = data.derive(); + ConduitBundle conduitBundle = data.get(ConduitBundleBlockEntity.BUNDLE_MODEL_PROPERTY); + if (conduitBundle != null && conduitBundle.hasFacade()) { + BlockState blockState = conduitBundle.facade().get().defaultBlockState(); + BakedModel blockModel = Minecraft.getInstance().getBlockRenderer().getBlockModel(blockState); + ModelData facadeData = blockModel.getModelData(level, pos, blockState, ModelData.EMPTY); + builder.with(ConduitBundleBlockEntity.FACADE_MODEL_DATA, facadeData); + builder.with(ConduitBundleBlockEntity.FACADE_RENDERTYPE, blockModel.getRenderTypes(blockState, new SingleThreadedRandomSource(state.getSeed(pos)), facadeData)); + } + return builder.build(); } private static TextureAtlasSprite sprite(ConduitBundle conduitBundle, Holder> type) { diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/FacadeItemGeometry.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/FacadeItemGeometry.java new file mode 100644 index 000000000..102752c48 --- /dev/null +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/FacadeItemGeometry.java @@ -0,0 +1,49 @@ +package com.enderio.conduits.client.model; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.Material; +import net.minecraft.client.resources.model.ModelBaker; +import net.minecraft.client.resources.model.ModelResourceLocation; +import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.client.model.geometry.IGeometryBakingContext; +import net.neoforged.neoforge.client.model.geometry.IGeometryLoader; +import net.neoforged.neoforge.client.model.geometry.IUnbakedGeometry; + +import java.util.function.Function; + +public class FacadeItemGeometry implements IUnbakedGeometry { + + private final BlockModel facadeModel; + + public FacadeItemGeometry(BlockModel facadeModel) { + this.facadeModel = facadeModel; + } + + @Override + public BakedModel bake(IGeometryBakingContext context, ModelBaker baker, Function spriteGetter, ModelState modelState, + ItemOverrides overrides) { + return new FacadeItemModel(facadeModel.bake(baker, spriteGetter, modelState)); + } + + @Override + public void resolveParents(Function modelGetter, IGeometryBakingContext context) { + facadeModel.resolveParents(modelGetter); + } + + public static class Loader implements IGeometryLoader { + @Override + public FacadeItemGeometry read(JsonObject jsonObject, JsonDeserializationContext deserializationContext) throws JsonParseException { + BlockModel model = deserializationContext.deserialize(jsonObject.get("model"), BlockModel.class); + return new FacadeItemGeometry(model); + } + } +} diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/FacadeItemModel.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/FacadeItemModel.java new file mode 100644 index 000000000..3f395390e --- /dev/null +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/FacadeItemModel.java @@ -0,0 +1,126 @@ +package com.enderio.conduits.client.model; + +import com.enderio.base.common.init.EIODataComponents; +import com.enderio.conduits.client.ConduitClientSetup; +import com.enderio.core.data.model.ModelHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.renderer.block.model.ItemOverrides; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.Direction; +import net.minecraft.util.RandomSource; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.client.model.IDynamicBakedModel; +import net.neoforged.neoforge.client.model.data.ModelData; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static com.enderio.conduits.client.ConduitClientSetup.modelOf; + +public class FacadeItemModel implements IDynamicBakedModel { + + private final Map> itemRenderCache = new HashMap<>(); + private final Block facade; + private final BakedModel facadeModel; + + public FacadeItemModel(BakedModel facadeModel) { + this.facade = null; + this.facadeModel = facadeModel; + } + + private FacadeItemModel(BakedModel facadeModel, Block facade) { + this.facade = facade; + this.facadeModel = facadeModel; + } + + @Override + public List getQuads(@Nullable BlockState state, @Nullable Direction side, RandomSource rand, ModelData extraData, + @Nullable RenderType renderType) { + List bakedQuads = new ArrayList<>(); + if (facade != null) { + bakedQuads.addAll(getItemModel().getQuads(facade.defaultBlockState(), side, rand, extraData, renderType)); + bakedQuads.addAll(modelOf(ConduitClientSetup.CONDUIT_FACADE_OVERLAY).getQuads(null, side, rand, extraData, renderType)); + } else { + bakedQuads.addAll(facadeModel.getQuads(null, side, rand, extraData, renderType)); + } + return bakedQuads; + } + + @Override + public boolean useAmbientOcclusion() { + return false; + } + + @Override + public boolean isGui3d() { + return true; + } + + @Override + public boolean usesBlockLight() { + return true; + } + + @Override + public boolean isCustomRenderer() { + return false; + } + + @Override + public TextureAtlasSprite getParticleIcon() { + return ModelHelper.getMissingTexture(); + } + + @Override + public ItemOverrides getOverrides() { + return ItemOverrides.EMPTY; + } + + @Override + public ItemTransforms getTransforms() { + return modelOf(ConduitClientSetup.CONDUIT_FACADE_OVERLAY).getTransforms(); + } + + @Override + public List getRenderTypes(ItemStack itemStack, boolean fabulous) { + if (!itemStack.has(EIODataComponents.BLOCK_PAINT)) { + return List.of(RenderType.solid()); + } + + var paintData = itemStack.get(EIODataComponents.BLOCK_PAINT); + if (paintData == null) { + return List.of(RenderType.cutout()); + } + return Minecraft.getInstance().getItemRenderer().getModel(paintData.paint().asItem().getDefaultInstance(), null, null, 0).getRenderTypes(itemStack, fabulous); + } + + @Override + public List getRenderPasses(ItemStack itemStack, boolean fabulous) { + if (!itemStack.has(EIODataComponents.BLOCK_PAINT)) { + return List.of(this); + } + + var paintData = itemStack.get(EIODataComponents.BLOCK_PAINT); + return itemRenderCache.computeIfAbsent(paintData.paint(), + paintKey -> List.of(new FacadeItemModel(facadeModel, paintData.paint())) + ); + } + + /** + * Get the reference block's item model. + */ + private BakedModel getItemModel() { + return Minecraft.getInstance().getItemRenderer().getModel(facade.asItem().getDefaultInstance(), null, null, 0); + } + +} diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java index aeae953af..2a3b98a41 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java @@ -1,21 +1,18 @@ package com.enderio.conduits.client.model.conduit.facades; -import com.enderio.base.common.tag.EIOTags; import net.minecraft.client.Minecraft; -import net.minecraft.world.InteractionHand; // TODO: In future, support hiding specific conduit types too. public class FacadeHelper { - public static boolean areFacadesVisible() { - var minecraft = Minecraft.getInstance(); - if (minecraft.player == null) { - return true; - } - var mainHand = minecraft.player.getItemInHand(InteractionHand.MAIN_HAND); - var offHand = minecraft.player.getItemInHand(InteractionHand.OFF_HAND); + private static boolean FACADES_VISIBLE = true; - return !mainHand.is(EIOTags.Items.HIDE_FACADES) && !offHand.is(EIOTags.Items.HIDE_FACADES); + public static void setFacadesVisible(boolean visible) { + FACADES_VISIBLE = visible; + } + + public static boolean areFacadesVisible() { + return FACADES_VISIBLE; } public static void rebuildChunkMeshes() { diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/YetaChunkRebuildHandler.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/YetaChunkRebuildHandler.java index 7312b3aa3..deaf97457 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/YetaChunkRebuildHandler.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/YetaChunkRebuildHandler.java @@ -1,6 +1,5 @@ package com.enderio.conduits.client.model.conduit.facades; -import com.enderio.base.common.item.tool.YetaWrenchItem; import com.enderio.base.common.tag.EIOTags; import com.enderio.conduits.EnderIOConduits; import net.minecraft.client.player.LocalPlayer; @@ -22,6 +21,7 @@ public static void onEquipmentChanged(LivingEquipmentChangeEvent event) { if (event.getTo().is(EIOTags.Items.HIDE_FACADES) || event.getFrom().is(EIOTags.Items.HIDE_FACADES)) { + FacadeHelper.setFacadesVisible(!event.getTo().is(EIOTags.Items.HIDE_FACADES)); FacadeHelper.rebuildChunkMeshes(); } } diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/common/conduit/block/ConduitBundleBlock.java b/enderio-conduits/src/main/java/com/enderio/conduits/common/conduit/block/ConduitBundleBlock.java index a030d5a6a..56a13af0a 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/common/conduit/block/ConduitBundleBlock.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/common/conduit/block/ConduitBundleBlock.java @@ -455,7 +455,7 @@ public ItemStack getCloneItemStack(BlockState state, HitResult target, LevelRead if (level.getBlockEntity(pos) instanceof ConduitBundleBlockEntity blockEntity) { Optional facade = blockEntity.getBundle().facade(); - if (facade.isPresent()) { + if (facade.isPresent() && FacadeHelper.areFacadesVisible()) { return facade.get().asItem().getDefaultInstance(); } diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/common/conduit/block/ConduitBundleBlockEntity.java b/enderio-conduits/src/main/java/com/enderio/conduits/common/conduit/block/ConduitBundleBlockEntity.java index 3204186a7..90829640d 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/common/conduit/block/ConduitBundleBlockEntity.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/common/conduit/block/ConduitBundleBlockEntity.java @@ -23,8 +23,6 @@ import com.enderio.conduits.common.conduit.connection.ConnectionState; import com.enderio.conduits.common.conduit.connection.DynamicConnectionState; import com.enderio.conduits.common.conduit.connection.StaticConnectionStates; -import com.enderio.conduits.common.conduit.facades.ConduitFacadeProvider; -import com.enderio.conduits.common.conduit.facades.FacadeType; import com.enderio.conduits.common.init.ConduitBlockEntities; import com.enderio.conduits.common.init.ConduitCapabilities; import com.enderio.conduits.common.menu.ConduitMenu; @@ -55,6 +53,7 @@ import net.neoforged.fml.LogicalSide; import net.neoforged.neoforge.capabilities.BlockCapability; import net.neoforged.neoforge.capabilities.ICapabilityProvider; +import net.neoforged.neoforge.client.ChunkRenderTypeSet; import net.neoforged.neoforge.client.model.data.ModelData; import net.neoforged.neoforge.client.model.data.ModelProperty; import net.neoforged.neoforge.common.util.INBTSerializable; @@ -76,9 +75,13 @@ public class ConduitBundleBlockEntity extends EnderBlockEntity { public static final ModelProperty BUNDLE_MODEL_PROPERTY = new ModelProperty<>(); - public static final ModelProperty POS = new ModelProperty<>(); + public static final ModelProperty FACADE_MODEL_DATA = new ModelProperty<>(); + public static final ModelProperty FACADE_RENDERTYPE = new ModelProperty<>(); public static final String CONDUIT_INV_KEY = "ConduitInv"; + @UseOnly(LogicalSide.CLIENT) + public static final Map FACADES = new HashMap<>(); + private final ConduitShape shape = new ConduitShape(); private ConduitBundle bundle; @@ -117,6 +120,11 @@ public void updateClient() { updateShape(); requestModelDataUpdate(); level.setBlocksDirty(getBlockPos(), Blocks.AIR.defaultBlockState(), getBlockState()); + if (bundle.hasFacade()) { + FACADES.put(worldPosition, bundle.facade().get().defaultBlockState()); + } else { + FACADES.remove(worldPosition); + } } } @@ -203,6 +211,12 @@ public void onChunkUnloaded() { if (level instanceof ServerLevel serverLevel) { ConduitSavedData savedData = ConduitSavedData.get(serverLevel); bundle.getConduits().forEach(type -> onChunkUnloaded(savedData, type)); + } else { + if (bundle.hasFacade()) { + FACADES.put(worldPosition, bundle.facade().get().defaultBlockState()); + } else { + FACADES.remove(worldPosition); + } } } @@ -299,7 +313,9 @@ public void setLevel(Level pLevel) { @Override public ModelData getModelData() { - return ModelData.builder().with(BUNDLE_MODEL_PROPERTY, clientBundle).with(POS, worldPosition).build(); + return ModelData.builder() + .with(BUNDLE_MODEL_PROPERTY, clientBundle) + .build(); } public boolean hasType(Holder> conduit) { diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/common/init/ConduitBlocks.java b/enderio-conduits/src/main/java/com/enderio/conduits/common/init/ConduitBlocks.java index 3c5d68dd4..412562c07 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/common/init/ConduitBlocks.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/common/init/ConduitBlocks.java @@ -2,6 +2,7 @@ import com.enderio.base.common.tag.EIOTags; import com.enderio.conduits.EnderIOConduits; +import com.enderio.conduits.client.ConduitFacadeColor; import com.enderio.conduits.common.conduit.ConduitBlockItem; import com.enderio.conduits.common.conduit.block.ConduitBundleBlock; import com.enderio.conduits.data.model.ConduitBlockState; @@ -26,6 +27,7 @@ public class ConduitBlocks { .noOcclusion() .dynamicShape() .mapColor(MapColor.STONE)) + .setColorSupplier(() -> ConduitFacadeColor::new) .setTranslation("Conduit Bundle") .setBlockStateProvider(ConduitBlockState::conduit) .addBlockTags(BlockTags.MINEABLE_WITH_PICKAXE) diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/common/init/ConduitItems.java b/enderio-conduits/src/main/java/com/enderio/conduits/common/init/ConduitItems.java index c61e0db0d..2a1258ee3 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/common/init/ConduitItems.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/common/init/ConduitItems.java @@ -5,6 +5,8 @@ import com.enderio.base.common.init.EIOCreativeTabs; import com.enderio.base.data.model.block.PaintedBlockModelBuilder; import com.enderio.conduits.EnderIOConduits; +import com.enderio.conduits.client.ConduitClientSetup; +import com.enderio.conduits.client.ConduitFacadeColor; import com.enderio.conduits.common.conduit.facades.ComponentBackedConduitFacadeProvider; import com.enderio.conduits.common.conduit.facades.FacadeType; import com.enderio.conduits.common.conduit.upgrade.SpeedUpgradeItem; @@ -13,6 +15,8 @@ import com.enderio.conduits.common.redstone.RedstoneFilterItem; import com.enderio.conduits.common.redstone.RedstoneTLatchFilter; import com.enderio.conduits.common.redstone.RedstoneTimerFilter; +import com.enderio.conduits.data.model.FacadeItemModelBuilder; +import com.enderio.core.client.ClientModEvents; import com.enderio.regilite.holder.RegiliteItem; import com.enderio.regilite.registry.ItemRegistry; import net.minecraft.core.component.DataComponentType; @@ -40,10 +44,11 @@ private static RegiliteItem conduitFacade(String name, FacadeType type) { props -> new Item(props.component(ConduitComponents.FACADE_TYPE, type))) // TODO: Model for when there is no "paint" .setModelProvider((prov, ctx) -> prov.getBuilder(name) - .customLoader(PaintedBlockModelBuilder::begin) - .reference(Blocks.STONE) + .customLoader(FacadeItemModelBuilder::begin) + .model(name) .end()) .setTab(EIOCreativeTabs.CONDUITS) + .setColorSupplier(() -> ConduitFacadeColor::new) .addCapability(ConduitCapabilities.ConduitFacade.ITEM, ComponentBackedConduitFacadeProvider.PROVIDER); } diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/data/model/FacadeItemModelBuilder.java b/enderio-conduits/src/main/java/com/enderio/conduits/data/model/FacadeItemModelBuilder.java new file mode 100644 index 000000000..c82c1c140 --- /dev/null +++ b/enderio-conduits/src/main/java/com/enderio/conduits/data/model/FacadeItemModelBuilder.java @@ -0,0 +1,35 @@ +package com.enderio.conduits.data.model; + +import com.enderio.EnderIOBase; +import com.google.gson.JsonObject; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.neoforge.client.model.generators.CustomLoaderBuilder; +import net.neoforged.neoforge.client.model.generators.ModelBuilder; +import net.neoforged.neoforge.common.data.ExistingFileHelper; + +public class FacadeItemModelBuilder> extends CustomLoaderBuilder { + + private ResourceLocation model; + + public static > FacadeItemModelBuilder begin(T parent, ExistingFileHelper existingFileHelper) { + return new FacadeItemModelBuilder<>(parent, existingFileHelper); + } + + protected FacadeItemModelBuilder(T parent, ExistingFileHelper existingFileHelper) { + super(EnderIOBase.loc("facades_item"), parent, existingFileHelper, false); + } + + public FacadeItemModelBuilder model(String name) { + this.model = EnderIOBase.loc("block/" + name); + return this; + } + + @Override + public JsonObject toJson(JsonObject json) { + json = super.toJson(json); + JsonObject model = new JsonObject(); + model.addProperty("parent", this.model.toString()); + json.add("model", model); + return json; + } +} diff --git a/enderio-conduits/src/main/resources/assets/enderio/models/block/conduit_facade.json b/enderio-conduits/src/main/resources/assets/enderio/models/block/conduit_facade.json index 5508f8bc2..b3bc1dc43 100644 --- a/enderio-conduits/src/main/resources/assets/enderio/models/block/conduit_facade.json +++ b/enderio-conduits/src/main/resources/assets/enderio/models/block/conduit_facade.json @@ -1,18 +1,7 @@ { - "credit": "Made with Blockbench", - "elements": [ - { - "from": [0, 0, 0], - "to": [16, 2, 16], - "color": 3, - "faces": { - "north": {"uv": [0, 0, 16, 2], "texture": "#missing"}, - "east": {"uv": [0, 0, 16, 2], "texture": "#missing"}, - "south": {"uv": [0, 0, 16, 2], "texture": "#missing"}, - "west": {"uv": [0, 0, 16, 2], "texture": "#missing"}, - "up": {"uv": [0, 0, 16, 16], "texture": "#missing"}, - "down": {"uv": [0, 0, 16, 16], "texture": "#missing"} - } - } - ] -} \ No newline at end of file + "parent": "block/cube_all", + "textures": { + "all": "enderio:item/conduit_facade", + "particle": "enderio:item/conduit_facade" + } +} diff --git a/enderio-conduits/src/main/resources/assets/enderio/models/block/conduit_facade_overlay.json b/enderio-conduits/src/main/resources/assets/enderio/models/block/conduit_facade_overlay.json new file mode 100644 index 000000000..971e20efd --- /dev/null +++ b/enderio-conduits/src/main/resources/assets/enderio/models/block/conduit_facade_overlay.json @@ -0,0 +1,21 @@ +{ + "parent": "block/block", + "textures": { + "0": "enderio:block/conduit_facade_overlay", + "particle": "enderio:block/conduit_facade_overlay" + }, + "elements": [ + { + "from": [-0.01, -0.01, -0.01], + "to": [16.01, 16.01, 16.01], + "faces": { + "north": {"texture": "#0"}, + "east": {"texture": "#0"}, + "south": {"texture": "#0"}, + "west": {"texture": "#0"}, + "up": {"texture": "#0"}, + "down": {"texture": "#0"} + } + } + ] +} diff --git a/enderio-conduits/src/main/resources/assets/enderio/models/block/hardened_conduit_facade.json b/enderio-conduits/src/main/resources/assets/enderio/models/block/hardened_conduit_facade.json new file mode 100644 index 000000000..ad3c0e7de --- /dev/null +++ b/enderio-conduits/src/main/resources/assets/enderio/models/block/hardened_conduit_facade.json @@ -0,0 +1,7 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "enderio:item/conduit_facade_hardened", + "particle": "enderio:item/conduit_facade_hardened" + } +} diff --git a/enderio-conduits/src/main/resources/assets/enderio/models/block/transparent_conduit_facade.json b/enderio-conduits/src/main/resources/assets/enderio/models/block/transparent_conduit_facade.json new file mode 100644 index 000000000..1c76c2ba2 --- /dev/null +++ b/enderio-conduits/src/main/resources/assets/enderio/models/block/transparent_conduit_facade.json @@ -0,0 +1,7 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "enderio:item/conduit_facade_transparent", + "particle": "enderio:item/conduit_facade_transparent" + } +} diff --git a/enderio-conduits/src/main/resources/assets/enderio/models/block/transparent_hardened_conduit_facade.json b/enderio-conduits/src/main/resources/assets/enderio/models/block/transparent_hardened_conduit_facade.json new file mode 100644 index 000000000..0f7bc7834 --- /dev/null +++ b/enderio-conduits/src/main/resources/assets/enderio/models/block/transparent_hardened_conduit_facade.json @@ -0,0 +1,7 @@ +{ + "parent": "block/cube_all", + "textures": { + "all": "enderio:item/conduit_facade_transparent_hardened", + "particle": "enderio:item/conduit_facade_transparent_hardened" + } +} diff --git a/enderio-conduits/src/main/resources/assets/enderio/textures/block/conduit_facade_overlay.png b/enderio-conduits/src/main/resources/assets/enderio/textures/block/conduit_facade_overlay.png new file mode 100644 index 000000000..ff417ba9a Binary files /dev/null and b/enderio-conduits/src/main/resources/assets/enderio/textures/block/conduit_facade_overlay.png differ diff --git a/enderio-machines/src/generated/resources/assets/enderio/blockstates/vat.json b/enderio-machines/src/generated/resources/assets/enderio/blockstates/vat.json index 1c3e62e96..e9a85c9bb 100644 --- a/enderio-machines/src/generated/resources/assets/enderio/blockstates/vat.json +++ b/enderio-machines/src/generated/resources/assets/enderio/blockstates/vat.json @@ -1,17 +1,32 @@ { "variants": { - "facing=east": { + "facing=east,powered=false": { "model": "enderio:block/vat_combined", "y": 90 }, - "facing=north": { + "facing=east,powered=true": { + "model": "enderio:block/vat_combined", + "y": 90 + }, + "facing=north,powered=false": { "model": "enderio:block/vat_combined" }, - "facing=south": { + "facing=north,powered=true": { + "model": "enderio:block/vat_combined" + }, + "facing=south,powered=false": { "model": "enderio:block/vat_combined", "y": 180 }, - "facing=west": { + "facing=south,powered=true": { + "model": "enderio:block/vat_combined", + "y": 180 + }, + "facing=west,powered=false": { + "model": "enderio:block/vat_combined", + "y": 270 + }, + "facing=west,powered=true": { "model": "enderio:block/vat_combined", "y": 270 }