From f5a76ed0cd5724f08b6bda874e044e8732abf0ad Mon Sep 17 00:00:00 2001 From: Nito Date: Sat, 29 Jul 2023 21:24:14 +0200 Subject: [PATCH] render patterns via textures to boost fps --- .../client/entity/WallScrollRenderer.java | 11 +- .../client/render/HexPatternPoints.java | 15 + .../client/render/PatternTextureManager.java | 307 ++++++++++++++++++ .../BlockEntityAkashicBookshelfRenderer.java | 7 + .../render/be/BlockEntitySlateRenderer.java | 9 +- .../akashic/BlockEntityAkashicBookshelf.java | 3 + .../blocks/circles/BlockEntitySlate.java | 3 + .../command/PatternTexturesCommand.java | 43 +++ .../common/entities/EntityWallScroll.java | 11 +- .../hexcasting/common/lib/HexBlocks.java | 2 +- .../hexcasting/common/lib/HexCommands.java | 2 + 11 files changed, 401 insertions(+), 12 deletions(-) create mode 100644 Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternPoints.java create mode 100644 Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java create mode 100644 Common/src/main/java/at/petrak/hexcasting/common/command/PatternTexturesCommand.java diff --git a/Common/src/main/java/at/petrak/hexcasting/client/entity/WallScrollRenderer.java b/Common/src/main/java/at/petrak/hexcasting/client/entity/WallScrollRenderer.java index 14a86cd2..4f9af78a 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/entity/WallScrollRenderer.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/entity/WallScrollRenderer.java @@ -1,5 +1,6 @@ package at.petrak.hexcasting.client.entity; +import at.petrak.hexcasting.client.render.PatternTextureManager; import at.petrak.hexcasting.client.render.RenderLib; import at.petrak.hexcasting.common.entities.EntityWallScroll; import com.mojang.blaze3d.systems.RenderSystem; @@ -97,12 +98,16 @@ public class WallScrollRenderer extends EntityRenderer { vertex(mat, norm, light, verts, dx, dy, dz, 1, 1 - margin, 0, 1, 0); ps.popPose(); + + if (PatternTextureManager.useTextures && wallScroll.points != null) + PatternTextureManager.renderPatternForScroll(wallScroll.points.pointsKey, ps, bufSource, light, wallScroll.points.zappyPoints, wallScroll.blockSize, wallScroll.getShowsStrokeOrder()); } - if (wallScroll.zappyPoints != null) { - var points = wallScroll.zappyPoints; - ps.pushPose(); + //TODO: remove old rendering if not needed anymore for comparison + if(!PatternTextureManager.useTextures && wallScroll.points != null) { + var points = wallScroll.points.zappyPoints; + ps.pushPose(); ps.mulPose(Vector3f.YP.rotationDegrees(180f)); ps.translate(0, 0, 1.1f / 16f); // make smaller scrolls not be charlie kirk-sized diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternPoints.java b/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternPoints.java new file mode 100644 index 00000000..b033e8de --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/HexPatternPoints.java @@ -0,0 +1,15 @@ +package at.petrak.hexcasting.client.render; + +import net.minecraft.world.phys.Vec2; + +import java.util.List; + +public class HexPatternPoints { + public List zappyPoints = null; + public String pointsKey = null; //TODO: if a string key isnt performant enough override hashcode for points + + public HexPatternPoints(List zappyPoints) { + this.zappyPoints = zappyPoints; + pointsKey = PatternTextureManager.getPointsKey(zappyPoints); + } +} \ No newline at end of file diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java new file mode 100644 index 00000000..d2befd1d --- /dev/null +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/PatternTextureManager.java @@ -0,0 +1,307 @@ +package at.petrak.hexcasting.client.render; + +import at.petrak.hexcasting.api.block.HexBlockEntity; +import at.petrak.hexcasting.api.casting.math.HexPattern; +import at.petrak.hexcasting.common.blocks.akashic.BlockAkashicBookshelf; +import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicBookshelf; +import at.petrak.hexcasting.common.blocks.circles.BlockEntitySlate; +import at.petrak.hexcasting.common.blocks.circles.BlockSlate; +import com.mojang.blaze3d.platform.NativeImage; +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Matrix3f; +import com.mojang.math.Matrix4f; +import com.mojang.math.Vector3f; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.GameRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.DynamicTexture; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Tuple; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.AttachFace; +import net.minecraft.world.phys.Vec2; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.HashMap; +import java.util.List; +import java.util.stream.Collectors; + +public class PatternTextureManager { + + //TODO: remove if not needed anymore for comparison + public static boolean useTextures = true; + public static int repaintIndex = 0; + + public static int resolutionByBlockSize = 512; + public static int paddingByBlockSize = 50; + public static int circleRadiusByBlockSize = 8; + public static int scaleLimit = 16; + + private static HashMap patternTextures = new HashMap<>(); + + public static String getPointsKey(List zappyPoints) + { + return zappyPoints.stream() + .map(p -> String.format("(%f,%f)", p.x, p.y)) + .collect(Collectors.joining(";")); + } + + public static HexPatternPoints generateHexPatternPoints(HexBlockEntity tile, HexPattern pattern, float flowIrregular) + { + var stupidHash = tile.getBlockPos().hashCode(); + var lines1 = pattern.toLines(1, Vec2.ZERO); + var zappyPoints = RenderLib.makeZappy(lines1, RenderLib.findDupIndices(pattern.positions()), + 10, 0.5f, 0f, flowIrregular, 0f, 1f, stupidHash); + return new HexPatternPoints(zappyPoints); + } + + public static void renderPatternForScroll(String pointsKey, PoseStack ps, MultiBufferSource bufSource, int light, List zappyPoints, int blockSize, boolean showStrokeOrder) + { + renderPattern(pointsKey, ps, bufSource, light, zappyPoints, blockSize, showStrokeOrder, false, true, false,false, true,-1); + } + public static void renderPatternForSlate(BlockEntitySlate tile, HexPattern pattern, PoseStack ps, MultiBufferSource buffer, int light, BlockState bs) + { + if(tile.points == null) + tile.points = generateHexPatternPoints(tile, pattern, 0.2f); + + boolean isOnWall = bs.getValue(BlockSlate.ATTACH_FACE) == AttachFace.WALL; + boolean isOnCeiling = bs.getValue(BlockSlate.ATTACH_FACE) == AttachFace.CEILING; + int facing = bs.getValue(BlockSlate.FACING).get2DDataValue(); + + renderPatternForBlockEntity(tile.points, ps, buffer, light, isOnWall, isOnCeiling, true, facing); + } + public static void renderPatternForAkashicBookshelf(BlockEntityAkashicBookshelf tile, HexPattern pattern, PoseStack ps, MultiBufferSource buffer, int light, BlockState bs) + { + if(tile.points == null) + tile.points = generateHexPatternPoints(tile, pattern, 0f); + + int facing = bs.getValue(BlockAkashicBookshelf.FACING).get2DDataValue(); + renderPatternForBlockEntity(tile.points, ps, buffer, light, true, false, false, facing); + } + + public static void renderPatternForBlockEntity(HexPatternPoints points, PoseStack ps, MultiBufferSource buffer, int light, boolean isOnWall, boolean isOnCeiling, boolean isSlate, int facing) + { + var oldShader = RenderSystem.getShader(); + ps.pushPose(); + RenderSystem.setShader(GameRenderer::getPositionTexShader); + renderPattern(points.pointsKey, ps, buffer, light, points.zappyPoints, 1, false, true, isOnWall, isOnCeiling, isSlate, false, facing); + ps.popPose(); + RenderSystem.setShader(() -> oldShader); + } + + public static void renderPattern(String pointsKey, PoseStack ps, MultiBufferSource bufSource, int light, List zappyPoints, int blockSize, boolean showStrokeOrder, boolean useFullSize, boolean isOnWall, boolean isOnCeiling, boolean isSlate, boolean isScroll, int facing) + { + ps.pushPose(); + + PoseStack.Pose last = ps.last(); + Matrix4f mat = last.pose(); + Matrix3f normal = last.normal(); + + float x = blockSize, y = blockSize, z = (-1f / 16f) - 0.01f; + float nx = 0, ny = 0, nz = 0; + + //TODO: refactor this mess of a method + + if(isOnWall) + { + if(isScroll) + { + ps.translate(-blockSize / 2f, -blockSize / 2f, 1f / 32f); + nz = -1; + } + else + { + ps.mulPose(Vector3f.ZP.rotationDegrees(180)); + + if(isSlate) + { + if(facing == 0) + ps.translate(0,-1,0); + if(facing == 1) + ps.translate(-1,-1,0); + if(facing == 2) + ps.translate(-1,-1,1); + if(facing == 3) + ps.translate(0,-1,1); + } + else + { + z = -0.01f; + if(facing == 0) + ps.translate(0,-1,1); + if(facing == 1) + ps.translate(0,-1,0); + if(facing == 2) + ps.translate(-1,-1,0); + if(facing == 3) + ps.translate(-1,-1,1); + } + + if(facing == 0) + ps.mulPose(Vector3f.YP.rotationDegrees(180)); + if(facing == 1) + ps.mulPose(Vector3f.YP.rotationDegrees(270)); + if(facing == 3) + ps.mulPose(Vector3f.YP.rotationDegrees(90)); + + if(facing == 0 || facing == 2) + nz = -1; + if(facing == 1 || facing == 3) + nx = -1; + ps.translate(0,0,0); + } + } + else //slates on the floor or ceiling + { + if(facing == 0) + ps.translate(0,0,0); + if(facing == 1) + ps.translate(1,0,0); + if(facing == 2) + ps.translate(1,0,1); + if(facing == 3) + ps.translate(0,0,1); + ps.mulPose(Vector3f.YP.rotationDegrees(facing*-90)); + + if(isOnCeiling) + { + ps.mulPose(Vector3f.XP.rotationDegrees(-90)); + ps.translate(0,-1,1); + } + else + ps.mulPose(Vector3f.XP.rotationDegrees(90)); + nz = -1; + } + + int lineWidth = 16; + int outerColor = 0xB4B4BE;//0xff_c8c8d2; + int innerColor = 0x2A2A2A;//0xc8_322b33; + if(isScroll) + { + lineWidth = 20; + outerColor = 0xDEDEDE;//0xff_d2c8c8; + innerColor = 0x343434;//0xc8_322b33; + } + + ResourceLocation texture = getTexture(zappyPoints, pointsKey, blockSize, showStrokeOrder, lineWidth, useFullSize, new Color(innerColor), new Color(outerColor)); + VertexConsumer verts = bufSource.getBuffer(RenderType.entityCutout(texture)); + + vertex(mat, normal, light, verts, 0, 0, z, 0, 0, nx, ny, nz); + vertex(mat, normal, light, verts, 0, y, z, 0, 1, nx, ny, nz); + vertex(mat, normal, light, verts, x, y, z, 1, 1, nx, ny, nz); + vertex(mat, normal, light, verts, x, 0, z, 1, 0, nx, ny, nz); + + ps.popPose(); + } + + private static void vertex(Matrix4f mat, Matrix3f normal, int light, VertexConsumer verts, float x, float y, float z, + float u, float v, float nx, float ny, float nz) { + verts.vertex(mat, x, y, z) + .color(0xffffffff) + .uv(u, v).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(light) + .normal(normal, nx, ny, nz) + .endVertex(); + } + + public static ResourceLocation getTexture(List points, String pointsKey, int blockSize, boolean showsStrokeOrder, int lineWidth, boolean useFullSize, Color innerColor, Color outerColor) { + if (patternTextures.containsKey(pointsKey)) + return patternTextures.get(pointsKey); + return createTexture(points, pointsKey, blockSize, showsStrokeOrder, lineWidth, useFullSize, innerColor, outerColor); + } + + public static ResourceLocation createTexture(List points, String pointsKey, int blockSize, boolean showsStrokeOrder, int lineWidth, boolean useFullSize, Color innerColor, Color outerColor) + { + int resolution = resolutionByBlockSize * blockSize; + int padding = paddingByBlockSize * blockSize; + + double minX = Double.MAX_VALUE, maxX = Double.MIN_VALUE, minY = Double.MAX_VALUE, maxY = Double.MIN_VALUE; + for (Vec2 point : points) + { + minX = Math.min(minX, point.x); + maxX = Math.max(maxX, point.x); + minY = Math.min(minY, point.y); + maxY = Math.max(maxY, point.y); + } + + double rangeX = maxX - minX; + double rangeY = maxY - minY; + + double scale = Math.min((resolution - 2 * padding) / rangeX, (resolution - 2 * padding) / rangeY); + + double limit = blockSize * scaleLimit; + if (!useFullSize && scale > limit) + scale = limit; + + double offsetX = ((resolution - 2 * padding) - rangeX * scale) / 2; + double offsetY = ((resolution - 2 * padding) - rangeY * scale) / 2; + + BufferedImage img = new BufferedImage(resolution, resolution, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = img.createGraphics(); + + g2d.setColor(outerColor); + g2d.setStroke(new BasicStroke((blockSize * 5f / 3f) * lineWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + drawLines(g2d, points, minX, minY, scale, offsetX, offsetY, padding); + + g2d.setColor(innerColor); + g2d.setStroke(new BasicStroke((blockSize * 2f / 3f) * lineWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + drawLines(g2d, points, minX, minY, scale, offsetX, offsetY, padding); + + + if (showsStrokeOrder) { + g2d.setColor(new Color(0xff_d77b5b)); + Tuple point = getTextureCoordinates(points.get(0), minX, minY, scale, offsetX, offsetY, padding); + int spotRadius = circleRadiusByBlockSize * blockSize; + drawHexagon(g2d, point.getA(), point.getB(), spotRadius); + } + + g2d.dispose(); + + NativeImage nativeImage = new NativeImage(img.getWidth(), img.getHeight(), true); + for (int y = 0; y < img.getHeight(); y++) + for (int x = 0; x < img.getWidth(); x++) + nativeImage.setPixelRGBA(x, y, img.getRGB(x, y)); + + DynamicTexture dynamicTexture = new DynamicTexture(nativeImage); + ResourceLocation resourceLocation = Minecraft.getInstance().getTextureManager().register("hex_pattern_texture_" + points.hashCode() + "_" + repaintIndex + ".png", dynamicTexture); + patternTextures.put(pointsKey, resourceLocation); + return resourceLocation; + } + + private static void drawLines(Graphics2D g2d, List points, double minX, double minY, double scale, double offsetX, double offsetY, int padding) { + for (int i = 0; i < points.size() - 1; i++) { + Tuple pointFrom = getTextureCoordinates(points.get(i), minX, minY, scale, offsetX, offsetY, padding); + Tuple pointTo = getTextureCoordinates(points.get(i+1), minX, minY, scale, offsetX, offsetY, padding); + g2d.drawLine(pointFrom.getA(), pointFrom.getB(), pointTo.getA(), pointTo.getB()); + } + } + + private static Tuple getTextureCoordinates(Vec2 point, double minX, double minY, double scale, double offsetX, double offsetY, int padding) { + int x = (int) ((point.x - minX) * scale + offsetX) + padding; + int y = (int) ((point.y - minY) * scale + offsetY) + padding; + return new Tuple(x, y); + } + + private static void drawHexagon(Graphics2D g2d, int x, int y, int radius) { + int fracOfCircle = 6; + Polygon hexagon = new Polygon(); + + for (int i = 0; i < fracOfCircle; i++) { + double theta = (i / (double) fracOfCircle) * Math.PI * 2; + int hx = (int) (x + Math.cos(theta) * radius); + int hy = (int) (y + Math.sin(theta) * radius); + hexagon.addPoint(hx, hy); + } + + g2d.fill(hexagon); + } + + public static void repaint() { + repaintIndex++; + patternTextures.clear(); + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntityAkashicBookshelfRenderer.java b/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntityAkashicBookshelfRenderer.java index 8da81bef..6fe5ca84 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntityAkashicBookshelfRenderer.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntityAkashicBookshelfRenderer.java @@ -1,6 +1,7 @@ package at.petrak.hexcasting.client.render.be; import at.petrak.hexcasting.api.casting.math.HexPattern; +import at.petrak.hexcasting.client.render.PatternTextureManager; import at.petrak.hexcasting.client.render.RenderLib; import at.petrak.hexcasting.common.blocks.akashic.BlockAkashicBookshelf; import at.petrak.hexcasting.common.blocks.akashic.BlockEntityAkashicBookshelf; @@ -16,6 +17,7 @@ import net.minecraft.util.Mth; import net.minecraft.world.phys.Vec2; public class BlockEntityAkashicBookshelfRenderer implements BlockEntityRenderer { + public BlockEntityAkashicBookshelfRenderer(BlockEntityRendererProvider.Context ctx) { // NO-OP } @@ -29,7 +31,12 @@ public class BlockEntityAkashicBookshelfRenderer implements BlockEntityRenderer< } var bs = tile.getBlockState(); + if(PatternTextureManager.useTextures) { + PatternTextureManager.renderPatternForAkashicBookshelf(tile, pattern, ps, buffer, light, bs); + return; + } + //TODO: remove old rendering if not needed anymore for comparison var oldShader = RenderSystem.getShader(); RenderSystem.setShader(GameRenderer::getPositionColorShader); RenderSystem.enableDepthTest(); diff --git a/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntitySlateRenderer.java b/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntitySlateRenderer.java index 47cf4710..c9fbe215 100644 --- a/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntitySlateRenderer.java +++ b/Common/src/main/java/at/petrak/hexcasting/client/render/be/BlockEntitySlateRenderer.java @@ -1,5 +1,6 @@ package at.petrak.hexcasting.client.render.be; +import at.petrak.hexcasting.client.render.PatternTextureManager; import at.petrak.hexcasting.client.render.RenderLib; import at.petrak.hexcasting.common.blocks.circles.BlockEntitySlate; import at.petrak.hexcasting.common.blocks.circles.BlockSlate; @@ -23,11 +24,15 @@ public class BlockEntitySlateRenderer implements BlockEntityRenderer cmd) { + cmd.then(Commands.literal("textureToggle") + .requires(dp -> dp.hasPermission(Commands.LEVEL_ADMINS)) + .executes(ctx -> { + PatternTextureManager.useTextures = !PatternTextureManager.useTextures; + return 1; + })); + +// cmd.then(Commands.literal("textureSetColor") +// .requires(dp -> dp.hasPermission(Commands.LEVEL_ADMINS)) +// .then(Commands.argument("r", IntegerArgumentType.integer()) +// .then(Commands.argument("g", IntegerArgumentType.integer()) +// .then(Commands.argument("b", IntegerArgumentType.integer()).executes(ctx -> { +// var r = IntegerArgumentType.getInteger(ctx, "r"); +// var g = IntegerArgumentType.getInteger(ctx, "g"); +// var b = IntegerArgumentType.getInteger(ctx, "b"); +// PatternTextureManager.color = new Color(r,g,b,255); +// PatternTextureManager.repaint(); +// return 1; +// }))))); +// +// cmd.then(Commands.literal("textureSetResolution") +// .requires(dp -> dp.hasPermission(Commands.LEVEL_ADMINS)) +// .then(Commands.argument("integer", IntegerArgumentType.integer()).executes(ctx -> { +// var integer = IntegerArgumentType.getInteger(ctx, "integer"); +// PatternTextureManager.resolutionByBlockSize = integer; +// PatternTextureManager.repaint(); +// return 1; +// }))); + } +} diff --git a/Common/src/main/java/at/petrak/hexcasting/common/entities/EntityWallScroll.java b/Common/src/main/java/at/petrak/hexcasting/common/entities/EntityWallScroll.java index 304a97c7..9bad2b6e 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/entities/EntityWallScroll.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/entities/EntityWallScroll.java @@ -1,5 +1,6 @@ package at.petrak.hexcasting.common.entities; +import at.petrak.hexcasting.client.render.HexPatternPoints; import at.petrak.hexcasting.api.casting.math.HexPattern; import at.petrak.hexcasting.api.utils.HexUtils; import at.petrak.hexcasting.api.utils.NBTHelper; @@ -30,12 +31,9 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.GameRules; import net.minecraft.world.level.Level; -import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.Nullable; -import java.util.List; - public class EntityWallScroll extends HangingEntity { private static final EntityDataAccessor SHOWS_STROKE_ORDER = SynchedEntityData.defineId( EntityWallScroll.class, @@ -46,7 +44,7 @@ public class EntityWallScroll extends HangingEntity { public boolean isAncient; public int blockSize; // Client-side only! - public List zappyPoints; + public HexPatternPoints points; public EntityWallScroll(EntityType type, Level world) { super(type, world); @@ -74,14 +72,15 @@ public class EntityWallScroll extends HangingEntity { var dots = pair.getSecond(); var readOffset = this.getShowsStrokeOrder() ? RenderLib.DEFAULT_READABILITY_OFFSET : 0f; var lastProp = this.getShowsStrokeOrder() ? RenderLib.DEFAULT_LAST_SEGMENT_LEN_PROP : 1f; - this.zappyPoints = RenderLib.makeZappy(dots, RenderLib.findDupIndices(pattern.positions()), 10, 0.4f, + var zappyPoints = RenderLib.makeZappy(dots, RenderLib.findDupIndices(pattern.positions()), 10, 0.4f, 0f, 0f, readOffset, lastProp, this.getId()); + points = new HexPatternPoints(zappyPoints); } this.isAncient = NBTHelper.hasString(scroll, ItemScroll.TAG_OP_ID); } else { this.pattern = null; - this.zappyPoints = null; + this.points = null; this.isAncient = false; } } diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexBlocks.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexBlocks.java index 92a4d76f..c7ad9323 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexBlocks.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexBlocks.java @@ -155,7 +155,7 @@ public class HexBlocks { new BlockAkashicRecord(akashicWoodyHard().lightLevel(bs -> 15))); public static final BlockAkashicBookshelf AKASHIC_BOOKSHELF = blockItem("akashic_bookshelf", new BlockAkashicBookshelf(akashicWoodyHard() - .lightLevel(bs -> (bs.getValue(BlockAkashicBookshelf.HAS_BOOKS)) ? 4 : 0))); + .lightLevel(bs -> (bs.getValue(BlockAkashicBookshelf.HAS_BOOKS)) ? 15 : 0))); public static final BlockAkashicLigature AKASHIC_LIGATURE = blockItem("akashic_connector", new BlockAkashicLigature(akashicWoodyHard().lightLevel(bs -> 4))); diff --git a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexCommands.java b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexCommands.java index 4e4d4418..3bb3c5d8 100644 --- a/Common/src/main/java/at/petrak/hexcasting/common/lib/HexCommands.java +++ b/Common/src/main/java/at/petrak/hexcasting/common/lib/HexCommands.java @@ -3,6 +3,7 @@ package at.petrak.hexcasting.common.lib; import at.petrak.hexcasting.common.command.BrainsweepCommand; import at.petrak.hexcasting.common.command.ListPerWorldPatternsCommand; import at.petrak.hexcasting.common.command.RecalcPatternsCommand; +import at.petrak.hexcasting.common.command.PatternTexturesCommand; import com.mojang.brigadier.CommandDispatcher; import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.Commands; @@ -14,6 +15,7 @@ public class HexCommands { BrainsweepCommand.add(mainCmd); ListPerWorldPatternsCommand.add(mainCmd); RecalcPatternsCommand.add(mainCmd); + PatternTexturesCommand.add(mainCmd); dispatcher.register(mainCmd); }