diff --git a/core/src/main/java/mrtjp/projectred/core/BundledSignalsLib.java b/core/src/main/java/mrtjp/projectred/core/BundledSignalsLib.java index 890a96978..0969fdd6a 100644 --- a/core/src/main/java/mrtjp/projectred/core/BundledSignalsLib.java +++ b/core/src/main/java/mrtjp/projectred/core/BundledSignalsLib.java @@ -139,6 +139,18 @@ public static void applyChangeMask(byte[] source, byte[] dest, int mask) { } } + public static int applyAndGetChangeMask(@Nullable byte[] source, byte[] dest) { + int mask = 0; + for (int i = 0; i < 16; i++) { + byte newVal = source == null ? 0 : source[i]; + if (dest[i] != newVal) { + dest[i] = newVal; + mask |= 1 << i; + } + } + return mask; + } + public static byte[] raiseSignal(@Nullable byte[] signal, @Nullable byte[] source) { if (signal == null) signal = new byte[16]; if (source == null) return signal; diff --git a/core/src/main/java/mrtjp/projectred/core/client/HaloRenderer.java b/core/src/main/java/mrtjp/projectred/core/client/HaloRenderer.java index 3b035d065..0669ca68d 100644 --- a/core/src/main/java/mrtjp/projectred/core/client/HaloRenderer.java +++ b/core/src/main/java/mrtjp/projectred/core/client/HaloRenderer.java @@ -102,13 +102,25 @@ public void onMovingPostRender() { //endregion //region World renderer - public static void addLight(BlockPos pos, int colour, Cuboid6 box) { - addLight(new Translation(pos), colour, box); + public static void addLight(BlockPos pos, Cuboid6 box, int colourIndex) { + addLight(new Translation(pos), box, colourIndex); } - public static void addLight(Transformation t, int colour, Cuboid6 box) { + public static void addLight(Transformation t, Cuboid6 box, int colourIndex) { Transformation t2 = new TransformationList(t, new Translation(offset)); - levelLights.add(new LevelLight(t2, colour, box)); + levelLights.add(new SingleColourLight(t2, box, colourIndex)); + if (Configurator.lightHaloMax > -1 && levelLights.size() > Configurator.lightHaloMax) { + levelLights.poll(); + } + } + + public static void addMultiLight(BlockPos pos, Cuboid6 box, byte[] alphas) { + addMultiLight(new Translation(pos), box, alphas); + } + + public static void addMultiLight(Transformation t, Cuboid6 box, byte[] alphas) { + Transformation t2 = new TransformationList(t, new Translation(offset)); + levelLights.add(new MultiLight(t2, box, alphas)); if (Configurator.lightHaloMax > -1 && levelLights.size() > Configurator.lightHaloMax) { levelLights.poll(); } @@ -153,19 +165,19 @@ public static void onRenderWorldStageEvent(final RenderLevelStageEvent event) { // Render to normal render target for primary visuals ccrs.bind(HALO_GLOW_RENDER_TYPE, buffers, stack); for (LevelLight light : lightList) { - renderToCCRS(ccrs, light.box, light.colour, light.t, HaloContext.LEVEL_RENDERER); + renderToCCRS(ccrs, light.box, light.t, light.getColour(HaloContext.LEVEL_RENDERER)); } // Update depth buffer ccrs.bind(HALO_FABULOUS_DEPTH_RENDER_TYPE, buffers, stack); for (LevelLight light : lightList) { - renderToCCRS(ccrs, light.box, light.colour, light.t, HaloContext.LEVEL_RENDERER); + renderToCCRS(ccrs, light.box, light.t, light.getColour(HaloContext.LEVEL_RENDERER)); } // Render to post chain for post-processing effects ccrs.bind(HALO_FABULOUS_BLOOM_RENDER_TYPE, buffers, stack); for (LevelLight light : lightList) { - renderToCCRS(ccrs, light.box, light.colour, light.t, HaloContext.BLOOM_RENDERER); + renderToCCRS(ccrs, light.box, light.t, light.getColour(HaloContext.LEVEL_RENDERER)); } postChainFlushPending = true; @@ -200,7 +212,7 @@ public static void onRenderWorldLastEvent(final RenderLevelLastEvent event) { // Render to normal render target for primary visuals ccrs.bind(HALO_GLOW_RENDER_TYPE, buffers, stack); for (LevelLight light : lightList) { - renderToCCRS(ccrs, light.box, light.colour, light.t, HaloContext.LEVEL_RENDERER); + renderToCCRS(ccrs, light.box, light.t, light.getColour(HaloContext.LEVEL_RENDERER)); } // Finish render @@ -255,24 +267,78 @@ private static boolean isFabulous() { //endregion //region Render functions - private static void renderToCCRS(CCRenderState ccrs, Cuboid6 cuboid, int colour, Transformation t, HaloContext context) { + private static void renderToCCRS(CCRenderState ccrs, Cuboid6 cuboid, Transformation t, int rgba) { ccrs.setPipeline(t); - ccrs.baseColour = getBaseColour(colour, context); + ccrs.baseColour = rgba; BlockRenderer.renderCuboid(ccrs, cuboid, 0); } - public static void renderInventoryHalo(CCRenderState ccrs, PoseStack mStack, MultiBufferSource buffers, Cuboid6 cuboid, int colour, Vector3 pos) { + public static void renderInventoryHalo(CCRenderState ccrs, PoseStack mStack, MultiBufferSource buffers, Cuboid6 cuboid, Vector3 pos, int colourIndex) { RenderType type = isFabulous() ? HALO_FABULOUS_ITEM_ENTITY_RENDER_TYPE : HALO_GLOW_RENDER_TYPE; ccrs.reset(); ccrs.bind(type, buffers, mStack); - renderToCCRS(ccrs, cuboid, colour, pos.translation(), HaloContext.ITEM_RENDERER); + renderToCCRS(ccrs, cuboid, pos.translation(), getBaseColour(colourIndex, HaloContext.ITEM_RENDERER)); + } + + public static void renderInventoryMultiHalo(CCRenderState ccrs, PoseStack mStack, MultiBufferSource buffers, Cuboid6 cuboid, Vector3 pos, byte[] alphas) { + RenderType type = isFabulous() ? HALO_FABULOUS_ITEM_ENTITY_RENDER_TYPE : HALO_GLOW_RENDER_TYPE; + ccrs.reset(); + ccrs.bind(type, buffers, mStack); + renderToCCRS(ccrs, cuboid, pos.translation(), getBlendedColour(alphas, HaloContext.ITEM_RENDERER)); } //endregion + //region Colour calculations private static int getBaseColour(int colorIndex, HaloContext context) { return LightColours.byIndex(colorIndex).rgbaByContext(context); } + /** + * Mix all 16 colours given input array of alpha values. Colours are additively blended + * using same calculations as GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA blending. + * + * @param alphas 16-element array of alpha values + * @return Blended colour (rgba) + */ + private static int getBlendedColour(byte[] alphas, HaloContext context) { + // Find the total alpha + int aTotal = 0; + int aMax = 0; + for (int i = 0; i < 16; i++) { + aTotal += alphas[i] & 0xFF; + aMax = Math.max(aMax, alphas[i] & 0xFF); + } + + if (aTotal == 0) { + return 0; + } + + // Normalize alpha values + float[] aNorm = new float[16]; + for (int i = 0; i < 16; i++) { + aNorm[i] = (alphas[i] & 0xFF) / (float) aTotal * aMax / 255f; + } + + float r = 0, g = 0, b = 0, a = 0; + for (int i = 0; i < 16; i++) { + if (alphas[i] == 0) continue; + + int colour = getBaseColour(i, context); + float rsrc = ((colour >> 24) & 0xFF) / 255f; + float gsrc = ((colour >> 16) & 0xFF) / 255f; + float bsrc = ((colour >> 8) & 0xFF) / 255f; + float asrc = aNorm[i]; + + r = rsrc * asrc + r * (1 - asrc); + g = gsrc * asrc + g * (1 - asrc); + b = bsrc * asrc + b * (1 - asrc); + a = asrc * asrc + a * (1 - asrc); + } + + // Note: Below alpha controls how halo renderer blends it into the render target, not alpha used to blend colours together + return (int) (r * 255) << 24 | (int) (g * 255) << 16 | (int) (b * 255) << 8 | 0xA0; + } + private enum HaloContext { ITEM_RENDERER, LEVEL_RENDERER, @@ -372,8 +438,48 @@ public static LightColours byIndex(int index) { return values()[index]; } } + //endregion + + private static abstract class LevelLight { + + public final Transformation t; + public final Cuboid6 box; + + public LevelLight(Transformation t, Cuboid6 box) { + this.t = t; + this.box = box; + } + + abstract int getColour(HaloContext context); + } + + private static class SingleColourLight extends LevelLight { + + private final int colourIndex; + + public SingleColourLight(Transformation t, Cuboid6 box, int colourIndex) { + super(t, box); + this.colourIndex = colourIndex; + } + + @Override + int getColour(HaloContext context) { + return getBaseColour(colourIndex, context); + } + } + + private static class MultiLight extends LevelLight { - private record LevelLight(Transformation t, int colour, Cuboid6 box) { + private final byte[] colourAlphas; + public MultiLight(Transformation t, Cuboid6 box, byte[] colourAlphas) { + super(t, box); + this.colourAlphas = colourAlphas; + } + + @Override + int getColour(HaloContext context) { + return getBlendedColour(colourAlphas, context); + } } } diff --git a/illumination/src/main/generated/.cache/2b7776bd503c0a3d6dc4b121fe385660c1c6dc19 b/illumination/src/main/generated/.cache/2b7776bd503c0a3d6dc4b121fe385660c1c6dc19 index 5bf4c7697..b3bca1420 100644 --- a/illumination/src/main/generated/.cache/2b7776bd503c0a3d6dc4b121fe385660c1c6dc19 +++ b/illumination/src/main/generated/.cache/2b7776bd503c0a3d6dc4b121fe385660c1c6dc19 @@ -1,4 +1,4 @@ -// 1.19.2 2024-03-05T10:08:22.223009 ProjectRed-Illumination Item Models +// 1.19.2 2024-05-06T17:00:08.454488 ProjectRed-Illumination Item Models a163c9ce1e63e428f3fa804b66e491b455f18540 assets/projectred_illumination/models/item/black_cage_light.json a163c9ce1e63e428f3fa804b66e491b455f18540 assets/projectred_illumination/models/item/black_fallout_light.json a163c9ce1e63e428f3fa804b66e491b455f18540 assets/projectred_illumination/models/item/black_fixture_light.json @@ -59,6 +59,7 @@ a163c9ce1e63e428f3fa804b66e491b455f18540 assets/projectred_illumination/models/i 3b57b1bd43ea0d8e0b5691177b1431a5c5b8e6fa assets/projectred_illumination/models/item/green_inverted_illumar_lamp.json a163c9ce1e63e428f3fa804b66e491b455f18540 assets/projectred_illumination/models/item/green_inverted_lantern.json a163c9ce1e63e428f3fa804b66e491b455f18540 assets/projectred_illumination/models/item/green_lantern.json +f08f45f7fd93ac70ed2e01d17acf536a88abe652 assets/projectred_illumination/models/item/illumar_smart_lamp.json a163c9ce1e63e428f3fa804b66e491b455f18540 assets/projectred_illumination/models/item/light_blue_cage_light.json a163c9ce1e63e428f3fa804b66e491b455f18540 assets/projectred_illumination/models/item/light_blue_fallout_light.json a163c9ce1e63e428f3fa804b66e491b455f18540 assets/projectred_illumination/models/item/light_blue_fixture_light.json diff --git a/illumination/src/main/generated/.cache/3c5437fdfe8bcc1d7d617f64e23b502caa42a0e1 b/illumination/src/main/generated/.cache/3c5437fdfe8bcc1d7d617f64e23b502caa42a0e1 index 76e83bade..2efacaa59 100644 --- a/illumination/src/main/generated/.cache/3c5437fdfe8bcc1d7d617f64e23b502caa42a0e1 +++ b/illumination/src/main/generated/.cache/3c5437fdfe8bcc1d7d617f64e23b502caa42a0e1 @@ -1,4 +1,4 @@ -// 1.19.2 2024-03-05T10:08:22.240051 ProjectRed-Illumination Recipes +// 1.19.2 2024-05-08T21:36:25.799111 ProjectRed-Illumination Recipes bab0e0ace8eafa4f132dd7aa9ea77ce3743620f1 data/projectred_illumination/recipes/black_cage_light.json 7346715a74ba4257b555898569b21950b6c69747 data/projectred_illumination/recipes/black_fallout_light.json 408cec0af00793db8e5895042fe84e4120c17b33 data/projectred_illumination/recipes/black_fixture_light.json @@ -59,6 +59,7 @@ bd0ba40afb2e62423d4e81e30adba54004eb2483 data/projectred_illumination/recipes/gr 6afac6792ea3525e6a20140fec5038fcf60066ce data/projectred_illumination/recipes/green_inverted_illumar_lamp.json 3cbcf89e8fca3b497f11a8b47f3e169b5559e1f9 data/projectred_illumination/recipes/green_inverted_lantern.json c849335acf420adbd919fd18bf0828690eabba30 data/projectred_illumination/recipes/green_lantern.json +4186608e2b704efdf4cb473b603a5cca3623617a data/projectred_illumination/recipes/illumar_smart_lamp.json 343c00444ba713d21c9d7800377363b528676b1f data/projectred_illumination/recipes/light_blue_cage_light.json 250e310dadd501be6ab7a84d0f3204fb5200eda2 data/projectred_illumination/recipes/light_blue_fallout_light.json c1be8144957ba247e87114e8473c6e4f34557d04 data/projectred_illumination/recipes/light_blue_fixture_light.json diff --git a/illumination/src/main/generated/.cache/73585f9635c75d62bca484a7ea9ba4b7d3c67a68 b/illumination/src/main/generated/.cache/73585f9635c75d62bca484a7ea9ba4b7d3c67a68 index e33084706..a7f9bd843 100644 --- a/illumination/src/main/generated/.cache/73585f9635c75d62bca484a7ea9ba4b7d3c67a68 +++ b/illumination/src/main/generated/.cache/73585f9635c75d62bca484a7ea9ba4b7d3c67a68 @@ -1,4 +1,4 @@ -// 1.19.2 2024-03-05T10:08:22.239755 ProjectRed-Illumination Block Loot Tables +// 1.19.2 2024-05-08T16:20:21.395168 ProjectRed-Illumination Block Loot Tables ca2aba13d5b4bcbedec5753a41db442358432327 data/projectred_illumination/loot_tables/blocks/black_illumar_lamp.json 6f70dd57e208bacc8c06e451db975c57cfa5a3a6 data/projectred_illumination/loot_tables/blocks/black_inverted_illumar_lamp.json df6b2b1652062f4dbcabe57c04201f9c03b655ca data/projectred_illumination/loot_tables/blocks/blue_illumar_lamp.json @@ -11,6 +11,7 @@ bf9d87f4ec56c5a82548eca928f2a00e2f47048b data/projectred_illumination/loot_table c7d386cf69bfcf351d594c19416129dcdb92a50c data/projectred_illumination/loot_tables/blocks/gray_inverted_illumar_lamp.json 93ce38abe30aa4f1d205453c89f750226d037031 data/projectred_illumination/loot_tables/blocks/green_illumar_lamp.json 44bca255835e3cd52a14a0d7ae64ca5c2af0f794 data/projectred_illumination/loot_tables/blocks/green_inverted_illumar_lamp.json +02a0f482e29ef8f4f2f4e4e36592d07d2af1332e data/projectred_illumination/loot_tables/blocks/illumar_smart_lamp.json 2cf051942144dd90ce174df0886e0c693bd603ad data/projectred_illumination/loot_tables/blocks/light_blue_illumar_lamp.json f2802e525768f1e0f7dc0f7726b2ee283dff792e data/projectred_illumination/loot_tables/blocks/light_blue_inverted_illumar_lamp.json dcc7947bad8775d1ff68dc0c0d20b06ab6b902fd data/projectred_illumination/loot_tables/blocks/light_gray_illumar_lamp.json diff --git a/illumination/src/main/generated/.cache/be1ef78e8a7cc1ad66607d87653d2e29da533af1 b/illumination/src/main/generated/.cache/be1ef78e8a7cc1ad66607d87653d2e29da533af1 index c50793f46..bfe3f5a8d 100644 --- a/illumination/src/main/generated/.cache/be1ef78e8a7cc1ad66607d87653d2e29da533af1 +++ b/illumination/src/main/generated/.cache/be1ef78e8a7cc1ad66607d87653d2e29da533af1 @@ -1,4 +1,4 @@ -// 1.19.2 2024-03-05T10:08:22.238879 ProjectRed-Illumination Block Models +// 1.19.2 2024-05-07T15:02:14.42821 ProjectRed-Illumination Block Models 0746294f4d3dd435feb6f198d7131a6fe4be71fa assets/projectred_illumination/blockstates/black_illumar_lamp.json 0746294f4d3dd435feb6f198d7131a6fe4be71fa assets/projectred_illumination/blockstates/black_inverted_illumar_lamp.json 14312633b8d330d240fa130218c89f36a16579c1 assets/projectred_illumination/blockstates/blue_illumar_lamp.json @@ -11,6 +11,7 @@ eccf141f058ae9adb65b77fd11c82ccbc44e5108 assets/projectred_illumination/blocksta eccf141f058ae9adb65b77fd11c82ccbc44e5108 assets/projectred_illumination/blockstates/gray_inverted_illumar_lamp.json d49ec0eee75ebf8b26b19bd7947521c052fab378 assets/projectred_illumination/blockstates/green_illumar_lamp.json d49ec0eee75ebf8b26b19bd7947521c052fab378 assets/projectred_illumination/blockstates/green_inverted_illumar_lamp.json +d6ebdb5e8eadaba44c9200e53c4982b04dd77359 assets/projectred_illumination/blockstates/illumar_smart_lamp.json 3c01dccff2ba9c4e93ed0fc989f5b93af0edc1ad assets/projectred_illumination/blockstates/light_blue_illumar_lamp.json 3c01dccff2ba9c4e93ed0fc989f5b93af0edc1ad assets/projectred_illumination/blockstates/light_blue_inverted_illumar_lamp.json e31dd0781aa8551edcdad8f3d0f51d02f69ae9d5 assets/projectred_illumination/blockstates/light_gray_illumar_lamp.json @@ -43,6 +44,8 @@ f81f1a943995009a435634ce66184a37b91142ef assets/projectred_illumination/models/b b74a5d560b10ff6da6302100aa2a3576859567e8 assets/projectred_illumination/models/block/gray_illumar_lamp_on.json c2ea0630753528faa979169f4896680edd444740 assets/projectred_illumination/models/block/green_illumar_lamp.json f8618a27bdb622b34d2159a0971a1ecc82eb7830 assets/projectred_illumination/models/block/green_illumar_lamp_on.json +a10bc3eccc0d66e962e91821236deadc48cff693 assets/projectred_illumination/models/block/illumar_smart_lamp.json +ef2683c5a198564370912026bb7d58ee36cdbf2f assets/projectred_illumination/models/block/illumar_smart_lamp_on.json 05aa22099bae4f9fa31127b214f3ce3aa62e36ee assets/projectred_illumination/models/block/light_blue_illumar_lamp.json a7d29aab07598cbd6028e141475541aabcd62979 assets/projectred_illumination/models/block/light_blue_illumar_lamp_on.json 672ed59c46c3acc2baf1825ec0696da87620c095 assets/projectred_illumination/models/block/light_gray_illumar_lamp.json diff --git a/illumination/src/main/generated/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 b/illumination/src/main/generated/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 index 3930de9b5..59e524781 100644 --- a/illumination/src/main/generated/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 +++ b/illumination/src/main/generated/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 @@ -1,2 +1,2 @@ -// 1.19.2 2024-03-05T10:08:22.238073 Languages: en_us -548cfaf60e6a16b400fd90c0cc5da98891f425cf assets/projectred_illumination/lang/en_us.json +// 1.19.2 2024-05-07T15:11:08.498971 Languages: en_us +bd4c754665d90437f9a3014a701298a4082d18cc assets/projectred_illumination/lang/en_us.json diff --git a/illumination/src/main/generated/assets/projectred_illumination/blockstates/illumar_smart_lamp.json b/illumination/src/main/generated/assets/projectred_illumination/blockstates/illumar_smart_lamp.json new file mode 100644 index 000000000..66b0174ea --- /dev/null +++ b/illumination/src/main/generated/assets/projectred_illumination/blockstates/illumar_smart_lamp.json @@ -0,0 +1,436 @@ +{ + "variants": { + "level=0,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp" + }, + "level=0,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp", + "x": 180, + "y": 180 + }, + "level=0,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp", + "x": 90, + "y": 180 + }, + "level=0,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp", + "x": 90 + }, + "level=0,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp", + "x": 90, + "y": 90 + }, + "level=0,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp", + "x": 90, + "y": 270 + }, + "level=1,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=1,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=1,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=1,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=1,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=1,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=10,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=10,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=10,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=10,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=10,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=10,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=11,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=11,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=11,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=11,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=11,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=11,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=12,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=12,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=12,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=12,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=12,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=12,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=13,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=13,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=13,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=13,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=13,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=13,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=14,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=14,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=14,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=14,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=14,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=14,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=15,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=15,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=15,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=15,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=15,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=15,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=2,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=2,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=2,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=2,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=2,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=2,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=3,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=3,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=3,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=3,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=3,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=3,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=4,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=4,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=4,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=4,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=4,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=4,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=5,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=5,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=5,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=5,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=5,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=5,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=6,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=6,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=6,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=6,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=6,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=6,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=7,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=7,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=7,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=7,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=7,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=7,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=8,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=8,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=8,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=8,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=8,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=8,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + }, + "level=9,side=0": { + "model": "projectred_illumination:block/illumar_smart_lamp_on" + }, + "level=9,side=1": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 180, + "y": 180 + }, + "level=9,side=2": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 180 + }, + "level=9,side=3": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90 + }, + "level=9,side=4": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 90 + }, + "level=9,side=5": { + "model": "projectred_illumination:block/illumar_smart_lamp_on", + "x": 90, + "y": 270 + } + } +} \ No newline at end of file diff --git a/illumination/src/main/generated/assets/projectred_illumination/lang/en_us.json b/illumination/src/main/generated/assets/projectred_illumination/lang/en_us.json index 415889ea8..b28b44184 100644 --- a/illumination/src/main/generated/assets/projectred_illumination/lang/en_us.json +++ b/illumination/src/main/generated/assets/projectred_illumination/lang/en_us.json @@ -11,6 +11,7 @@ "block.projectred_illumination.gray_inverted_illumar_lamp": "Gray Inverted Illumar Lamp", "block.projectred_illumination.green_illumar_lamp": "Green Illumar Lamp", "block.projectred_illumination.green_inverted_illumar_lamp": "Green Inverted Illumar Lamp", + "block.projectred_illumination.illumar_smart_lamp": "Illumar Smart Lamp", "block.projectred_illumination.light_blue_illumar_lamp": "Light Blue Illumar Lamp", "block.projectred_illumination.light_blue_inverted_illumar_lamp": "Light Blue Inverted Illumar Lamp", "block.projectred_illumination.light_gray_illumar_lamp": "Light Gray Illumar Lamp", diff --git a/illumination/src/main/generated/assets/projectred_illumination/models/block/illumar_smart_lamp.json b/illumination/src/main/generated/assets/projectred_illumination/models/block/illumar_smart_lamp.json new file mode 100644 index 000000000..0ec35f1bb --- /dev/null +++ b/illumination/src/main/generated/assets/projectred_illumination/models/block/illumar_smart_lamp.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "bottom": "projectred_illumination:block/illumar_smart_lamp_bottom", + "side": "projectred_illumination:block/illumar_smart_lamp_side", + "top": "projectred_illumination:block/illumar_smart_lamp_top" + } +} \ No newline at end of file diff --git a/illumination/src/main/generated/assets/projectred_illumination/models/block/illumar_smart_lamp_on.json b/illumination/src/main/generated/assets/projectred_illumination/models/block/illumar_smart_lamp_on.json new file mode 100644 index 000000000..303a310ca --- /dev/null +++ b/illumination/src/main/generated/assets/projectred_illumination/models/block/illumar_smart_lamp_on.json @@ -0,0 +1,8 @@ +{ + "parent": "minecraft:block/cube_bottom_top", + "textures": { + "bottom": "projectred_illumination:block/illumar_smart_lamp_bottom", + "side": "projectred_illumination:block/illumar_smart_lamp_side_on", + "top": "projectred_illumination:block/illumar_smart_lamp_top_on" + } +} \ No newline at end of file diff --git a/illumination/src/main/generated/assets/projectred_illumination/models/item/illumar_smart_lamp.json b/illumination/src/main/generated/assets/projectred_illumination/models/item/illumar_smart_lamp.json new file mode 100644 index 000000000..319ef8b07 --- /dev/null +++ b/illumination/src/main/generated/assets/projectred_illumination/models/item/illumar_smart_lamp.json @@ -0,0 +1,3 @@ +{ + "parent": "projectred_illumination:block/illumar_smart_lamp" +} \ No newline at end of file diff --git a/illumination/src/main/generated/data/projectred_illumination/loot_tables/blocks/illumar_smart_lamp.json b/illumination/src/main/generated/data/projectred_illumination/loot_tables/blocks/illumar_smart_lamp.json new file mode 100644 index 000000000..811308658 --- /dev/null +++ b/illumination/src/main/generated/data/projectred_illumination/loot_tables/blocks/illumar_smart_lamp.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "entries": [ + { + "type": "minecraft:item", + "name": "projectred_illumination:illumar_smart_lamp" + } + ], + "rolls": 1.0 + } + ] +} \ No newline at end of file diff --git a/illumination/src/main/generated/data/projectred_illumination/recipes/illumar_smart_lamp.json b/illumination/src/main/generated/data/projectred_illumination/recipes/illumar_smart_lamp.json new file mode 100644 index 000000000..7b6abf625 --- /dev/null +++ b/illumination/src/main/generated/data/projectred_illumination/recipes/illumar_smart_lamp.json @@ -0,0 +1,28 @@ +{ + "type": "minecraft:crafting_shaped", + "key": { + "B": { + "item": "projectred_core:blue_illumar" + }, + "C": { + "item": "projectred_core:bundled_plate" + }, + "G": { + "item": "projectred_core:green_illumar" + }, + "P": { + "tag": "forge:glass_panes/colorless" + }, + "R": { + "item": "projectred_core:red_illumar" + } + }, + "pattern": [ + "PRP", + "PGP", + "CBC" + ], + "result": { + "item": "projectred_illumination:illumar_smart_lamp" + } +} \ No newline at end of file diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/MultipartLightProperties.java b/illumination/src/main/java/mrtjp/projectred/illumination/MultipartLightProperties.java index b4150dd97..751c5c858 100644 --- a/illumination/src/main/java/mrtjp/projectred/illumination/MultipartLightProperties.java +++ b/illumination/src/main/java/mrtjp/projectred/illumination/MultipartLightProperties.java @@ -115,7 +115,7 @@ public void renderItem(ItemStack stack, ItemTransforms.TransformType transformTy renderInventory(lightItem.getColor(), lightItem.isInverted(), Vector3.ZERO, ccrs); if (lightItem.isInverted()) { - HaloRenderer.renderInventoryHalo(ccrs, mStack, getter, getInventoryGlowBounds(), lightItem.getColor(), Vector3.ZERO); + HaloRenderer.renderInventoryHalo(ccrs, mStack, getter, getInventoryGlowBounds(), Vector3.ZERO, lightItem.getColor()); } } diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/ProjectRedIllumination.java b/illumination/src/main/java/mrtjp/projectred/illumination/ProjectRedIllumination.java index cf66496ad..6399763fa 100644 --- a/illumination/src/main/java/mrtjp/projectred/illumination/ProjectRedIllumination.java +++ b/illumination/src/main/java/mrtjp/projectred/illumination/ProjectRedIllumination.java @@ -23,6 +23,8 @@ import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import static mrtjp.projectred.illumination.ProjectRedIllumination.MOD_ID; @@ -31,6 +33,8 @@ public class ProjectRedIllumination { public static final String MOD_ID = "projectred_illumination"; + public static final Logger LOGGER = LogManager.getLogger(MOD_ID); + public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MOD_ID); public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MOD_ID); public static final DeferredRegister> BLOCK_ENTITY_TYPES = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, MOD_ID); diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/block/IllumarSmartLampBlock.java b/illumination/src/main/java/mrtjp/projectred/illumination/block/IllumarSmartLampBlock.java new file mode 100644 index 000000000..cc1e721a7 --- /dev/null +++ b/illumination/src/main/java/mrtjp/projectred/illumination/block/IllumarSmartLampBlock.java @@ -0,0 +1,55 @@ +package mrtjp.projectred.illumination.block; + +import mrtjp.projectred.core.block.ProjectRedBlock; +import mrtjp.projectred.illumination.init.IlluminationBlocks; +import mrtjp.projectred.illumination.tile.IllumarSmartLampBlockEntity; +import net.minecraft.core.BlockPos; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.EntityBlock; +import net.minecraft.world.level.block.LightBlock; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import net.minecraft.world.level.material.Material; +import org.jetbrains.annotations.Nullable; + +import java.util.function.ToIntFunction; + +public class IllumarSmartLampBlock extends ProjectRedBlock implements EntityBlock { + + public static final IntegerProperty LEVEL = LightBlock.LEVEL; + public static final ToIntFunction LIGHT_EMISSION = LightBlock.LIGHT_EMISSION; + + public IllumarSmartLampBlock() { + super(BlockBehaviour.Properties.of(Material.BUILDABLE_GLASS) + .strength(0.5F) + .lightLevel(LIGHT_EMISSION)); + + this.registerDefaultState(this.stateDefinition.any().setValue(LEVEL, 0)); + } + + protected void createBlockStateDefinition(StateDefinition.Builder pBuilder) { + pBuilder.add(LEVEL).add(ProjectRedBlock.SIDE); + } + + @Nullable + @Override + public BlockState getStateForPlacement(BlockPlaceContext pContext) { + return defaultBlockState().setValue(LEVEL, 0); + } + + @Override + protected BlockEntityType getBlockEntityType() { + return IlluminationBlocks.ILLUMAR_SMART_LAMP_BLOCK_ENTITY.get(); + } + + @Nullable + @Override + public BlockEntity newBlockEntity(BlockPos pPos, BlockState pState) { + return new IllumarSmartLampBlockEntity(pPos, pState); + } +} diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarLampItemRenderer.java b/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarLampItemRenderer.java index 1bca0b01b..d0c80eeac 100644 --- a/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarLampItemRenderer.java +++ b/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarLampItemRenderer.java @@ -17,17 +17,13 @@ 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.client.resources.model.ModelState; import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.levelgen.RandomState; import org.jetbrains.annotations.Nullable; -import java.util.Random; - public class IllumarLampItemRenderer extends WrappedItemModel implements IItemRenderer { private static final Cuboid6 BLOCK_BOUNDS = Cuboid6.full.copy().expand(-0.02D); @@ -69,7 +65,7 @@ public void renderItem(ItemStack stack, ItemTransforms.TransformType transformTy BlockRenderer.renderCuboid(ccrs, BLOCK_BOUNDS, 0); // Render halo - HaloRenderer.renderInventoryHalo(ccrs, mStack, getter, GLOW_BOUNDS, block.getColor(), Vector3.ZERO); + HaloRenderer.renderInventoryHalo(ccrs, mStack, getter, GLOW_BOUNDS, Vector3.ZERO, block.getColor()); } @Override diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarLampTileRenderer.java b/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarLampTileRenderer.java index b42de872a..7e1f3c82f 100644 --- a/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarLampTileRenderer.java +++ b/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarLampTileRenderer.java @@ -24,7 +24,7 @@ public void render(IllumarLampTile tile, float partialTicks, PoseStack matrixSta if (tile.getLevel() != null) { BlockState state = tile.getLevel().getBlockState(tile.getBlockPos()); if (state.getBlock() instanceof IllumarLampBlock && tile.isLit()) { - HaloRenderer.addLight(tile.getBlockPos(), tile.color, GLOW_BOUNDS); + HaloRenderer.addLight(tile.getBlockPos(), GLOW_BOUNDS, tile.color); } } } diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarSmartLampBlockEntityRenderer.java b/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarSmartLampBlockEntityRenderer.java new file mode 100644 index 000000000..85cc03036 --- /dev/null +++ b/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarSmartLampBlockEntityRenderer.java @@ -0,0 +1,30 @@ +package mrtjp.projectred.illumination.client; + +import codechicken.lib.vec.Cuboid6; +import com.mojang.blaze3d.vertex.PoseStack; +import mrtjp.projectred.core.BundledSignalsLib; +import mrtjp.projectred.core.client.HaloRenderer; +import mrtjp.projectred.illumination.tile.IllumarSmartLampBlockEntity; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; + +public class IllumarSmartLampBlockEntityRenderer implements BlockEntityRenderer { + + public static final IllumarSmartLampBlockEntityRenderer INSTANCE = new IllumarSmartLampBlockEntityRenderer(); + + public static final Cuboid6 GLOW_BOUNDS = Cuboid6.full.copy().expand(0.05D); + + @Override + public void render(IllumarSmartLampBlockEntity tile, float pPartialTick, PoseStack pPoseStack, MultiBufferSource pBufferSource, int pPackedLight, int pPackedOverlay) { + + byte[] signal = tile.getSignal(); + if (!BundledSignalsLib.isSignalZero(signal)) { + HaloRenderer.addMultiLight(tile.getBlockPos(), GLOW_BOUNDS, tile.getSignal()); + } + } + + @Override + public int getViewDistance() { + return 256; + } +} diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarSmartLampItemRenderer.java b/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarSmartLampItemRenderer.java new file mode 100644 index 000000000..7789dbff8 --- /dev/null +++ b/illumination/src/main/java/mrtjp/projectred/illumination/client/IllumarSmartLampItemRenderer.java @@ -0,0 +1,117 @@ +package mrtjp.projectred.illumination.client; + +import codechicken.lib.model.PerspectiveModelState; +import codechicken.lib.model.bakedmodels.WrappedItemModel; +import codechicken.lib.render.BlockRenderer; +import codechicken.lib.render.CCRenderState; +import codechicken.lib.render.item.IItemRenderer; +import codechicken.lib.util.TransformUtils; +import codechicken.lib.vec.Cuboid6; +import codechicken.lib.vec.Vector3; +import codechicken.lib.vec.uv.MultiIconTransformation; +import com.mojang.blaze3d.vertex.PoseStack; +import mrtjp.projectred.core.client.HaloRenderer; +import mrtjp.projectred.illumination.block.IllumarSmartLampBlock; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +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.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.Nullable; + +public class IllumarSmartLampItemRenderer extends WrappedItemModel implements IItemRenderer { + + private static final Cuboid6 BLOCK_BOUNDS = Cuboid6.full.copy().expand(-0.02D); + private static final Cuboid6 GLOW_BOUNDS = Cuboid6.full.copy().expand(0.02D); + private static final RandomSource random = RandomSource.create(); + + private final byte[] signal = new byte[16]; + private long lastSignalAnimateTime = -1L; + + public IllumarSmartLampItemRenderer(BakedModel wrapped) { + super(wrapped); + } + + @Override + public void renderItem(ItemStack stack, ItemTransforms.TransformType transformType, PoseStack mStack, MultiBufferSource getter, int packedLight, int packedOverlay) { + Item item = stack.getItem(); + if (!(item instanceof BlockItem blockItem)) return; + + if (!(blockItem.getBlock() instanceof IllumarSmartLampBlock block)) return; + + // Render actual block. Required because renderWrapped does not play nice with + // halo rendering. Halo completely obscures wrapped render. + + // Obtain texture from original block model + TextureAtlasSprite[] icons = new TextureAtlasSprite[6]; + for (Direction dir : Direction.values()) { + icons[dir.get3DDataValue()] = wrapped.getQuads(null, dir, random).get(0).getSprite(); + } + MultiIconTransformation iconT = new MultiIconTransformation(icons); + + + // Render block + CCRenderState ccrs = CCRenderState.instance(); + ccrs.reset(); + ccrs.brightness = packedLight; + ccrs.overlay = packedOverlay; + ccrs.bind(RenderType.cutout(), getter, mStack); + + ccrs.setPipeline(iconT); + BlockRenderer.renderCuboid(ccrs, BLOCK_BOUNDS, 0); + + // Animate signals + animateSignal(); + + // Render halo + HaloRenderer.renderInventoryMultiHalo(ccrs, mStack, getter, GLOW_BOUNDS, Vector3.ZERO, signal); + } + + private void animateSignal() { + + Level level = Minecraft.getInstance().level; + long time = level != null ? level.getGameTime() : System.currentTimeMillis() / 50L; // approximate time progression if no level + + // Only do this once per tick + if (time == lastSignalAnimateTime) return; + lastSignalAnimateTime = time; + + // Sine-wave animation + double t = (Math.sin(time / 200.0) + 1.0) / 2.0 * 15.0; // Sine wave with bounds [0, 15] + double d = 1.5; // Max distance (max active colours / 2) + + for (int i = 0; i < 16; i++) { + double diff = Math.min(Math.abs(t - i), d); + double brightness = 1.0 - diff / d; + signal[i] = (byte) (255 * brightness); + } + } + + @Override + public @Nullable PerspectiveModelState getModelState() { + return TransformUtils.DEFAULT_BLOCK; + } + + @Override + public boolean useAmbientOcclusion() { + return true; + } + + @Override + public boolean isGui3d() { + return true; + } + + @Override + public boolean usesBlockLight() { + return true; + } + +} diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/client/MultipartLightPartRenderer.java b/illumination/src/main/java/mrtjp/projectred/illumination/client/MultipartLightPartRenderer.java index 9386e033c..4d530e4f4 100644 --- a/illumination/src/main/java/mrtjp/projectred/illumination/client/MultipartLightPartRenderer.java +++ b/illumination/src/main/java/mrtjp/projectred/illumination/client/MultipartLightPartRenderer.java @@ -28,6 +28,6 @@ public void renderStatic(MultipartLightPart part, @Nullable RenderType layer, CC @Override public void renderDynamic(MultipartLightPart part, PoseStack pStack, MultiBufferSource buffers, int packedLight, int packedOverlay, float partialTicks) { if (part.isLightOn()) - HaloRenderer.addLight(part.pos(), part.getColor(), part.getProperties().getGlowBounds(part.getSide())); + HaloRenderer.addLight(part.pos(), part.getProperties().getGlowBounds(part.getSide()), part.getColor()); } } diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationBlockLootProvider.java b/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationBlockLootProvider.java index 6b6c73f76..a8f9c46c6 100644 --- a/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationBlockLootProvider.java +++ b/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationBlockLootProvider.java @@ -4,6 +4,8 @@ import mrtjp.projectred.illumination.BlockLightType; import net.minecraft.data.DataGenerator; +import static mrtjp.projectred.illumination.init.IlluminationBlocks.ILLUMAR_SMART_LAMP; + public class IlluminationBlockLootProvider extends LootTableProvider.BlockLootProvider { public IlluminationBlockLootProvider(DataGenerator dataGenerator) { @@ -23,5 +25,7 @@ protected void registerTables() { register(lampType.getBlock(color, true), singleItem(lampType.getBlock(color, true))); } } + + register(ILLUMAR_SMART_LAMP.get(), singleItem(ILLUMAR_SMART_LAMP.get())); } } diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationBlockStateModelProvider.java b/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationBlockStateModelProvider.java index b6035bdf1..680fab056 100644 --- a/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationBlockStateModelProvider.java +++ b/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationBlockStateModelProvider.java @@ -1,19 +1,28 @@ package mrtjp.projectred.illumination.data; +import mrtjp.projectred.core.block.ProjectRedBlock; import mrtjp.projectred.illumination.BlockLightType; import mrtjp.projectred.illumination.ProjectRedIllumination; import mrtjp.projectred.illumination.block.IllumarLampBlock; +import mrtjp.projectred.illumination.block.IllumarSmartLampBlock; import net.minecraft.data.DataGenerator; import net.minecraft.world.level.block.Block; import net.minecraftforge.client.model.generators.BlockModelBuilder; import net.minecraftforge.client.model.generators.BlockStateProvider; import net.minecraftforge.client.model.generators.ConfiguredModel; +import net.minecraftforge.client.model.generators.ModelFile; import net.minecraftforge.common.data.ExistingFileHelper; +import net.minecraftforge.registries.ForgeRegistries; import javax.annotation.Nonnull; +import static mrtjp.projectred.illumination.init.IlluminationBlocks.ILLUMAR_SMART_LAMP; + public class IlluminationBlockStateModelProvider extends BlockStateProvider { + // XY rotations for non-rotatable sided devices + private static final int[][] DEVICE_SIDED_ROTATIONS = { {0, 0}, {2, 2}, {1, 2}, {1, 0}, {1, 1}, {1, 3} }; + public IlluminationBlockStateModelProvider(DataGenerator gen, ExistingFileHelper exFileHelper) { super(gen, ProjectRedIllumination.MOD_ID, exFileHelper); } @@ -31,6 +40,10 @@ protected void registerStatesAndModels() { addIllumarLampVariants(lampType.getBlock(color, false)); } } + + addSidedBlockVariants(ILLUMAR_SMART_LAMP.get(), + createSmartLampModel(ILLUMAR_SMART_LAMP.get(), false), + createSmartLampModel(ILLUMAR_SMART_LAMP.get(), true)); } private void addIllumarLampVariants(Block block) { @@ -43,4 +56,27 @@ private BlockModelBuilder createLampModel(Block block, boolean lit) { String textureName = BlockLightType.ILLUMAR_LAMP.getRegistryID(((IllumarLampBlock) block).getColor(), false) + (lit ? "_on" : ""); // Always use non-inverted unlocal name for textures return models().cubeAll(textureName, modLoc("block/" + textureName)); } + + private void addSidedBlockVariants(Block block, ModelFile offModel, ModelFile onModel) { + getVariantBuilder(block).forAllStates(state -> { + int s = state.getValue(ProjectRedBlock.SIDE); + boolean lit = state.getValue(IllumarSmartLampBlock.LEVEL) > 0; + + return ConfiguredModel.builder() + .modelFile(lit ? onModel : offModel) + .rotationX(DEVICE_SIDED_ROTATIONS[s][0] * 90) + .rotationY(DEVICE_SIDED_ROTATIONS[s][1] * 90) + .build(); + }); + } + + private BlockModelBuilder createSmartLampModel(Block block, boolean lit) { + String texture = ForgeRegistries.BLOCKS.getKey(block).getPath(); + String litKey = lit ? "_on" : ""; + String modelName = texture + litKey; + return models().cubeBottomTop(modelName, + modLoc("block/" + texture + "_side" + litKey), + modLoc("block/" + texture + "_bottom"), + modLoc("block/" + texture + "_top" + litKey)); + } } diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationItemModelProvider.java b/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationItemModelProvider.java index 28fd15e5c..94bc6fb6d 100644 --- a/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationItemModelProvider.java +++ b/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationItemModelProvider.java @@ -8,6 +8,7 @@ import net.minecraftforge.common.data.ExistingFileHelper; import static mrtjp.projectred.illumination.ProjectRedIllumination.MOD_ID; +import static mrtjp.projectred.illumination.init.IlluminationBlocks.ILLUMAR_SMART_LAMP; public class IlluminationItemModelProvider extends ItemModelProvider { @@ -33,6 +34,8 @@ protected void registerModels() { } } + simpleItemBlock(ILLUMAR_SMART_LAMP.get()); + for (MultipartLightType type : MultipartLightType.values()) { for (int color = 0; color < 16; color++) { generated(type.getItem(color, false)).noTexture(); diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationLanguageProvider.java b/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationLanguageProvider.java index 11aef80ea..66f55c56b 100644 --- a/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationLanguageProvider.java +++ b/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationLanguageProvider.java @@ -6,6 +6,7 @@ import net.minecraftforge.common.data.LanguageProvider; import static mrtjp.projectred.illumination.ProjectRedIllumination.MOD_ID; +import static mrtjp.projectred.illumination.init.IlluminationBlocks.ILLUMAR_SMART_LAMP; public class IlluminationLanguageProvider extends LanguageProvider { @@ -31,6 +32,9 @@ protected void addTranslations() { } } + // Illumar smart lamp + addBlock(ILLUMAR_SMART_LAMP, "Illumar Smart Lamp"); + // Multipart lights for (MultipartLightType type : MultipartLightType.values()) { for (int color = 0; color < 16; color++) { diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationRecipeProvider.java b/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationRecipeProvider.java index b7233a8e9..938a49940 100644 --- a/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationRecipeProvider.java +++ b/illumination/src/main/java/mrtjp/projectred/illumination/data/IlluminationRecipeProvider.java @@ -9,6 +9,7 @@ import net.minecraftforge.common.Tags; import static mrtjp.projectred.core.init.CoreItems.*; +import static mrtjp.projectred.illumination.init.IlluminationBlocks.ILLUMAR_SMART_LAMP; public class IlluminationRecipeProvider extends RecipeProvider { @@ -43,6 +44,17 @@ protected void registerRecipes() { .patternLine("GRG"); } + //Smart lamp + shapedRecipe(ILLUMAR_SMART_LAMP.get(), 1) + .key('P', Tags.Items.GLASS_PANES_COLORLESS) + .key('C', BUNDLED_PLATE_ITEM.get()) + .key('R', RED_ILLUMAR_ITEM.get()) + .key('G', GREEN_ILLUMAR_ITEM.get()) + .key('B', BLUE_ILLUMAR_ITEM.get()) + .patternLine("PRP") + .patternLine("PGP") + .patternLine("CBC"); + //Lanterns for (int c = 0; c < 16; c++) { shapedRecipe(MultipartLightType.LANTERN.getItem(c, false), 1) diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/init/IlluminationBlocks.java b/illumination/src/main/java/mrtjp/projectred/illumination/init/IlluminationBlocks.java index 76ca0448a..dc8e2f82c 100644 --- a/illumination/src/main/java/mrtjp/projectred/illumination/init/IlluminationBlocks.java +++ b/illumination/src/main/java/mrtjp/projectred/illumination/init/IlluminationBlocks.java @@ -1,16 +1,42 @@ package mrtjp.projectred.illumination.init; import mrtjp.projectred.illumination.BlockLightType; +import mrtjp.projectred.illumination.block.IllumarSmartLampBlock; +import mrtjp.projectred.illumination.tile.IllumarSmartLampBlockEntity; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.entity.BlockEntityType; +import net.minecraftforge.registries.RegistryObject; import static mrtjp.projectred.illumination.ProjectRedIllumination.*; +@SuppressWarnings({ "DataFlowIssue", "NotNullFieldNotInitialized" }) public class IlluminationBlocks { + public static final String ID_ILLUMAR_SMART_LAMP = "illumar_smart_lamp"; + + // Blocks + public static RegistryObject ILLUMAR_SMART_LAMP; + + // Block Entities + public static RegistryObject> ILLUMAR_SMART_LAMP_BLOCK_ENTITY; + + public static void register() { // Block lights for (BlockLightType lampType : BlockLightType.values()) { lampType.registerBlocks(BLOCKS, ITEMS, BLOCK_ENTITY_TYPES); } + + // Blocks + ILLUMAR_SMART_LAMP = BLOCKS.register(ID_ILLUMAR_SMART_LAMP, IllumarSmartLampBlock::new); + + // Block Items + ITEMS.register(ID_ILLUMAR_SMART_LAMP, () -> new BlockItem(ILLUMAR_SMART_LAMP.get(), new Item.Properties().tab(ILLUMINATION_GROUP))); + + // Block Entities + ILLUMAR_SMART_LAMP_BLOCK_ENTITY = BLOCK_ENTITY_TYPES.register(ID_ILLUMAR_SMART_LAMP, () -> BlockEntityType.Builder.of(IllumarSmartLampBlockEntity::new, ILLUMAR_SMART_LAMP.get()).build(null)); } } diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/init/IlluminationClientInit.java b/illumination/src/main/java/mrtjp/projectred/illumination/init/IlluminationClientInit.java index cb4a4cd3d..66ef3cdb2 100644 --- a/illumination/src/main/java/mrtjp/projectred/illumination/init/IlluminationClientInit.java +++ b/illumination/src/main/java/mrtjp/projectred/illumination/init/IlluminationClientInit.java @@ -5,9 +5,7 @@ import codechicken.multipart.api.MultipartClientRegistry; import mrtjp.projectred.illumination.BlockLightType; import mrtjp.projectred.illumination.MultipartLightType; -import mrtjp.projectred.illumination.client.IllumarLampItemRenderer; -import mrtjp.projectred.illumination.client.IllumarLampTileRenderer; -import mrtjp.projectred.illumination.client.MultipartLightPartRenderer; +import mrtjp.projectred.illumination.client.*; import net.covers1624.quack.util.SneakyUtils; import net.minecraft.client.renderer.blockentity.BlockEntityRenderers; import net.minecraft.client.resources.model.BakedModel; @@ -47,6 +45,13 @@ public static void init() { new ModelResourceLocation(blockRL, "inventory"), new IllumarLampItemRenderer(litModel)); } + + // Illumar smart lamp renderer + ResourceLocation smartLampRl = Objects.requireNonNull(ForgeRegistries.BLOCKS.getKey(IlluminationBlocks.ILLUMAR_SMART_LAMP.get())); + BakedModel smartLampModel = e.getModels().get(new ModelResourceLocation(smartLampRl, "level=15,side=0")); + e.getModels().put( + new ModelResourceLocation(smartLampRl, "inventory"), + new IllumarSmartLampItemRenderer(smartLampModel)); }); } @@ -60,6 +65,8 @@ private static void clientSetup(final FMLClientSetupEvent event) { } } + BlockEntityRenderers.register(SneakyUtils.unsafeCast(IlluminationBlocks.ILLUMAR_SMART_LAMP_BLOCK_ENTITY.get()), c -> IllumarSmartLampBlockEntityRenderer.INSTANCE); + // Register light part renderers for (MultipartLightType type : MultipartLightType.values()) { for (int colour = 0; colour < 16; colour++) { diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/part/IllumarLampMicroMaterial.java b/illumination/src/main/java/mrtjp/projectred/illumination/part/IllumarLampMicroMaterial.java index f3ae940e0..b20ac2c17 100644 --- a/illumination/src/main/java/mrtjp/projectred/illumination/part/IllumarLampMicroMaterial.java +++ b/illumination/src/main/java/mrtjp/projectred/illumination/part/IllumarLampMicroMaterial.java @@ -46,9 +46,9 @@ public void renderDynamic(MicroblockPart part, @Nullable ItemTransforms.Transfor Cuboid6 cuboid = part.getBounds().copy().expand(0.025D); if (transform != null) { // Inventory rendering - HaloRenderer.renderInventoryHalo(ccrs, pStack, buffers, cuboid, getLightColor(), Vector3.ZERO); + HaloRenderer.renderInventoryHalo(ccrs, pStack, buffers, cuboid, Vector3.ZERO, getLightColor()); } else { - HaloRenderer.addLight(part.pos(), getLightColor(), cuboid); + HaloRenderer.addLight(part.pos(), cuboid, getLightColor()); } } diff --git a/illumination/src/main/java/mrtjp/projectred/illumination/tile/IllumarSmartLampBlockEntity.java b/illumination/src/main/java/mrtjp/projectred/illumination/tile/IllumarSmartLampBlockEntity.java new file mode 100644 index 000000000..d03a8986c --- /dev/null +++ b/illumination/src/main/java/mrtjp/projectred/illumination/tile/IllumarSmartLampBlockEntity.java @@ -0,0 +1,269 @@ +package mrtjp.projectred.illumination.tile; + +import codechicken.lib.data.MCDataInput; +import codechicken.lib.data.MCDataOutput; +import codechicken.lib.vec.Rotation; +import mrtjp.projectred.api.IBundledEmitter; +import mrtjp.projectred.api.IBundledTile; +import mrtjp.projectred.api.IConnectable; +import mrtjp.projectred.api.IMaskedBundledTile; +import mrtjp.projectred.core.BundledSignalsLib; +import mrtjp.projectred.core.CenterLookup; +import mrtjp.projectred.core.FaceLookup; +import mrtjp.projectred.core.tile.BaseConnectableTile; +import mrtjp.projectred.core.tile.IOrientableBlockEntity; +import mrtjp.projectred.illumination.block.IllumarSmartLampBlock; +import mrtjp.projectred.illumination.init.IlluminationBlocks; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; + +import javax.annotation.Nullable; +import java.util.Objects; + +public class IllumarSmartLampBlockEntity extends BaseConnectableTile implements IOrientableBlockEntity, IMaskedBundledTile { + + private static final int PACKET_SIGNAL = 10; + + private final byte[] signal = new byte[16]; + + public IllumarSmartLampBlockEntity(BlockPos pos, BlockState state) { + super(IlluminationBlocks.ILLUMAR_SMART_LAMP_BLOCK_ENTITY.get(), pos, state); + } + + public byte[] getSignal() { + return signal; + } + + @Override + public void saveToNBT(CompoundTag tag) { + super.saveToNBT(tag); + tag.putByteArray("signal", signal); + } + + @Override + public void loadFromNBT(CompoundTag tag) { + super.loadFromNBT(tag); + + var s = tag.getByteArray("signal"); + if (s.length == 16) + System.arraycopy(s, 0, signal, 0, 16); + } + + @Override + public void writeDesc(MCDataOutput out) { + super.writeDesc(out); + for (int i = 0; i < 16; i++) + out.writeByte(signal[i]); + } + + @Override + public void readDesc(MCDataInput in) { + super.readDesc(in); + for (int i = 0; i < 16; i++) + signal[i] = in.readByte(); + } + + @Override + public void receiveUpdateFromServer(int key, MCDataInput input) { + switch (key) { + case PACKET_SIGNAL -> readSignalUpdate(input); + default -> super.receiveUpdateFromServer(key, input); + } + } + + private void readSignalUpdate(MCDataInput input) { + short changeMask = input.readShort(); + for (int i = 0; i < 16; i++) { + if ((changeMask & (1 << i)) != 0) { + signal[i] = input.readByte(); + } + } + } + + private void sendSignalUpdate(int changeMask) { + if (changeMask == 0) return; + + sendUpdateToPlayersWatchingChunk(PACKET_SIGNAL, stream -> { + stream.writeShort(changeMask); + for (int i = 0; i < 16; i++) { + if ((changeMask & (1 << i)) != 0) { + stream.writeByte(signal[i]); + } + } + }); + } + + @Override + public BlockState storeBlockState(BlockState defaultState) { + int max = 0; + for (byte b : signal) { + max = Math.max(max, b & 0xFF); + } + return super.storeBlockState(defaultState) + .setValue(IllumarSmartLampBlock.LEVEL, max / 17); // 255 -> 15 + } + + //region IMaskedBundled tile + @Override + public byte[] getBundledSignal(int dir) { + return null; // Block is input only + } + + @Override + public boolean canConnectBundled(int side) { + return side != (getSide() ^ 1); + } + + @Override + public int getConnectionMask(int side) { + if (side == getSide()) { + return 0x1F; // All edges and center + } if (side == (getSide() ^ 1)) { + return 0; // No connections on top + } else { + return 1 << Rotation.rotationTo(side, getSide()); // Bottom edge + } + } + //endregion + + @Override + public boolean canConnectPart(IConnectable part, int s, int edgeRot) { + if (!(part instanceof IBundledEmitter)) return false; + + int side = getSide(); + + if (s == side) { // Bottom side can input from all 4 edges and center + return true; + } + if (s == (side ^ 1)) { // Top side cannot input at all + return false; + } + + return edgeRot == Rotation.rotationTo(s, side); // Other sides input on edge touching bottom side + } + + @Override + public void onNeighborBlockChanged(BlockPos neighborPos) { + super.onNeighborBlockChanged(neighborPos); + + if (!getLevel().isClientSide) { + checkSignal(); + } + } + + @Override + public void onBlockPlaced(@Nullable LivingEntity player, ItemStack item) { + super.onBlockPlaced(player, item); + + if (!getLevel().isClientSide) { + checkSignal(); + } + } + + @Override + public void onOrientationChange() { + if (!getLevel().isClientSide) { + updateExternals(); + checkSignal(); + } + } + + private void checkSignal() { + byte[] newSig = calcBundledInput(); + // Send update if any byte is different + int changeMask = BundledSignalsLib.applyAndGetChangeMask(newSig, signal); + if (changeMask != 0) { + pushBlockState(); + sendSignalUpdate(changeMask); + } + } + + //region Signal acquisition + protected byte[] calcBundledInput() { + byte[] newSignal = new byte[16]; + + for (int s = 0; s < 6; s++) { + if (s == (getSide() ^ 1)) { // Cant connect on top + continue; + } + + if (s == getSide()) { // Bottom can connect straight or on edges + // Center connection + if (maskConnectsStraightCenter(s)) { + BundledSignalsLib.raiseSignal(newSignal, calcCenterSignal(s)); + } + + // Edge connections + for (int r = 0; r < 4; r++) { + if (maskConnectsStraight(s, r)) { // Straight down + BundledSignalsLib.raiseSignal(newSignal, calcStraightSignal(s, r)); + } else if (maskConnectsCorner(s, r)) { // Corner towards sides + BundledSignalsLib.raiseSignal(newSignal, calcCornerSignal(s, r)); + } + } + + continue; + } + + // Perpendicular faces can connect only on bottom edge + int r = Rotation.rotationTo(s, getSide()); + if (maskConnectsStraight(s, r)) { + BundledSignalsLib.raiseSignal(newSignal, calcStraightSignal(s, r)); + } else if (maskConnectsCorner(s, r)) { + BundledSignalsLib.raiseSignal(newSignal, calcCornerSignal(s, r)); + } + } + + return newSignal; + } + + private @Nullable byte[] calcCornerSignal(int s, int r) { + int vs = Rotation.rotateSide(s, r); // virtual internal face + int vr = Rotation.rotationTo(vs, s); // virtual rotation + FaceLookup lookup = FaceLookup.lookupCorner(getLevel(), getBlockPos(), vs, vr); + return resolveArray(lookup); + } + + private @Nullable byte[] calcStraightSignal(int s, int r) { + int vs = Rotation.rotateSide(s, r); // virtual internal face + int vr = Rotation.rotationTo(vs, s); // virtual rotation + FaceLookup lookup = FaceLookup.lookupStraight(getLevel(), getBlockPos(), vs, vr); + return resolveArray(lookup); + } + + private @Nullable byte[] calcCenterSignal(int s) { + CenterLookup lookup = CenterLookup.lookupStraightCenter(getLevel(), getBlockPos(), s); + return resolveArray(lookup); + } + + protected @Nullable byte[] resolveArray(FaceLookup lookup) { + if (lookup.part instanceof IBundledEmitter) { + return ((IBundledEmitter) lookup.part).getBundledSignal(lookup.otherRotation); + + } else if (lookup.tile instanceof IBundledTile) { + return ((IBundledTile) lookup.tile).getBundledSignal(Rotation.rotateSide(lookup.otherSide, lookup.otherRotation)); + + } else if (lookup.tile != null) { + return BundledSignalsLib.getBundledSignalViaInteraction(Objects.requireNonNull(lookup.tile.getLevel()), lookup.tile.getBlockPos(), Direction.values()[Rotation.rotateSide(lookup.otherSide, lookup.otherRotation)]); + } + return null; + } + + protected @Nullable byte[] resolveArray(CenterLookup lookup) { + if (lookup.part instanceof IBundledEmitter) { + return ((IBundledEmitter) lookup.part).getBundledSignal(lookup.otherDirection); + + } else if (lookup.tile instanceof IBundledTile) { + return ((IBundledTile) lookup.tile).getBundledSignal(lookup.otherDirection); + + } else if (lookup.tile != null) { + return BundledSignalsLib.getBundledSignalViaInteraction(Objects.requireNonNull(lookup.tile.getLevel()), lookup.tile.getBlockPos(), Direction.values()[lookup.otherDirection]); + } + return null; + } + //endregion +} diff --git a/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_bottom.png b/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_bottom.png new file mode 100644 index 000000000..059d19794 Binary files /dev/null and b/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_bottom.png differ diff --git a/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_side.png b/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_side.png new file mode 100644 index 000000000..b54df3291 Binary files /dev/null and b/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_side.png differ diff --git a/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_side_on.png b/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_side_on.png new file mode 100644 index 000000000..732a02493 Binary files /dev/null and b/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_side_on.png differ diff --git a/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_top.png b/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_top.png new file mode 100644 index 000000000..7b8d48594 Binary files /dev/null and b/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_top.png differ diff --git a/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_top_on.png b/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_top_on.png new file mode 100644 index 000000000..654084e12 Binary files /dev/null and b/illumination/src/main/resources/assets/projectred_illumination/textures/block/illumar_smart_lamp_top_on.png differ diff --git a/integration/src/main/java/mrtjp/projectred/integration/client/GateComponentModels.java b/integration/src/main/java/mrtjp/projectred/integration/client/GateComponentModels.java index cf1b83e06..19cbe16bc 100644 --- a/integration/src/main/java/mrtjp/projectred/integration/client/GateComponentModels.java +++ b/integration/src/main/java/mrtjp/projectred/integration/client/GateComponentModels.java @@ -1080,7 +1080,7 @@ public void renderLights(CCRenderState ccrs, BlockPos lightPos, PoseStack mStack Transformation t2 = t.with(new Translation(lightPos)); for (int i = 0; i < 16; i++) { if ((pressMask & 1 << i) != 0) { - HaloRenderer.addLight(t2, i, LIGHT_BOXES[i]); + HaloRenderer.addLight(t2, LIGHT_BOXES[i], i); } } }