From ba6ef2353cc282b49824a40d05605d053c4409af Mon Sep 17 00:00:00 2001 From: shedaniel Date: Mon, 22 Jun 2020 15:48:25 +0800 Subject: [PATCH] 4.7.0 Signed-off-by: shedaniel --- .gitignore | 2 + fabric/build.gradle | 2 +- .../lightoverlay/fabric/LOModMenuEntry.java | 18 +- .../lightoverlay/fabric/LightOverlay.java | 273 ++++++++++-------- .../fabric/mixin/MixinClientConnection.java | 3 + .../assets/lightoverlay/lang/en_us.json | 10 +- .../forge/LightOverlayClient.java | 257 +++++++++-------- .../lightoverlay/forge/LightOverlayCloth.java | 31 +- .../main/resources/META-INF/NetworkManager.js | 2 +- .../main/resources/META-INF/WorldRenderer.js | 2 +- .../assets/lightoverlay/lang/en_us.json | 10 +- gradle.properties | 8 +- 12 files changed, 347 insertions(+), 271 deletions(-) diff --git a/.gitignore b/.gitignore index 1be3abf..e787a1c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,10 @@ /.gradle */.gradle /minecraft +*/minecraft /out */run +*/out /run /classes diff --git a/fabric/build.gradle b/fabric/build.gradle index 7e6d021..dde613c 100755 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -1,5 +1,5 @@ plugins { - id("fabric-loom") version "0.4.3" + id("fabric-loom") version "0.4-SNAPSHOT" } minecraft { diff --git a/fabric/src/main/java/me/shedaniel/lightoverlay/fabric/LOModMenuEntry.java b/fabric/src/main/java/me/shedaniel/lightoverlay/fabric/LOModMenuEntry.java index b381757..e7d7200 100644 --- a/fabric/src/main/java/me/shedaniel/lightoverlay/fabric/LOModMenuEntry.java +++ b/fabric/src/main/java/me/shedaniel/lightoverlay/fabric/LOModMenuEntry.java @@ -1,13 +1,16 @@ package me.shedaniel.lightoverlay.fabric; +import io.github.prospector.modmenu.api.ConfigScreenFactory; import io.github.prospector.modmenu.api.ModMenuApi; import me.shedaniel.clothconfig2.api.ConfigBuilder; import me.shedaniel.clothconfig2.api.ConfigCategory; import me.shedaniel.clothconfig2.api.ConfigEntryBuilder; +import me.shedaniel.clothconfig2.gui.entries.IntegerSliderEntry; import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.resource.language.I18n; import net.minecraft.util.math.MathHelper; -import java.util.function.Function; +import java.util.Optional; public class LOModMenuEntry implements ModMenuApi { @Override @@ -16,7 +19,7 @@ public class LOModMenuEntry implements ModMenuApi { } @Override - public Function getConfigScreenFactory() { + public ConfigScreenFactory getModConfigScreenFactory() { return this::getConfigScreenByCloth; } @@ -25,14 +28,23 @@ public class LOModMenuEntry implements ModMenuApi { ConfigEntryBuilder eb = builder.entryBuilder(); ConfigCategory general = builder.getOrCreateCategory("config.lightoverlay.general"); + general.addEntry(eb.startTextDescription("§7" + I18n.translate("description.lightoverlay.caching")).build()); + general.addEntry(eb.startBooleanToggle("config.lightoverlay.caching", LightOverlay.caching).setDefaultValue(false).setSaveConsumer(bool -> LightOverlay.caching = bool).build()); general.addEntry(eb.startIntSlider("config.lightoverlay.reach", LightOverlay.reach, 1, 64).setDefaultValue(12).setTextGetter(integer -> "Reach: " + integer + " Blocks").setSaveConsumer(integer -> LightOverlay.reach = integer).build()); - general.addEntry(eb.startIntSlider("config.lightoverlay.crossLevel", LightOverlay.crossLevel, 0, 15).setDefaultValue(7).setTextGetter(integer -> "Cross Level: " + integer).setSaveConsumer(integer -> LightOverlay.crossLevel = integer).build()); + IntegerSliderEntry crossLevel = eb.startIntSlider("config.lightoverlay.crossLevel", LightOverlay.crossLevel, 0, 15).setDefaultValue(7).setTextGetter(integer -> "Cross Level: " + integer).setSaveConsumer(integer -> LightOverlay.crossLevel = integer).build(); + general.addEntry(crossLevel); + general.addEntry(eb.startIntSlider("config.lightoverlay.secondaryLevel", LightOverlay.secondaryLevel, -1, 15) + .setErrorSupplier(integer -> { + if (integer >= 0 && integer >= crossLevel.getValue()) return Optional.of("Secondary Level cannot be higher than Cross Level!"); + return Optional.empty(); + }).setDefaultValue(-1).setTextGetter(integer -> integer < 0 ? "Off" : "Level: " + integer).setSaveConsumer(integer -> LightOverlay.secondaryLevel = integer).build()); general.addEntry(eb.startBooleanToggle("config.lightoverlay.showNumber", LightOverlay.showNumber).setDefaultValue(false).setSaveConsumer(bool -> LightOverlay.showNumber = bool).build()); general.addEntry(eb.startBooleanToggle("config.lightoverlay.smoothLines", LightOverlay.smoothLines).setDefaultValue(true).setSaveConsumer(bool -> LightOverlay.smoothLines = bool).build()); general.addEntry(eb.startBooleanToggle("config.lightoverlay.underwater", LightOverlay.underwater).setDefaultValue(false).setSaveConsumer(bool -> LightOverlay.underwater = bool).build()); general.addEntry(eb.startIntSlider("config.lightoverlay.lineWidth", MathHelper.floor(LightOverlay.lineWidth * 100), 100, 700).setDefaultValue(100).setTextGetter(integer -> "Light Width: " + LightOverlay.FORMAT.format(integer / 100d)).setSaveConsumer(integer -> LightOverlay.lineWidth = integer / 100f).build()); general.addEntry(eb.startColorField("config.lightoverlay.yellowColor", LightOverlay.yellowColor).setDefaultValue(0xFFFF00).setSaveConsumer(color -> LightOverlay.yellowColor = color).build()); general.addEntry(eb.startColorField("config.lightoverlay.redColor", LightOverlay.redColor).setDefaultValue(0xFF0000).setSaveConsumer(color -> LightOverlay.redColor = color).build()); + general.addEntry(eb.startColorField("config.lightoverlay.secondaryColor", LightOverlay.secondaryColor).setDefaultValue(0x0000FF).setSaveConsumer(color -> LightOverlay.secondaryColor = color).build()); return builder.setSavingRunnable(() -> { try { diff --git a/fabric/src/main/java/me/shedaniel/lightoverlay/fabric/LightOverlay.java b/fabric/src/main/java/me/shedaniel/lightoverlay/fabric/LightOverlay.java index 28883f8..eafd14a 100644 --- a/fabric/src/main/java/me/shedaniel/lightoverlay/fabric/LightOverlay.java +++ b/fabric/src/main/java/me/shedaniel/lightoverlay/fabric/LightOverlay.java @@ -6,8 +6,7 @@ import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import me.shedaniel.cloth.hooks.ClothClientHooks; import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.fabric.api.client.keybinding.FabricKeyBinding; -import net.fabricmc.fabric.api.client.keybinding.KeyBindingRegistry; +import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; import net.fabricmc.fabric.api.event.client.ClientTickCallback; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.block.Block; @@ -15,7 +14,10 @@ import net.minecraft.block.BlockState; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.client.render.*; +import net.minecraft.client.options.KeyBinding; +import net.minecraft.client.render.Camera; +import net.minecraft.client.render.Tessellator; +import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.util.InputUtil; import net.minecraft.client.util.math.Rotation3; import net.minecraft.client.world.ClientWorld; @@ -25,7 +27,6 @@ import net.minecraft.entity.EntityContext; import net.minecraft.entity.EntityType; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.tag.BlockTags; -import net.minecraft.text.TranslatableText; import net.minecraft.util.Identifier; import net.minecraft.util.math.*; import net.minecraft.util.shape.VoxelShape; @@ -45,80 +46,114 @@ import java.io.FileOutputStream; import java.io.IOException; import java.text.DecimalFormat; import java.util.*; -import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import java.util.concurrent.ThreadPoolExecutor; public class LightOverlay implements ClientModInitializer { + static final DecimalFormat FORMAT = new DecimalFormat("#.#"); private static final String KEYBIND_CATEGORY = "key.lightoverlay.category"; private static final Identifier ENABLE_OVERLAY_KEYBIND = new Identifier("lightoverlay", "enable_overlay"); - private static final Identifier INCREASE_REACH_KEYBIND = new Identifier("lightoverlay", "increase_reach"); - private static final Identifier DECREASE_REACH_KEYBIND = new Identifier("lightoverlay", "decrease_reach"); - private static final Identifier INCREASE_LINE_WIDTH_KEYBIND = new Identifier("lightoverlay", "increase_line_width"); - private static final Identifier DECREASE_LINE_WIDTH_KEYBIND = new Identifier("lightoverlay", "decrease_line_width"); static int reach = 12; static int crossLevel = 7; + static int secondaryLevel = -1; + static int lowerCrossLevel = -1; + static int higherCrossLevel = -1; + static boolean caching = false; static boolean showNumber = false; static boolean smoothLines = true; static boolean underwater = false; static float lineWidth = 1.0F; - static int yellowColor = 0xFFFF00, redColor = 0xFF0000; + static int yellowColor = 0xFFFF00, redColor = 0xFF0000, secondaryColor = 0x0000FF; static File configFile = new File(FabricLoader.getInstance().getConfigDirectory(), "lightoverlay.properties"); - private static FabricKeyBinding enableOverlay, increaseReach, decreaseReach, increaseLineWidth, decreaseLineWidth; + private static final KeyBinding ENABLE_OVERLAY = createKeyBinding(ENABLE_OVERLAY_KEYBIND, InputUtil.Type.KEYSYM, 296, KEYBIND_CATEGORY); private static boolean enabled = false; private static EntityType testingEntityType; private static int threadNumber = 0; - private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), r -> { + private static final ThreadPoolExecutor EXECUTOR = (ThreadPoolExecutor) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), r -> { Thread thread = new Thread(r, "light-overlay-" + threadNumber++); thread.setDaemon(true); return thread; }); private static final List POS = Lists.newCopyOnWriteArrayList(); private static final Map> CHUNK_MAP = Maps.newConcurrentMap(); + private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); private static long ticks = 0; static { ClientTickCallback.EVENT.register(client -> { try { ticks++; - if (MinecraftClient.getInstance().player == null || !enabled) { + if (CLIENT.player == null || !enabled) { POS.clear(); CHUNK_MAP.clear(); } else { - ClientPlayerEntity player = MinecraftClient.getInstance().player; - ClientWorld world = MinecraftClient.getInstance().world; - EntityContext entityContext = EntityContext.of(player); - Vec3d[] playerPos = {null}; - int playerPosX = ((int) player.getX()) >> 4; - int playerPosZ = ((int) player.getZ()) >> 4; - if (ticks % 20 == 0) { - for (int chunkX = playerPosX - getChunkRange(); chunkX <= playerPosX + getChunkRange(); chunkX++) { - for (int chunkZ = playerPosZ - getChunkRange(); chunkZ <= playerPosZ + getChunkRange(); chunkZ++) { - ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); - if (!CHUNK_MAP.containsKey(chunkPos)) - queueChunk(chunkPos); + if (!caching) { + POS.clear(); + CHUNK_MAP.clear(); + ClientPlayerEntity player = CLIENT.player; + ClientWorld world = CLIENT.world; + BlockPos playerPos = player.getBlockPos(); + EntityContext entityContext = EntityContext.of(player); + ChunkLightingView block = world.getLightingProvider().get(LightType.BLOCK); + ChunkLightingView sky = showNumber ? null : world.getLightingProvider().get(LightType.SKY); + BlockPos.Mutable downPos = new BlockPos.Mutable(); + Iterable iterate = BlockPos.iterate(playerPos.getX() - reach, playerPos.getY() - reach, playerPos.getZ() - reach, + playerPos.getX() + reach, playerPos.getY() + reach, playerPos.getZ() + reach); + HashMap map = Maps.newHashMap(); + CHUNK_MAP.put(new ChunkPos(0, 0), map); + for (BlockPos blockPos : iterate) { + downPos.set(blockPos.getX(), blockPos.getY() - 1, blockPos.getZ()); + if (showNumber) { + int level = getCrossLevel(blockPos, downPos, world, block, entityContext); + if (level >= 0) { + map.put(blockPos.asLong(), level); + } + } else { + CrossType type = getCrossType(blockPos, downPos, world, block, sky, entityContext); + if (type != CrossType.NONE) { + map.put(blockPos.asLong(), type); + } } } - } - if (!POS.isEmpty()) { - if (playerPos[0] == null) { - playerPos[0] = player.getPos(); + } else { + ClientPlayerEntity player = CLIENT.player; + ClientWorld world = CLIENT.world; + EntityContext entityContext = EntityContext.of(player); + Vec3d[] playerPos = {null}; + int playerPosX = ((int) player.getX()) >> 4; + int playerPosZ = ((int) player.getZ()) >> 4; + if (ticks % 20 == 0) { + for (int chunkX = playerPosX - getChunkRange(); chunkX <= playerPosX + getChunkRange(); chunkX++) { + for (int chunkZ = playerPosZ - getChunkRange(); chunkZ <= playerPosZ + getChunkRange(); chunkZ++) { + ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); + if (!CHUNK_MAP.containsKey(chunkPos)) + queueChunk(chunkPos); + } + } } - ChunkPos pos = POS.stream().min(Comparator.comparingDouble(value -> value.toBlockPos(8, 0, 8).getSquaredDistance(playerPos[0].x, 0, playerPos[0].z, false))).get(); - EXECUTOR.submit(() -> { - if (MathHelper.abs(pos.x - playerPosX) <= getChunkRange() && MathHelper.abs(pos.z - playerPosZ) <= getChunkRange()) { - calculateChunk(world.getChunkManager().getChunk(pos.x, pos.z, ChunkStatus.FULL, false), world, pos, entityContext); - } else { - CHUNK_MAP.remove(pos); + if (!POS.isEmpty()) { + if (playerPos[0] == null) { + playerPos[0] = player.getPos(); + } + ChunkPos pos = POS.stream().min(Comparator.comparingDouble(value -> value.toBlockPos(8, 0, 8).getSquaredDistance(playerPos[0].x, 0, playerPos[0].z, false))).get(); + POS.remove(pos); + EXECUTOR.submit(() -> { + if (MathHelper.abs(pos.x - playerPosX) <= getChunkRange() && MathHelper.abs(pos.z - playerPosZ) <= getChunkRange()) { + calculateChunk(world.getChunkManager().getChunk(pos.x, pos.z, ChunkStatus.FULL, false), world, pos, entityContext); + } else { + CHUNK_MAP.remove(pos); + } + }); + } + if (ticks % 50 == 0) { + Iterator>> chunkMapIterator = CHUNK_MAP.entrySet().iterator(); + while (chunkMapIterator.hasNext()) { + Map.Entry> pos = chunkMapIterator.next(); + if (MathHelper.abs(pos.getKey().x - playerPosX) > getChunkRange() * 2 || MathHelper.abs(pos.getKey().z - playerPosZ) > getChunkRange() * 2) { + chunkMapIterator.remove(); + } } - }); - POS.remove(pos); - } - Iterator>> chunkMapIterator = CHUNK_MAP.entrySet().iterator(); - while (chunkMapIterator.hasNext()) { - Map.Entry> pos = chunkMapIterator.next(); - if (MathHelper.abs(pos.getKey().x - playerPosX) > getChunkRange() * 2 || MathHelper.abs(pos.getKey().z - playerPosZ) > getChunkRange() * 2) { - chunkMapIterator.remove(); } } } @@ -137,8 +172,9 @@ public class LightOverlay implements ClientModInitializer { } public static void queueChunk(ChunkPos pos) { - if (!POS.contains(pos)) - POS.add(0, pos); + if (caching) + if (!POS.contains(pos)) + POS.add(0, pos); } public static int getChunkRange() { @@ -147,9 +183,9 @@ public class LightOverlay implements ClientModInitializer { private static void calculateChunk(WorldChunk chunk, World world, ChunkPos chunkPos, EntityContext entityContext) { Map map = Maps.newHashMap(); - if (chunk != null) { - ChunkLightingView block = chunk.getLightingProvider().get(LightType.BLOCK); - ChunkLightingView sky = showNumber ? null : chunk.getLightingProvider().get(LightType.SKY); + if (world != null) { + ChunkLightingView block = world.getLightingProvider().get(LightType.BLOCK); + ChunkLightingView sky = showNumber ? null : world.getLightingProvider().get(LightType.SKY); for (BlockPos pos : BlockPos.iterate(chunkPos.getStartX(), 0, chunkPos.getStartZ(), chunkPos.getEndX(), 256, chunkPos.getEndZ())) { BlockPos down = pos.down(); if (showNumber) { @@ -191,11 +227,13 @@ public class LightOverlay implements ClientModInitializer { // Check block state allow spawning (excludes bedrock and barriers automatically) if (!blockBelowState.allowsSpawning(world, down, testingEntityType)) return CrossType.NONE; - if (block.getLightLevel(pos) > crossLevel) + int blockLightLevel = block.getLightLevel(pos); + int skyLightLevel = sky.getLightLevel(pos); + if (blockLightLevel > higherCrossLevel) return CrossType.NONE; - if (sky.getLightLevel(pos) > crossLevel) + if (skyLightLevel > higherCrossLevel) return CrossType.YELLOW; - return CrossType.RED; + return lowerCrossLevel >= 0 && blockLightLevel > lowerCrossLevel ? CrossType.SECONDARY : CrossType.RED; } public static int getCrossLevel(BlockPos pos, BlockPos down, BlockView world, ChunkLightingView view, EntityContext entityContext) { @@ -214,7 +252,7 @@ public class LightOverlay implements ClientModInitializer { return view.getLightLevel(pos); } - public static void renderCross(Tessellator tessellator, BufferBuilder buffer, Camera camera, World world, BlockPos pos, int color, EntityContext entityContext) { + public static void renderCross(Camera camera, World world, BlockPos pos, int color, EntityContext entityContext) { double d0 = camera.getPos().x; double d1 = camera.getPos().y - .005D; VoxelShape upperOutlineShape = world.getBlockState(pos).getOutlineShape(world, pos, entityContext); @@ -222,19 +260,22 @@ public class LightOverlay implements ClientModInitializer { d1 -= upperOutlineShape.getMaximum(Direction.Axis.Y); double d2 = camera.getPos().z; - buffer.begin(1, VertexFormats.POSITION_COLOR); int red = (color >> 16) & 255; int green = (color >> 8) & 255; int blue = color & 255; - buffer.vertex(pos.getX() + .01 - d0, pos.getY() - d1, pos.getZ() + .01 - d2).color(red, green, blue, 255).next(); - buffer.vertex(pos.getX() - .01 + 1 - d0, pos.getY() - d1, pos.getZ() - .01 + 1 - d2).color(red, green, blue, 255).next(); - buffer.vertex(pos.getX() - .01 + 1 - d0, pos.getY() - d1, pos.getZ() + .01 - d2).color(red, green, blue, 255).next(); - buffer.vertex(pos.getX() + .01 - d0, pos.getY() - d1, pos.getZ() - .01 + 1 - d2).color(red, green, blue, 255).next(); - tessellator.draw(); + int x = pos.getX(); + int y = pos.getY(); + int z = pos.getZ(); + RenderSystem.color4f(red / 255f, green / 255f, blue / 255f, 1f); + GL11.glVertex3d(x + .01 - d0, y - d1, z + .01 - d2); + GL11.glVertex3d(x - .01 + 1 - d0, y - d1, z - .01 + 1 - d2); + GL11.glVertex3d(x - .01 + 1 - d0, y - d1, z + .01 - d2); + GL11.glVertex3d(x + .01 - d0, y - d1, z - .01 + 1 - d2); } + @SuppressWarnings("deprecation") public static void renderLevel(MinecraftClient client, Camera camera, World world, BlockPos pos, BlockPos down, int level, EntityContext entityContext) { - String string_1 = String.valueOf(level); + String text = String.valueOf(level); TextRenderer textRenderer_1 = client.textRenderer; double double_4 = camera.getPos().x; double double_5 = camera.getPos().y; @@ -248,11 +289,11 @@ public class LightOverlay implements ClientModInitializer { RenderSystem.normal3f(0.0F, 1.0F, 0.0F); float size = 0.07F; RenderSystem.scalef(-size, -size, size); - float float_3 = (float) (-textRenderer_1.getStringWidth(string_1)) / 2.0F + 0.4f; + float float_3 = (float) (-textRenderer_1.getStringWidth(text)) / 2.0F + 0.4f; RenderSystem.enableAlphaTest(); - VertexConsumerProvider.Immediate vertexConsumerProvider$Immediate_1 = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer()); - textRenderer_1.draw(string_1, float_3, -3.5f, level > crossLevel ? 0xff042404 : 0xff731111, false, Rotation3.identity().getMatrix(), vertexConsumerProvider$Immediate_1, false, 0, 15728880); - vertexConsumerProvider$Immediate_1.draw(); + VertexConsumerProvider.Immediate immediate = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer()); + textRenderer_1.draw(text, float_3, -3.5f, level > higherCrossLevel ? 0xff042404 : (lowerCrossLevel >= 0 && level > lowerCrossLevel ? 0xff0066ff : 0xff731111), false, Rotation3.identity().getMatrix(), immediate, false, 0, 15728880); + immediate.draw(); RenderSystem.popMatrix(); } @@ -260,6 +301,7 @@ public class LightOverlay implements ClientModInitializer { try { redColor = 0xFF0000; yellowColor = 0xFFFF00; + secondaryColor = 0x0000FF; if (!file.exists() || !file.canRead()) saveConfig(file); FileInputStream fis = new FileInputStream(file); @@ -268,6 +310,8 @@ public class LightOverlay implements ClientModInitializer { fis.close(); reach = Integer.parseInt((String) properties.computeIfAbsent("reach", a -> "12")); crossLevel = Integer.parseInt((String) properties.computeIfAbsent("crossLevel", a -> "7")); + secondaryLevel = Integer.parseInt((String) properties.computeIfAbsent("secondaryLevel", a -> "-1")); + caching = ((String) properties.computeIfAbsent("caching", a -> "false")).equalsIgnoreCase("true"); showNumber = ((String) properties.computeIfAbsent("showNumber", a -> "false")).equalsIgnoreCase("true"); smoothLines = ((String) properties.computeIfAbsent("smoothLines", a -> "true")).equalsIgnoreCase("true"); underwater = ((String) properties.computeIfAbsent("underwater", a -> "false")).equalsIgnoreCase("true"); @@ -286,14 +330,24 @@ public class LightOverlay implements ClientModInitializer { b = Integer.parseInt((String) properties.computeIfAbsent("redColorBlue", a -> "0")); redColor = (r << 16) + (g << 8) + b; } + { + int r, g, b; + r = Integer.parseInt((String) properties.computeIfAbsent("secondaryColorRed", a -> "0")); + g = Integer.parseInt((String) properties.computeIfAbsent("secondaryColorGreen", a -> "0")); + b = Integer.parseInt((String) properties.computeIfAbsent("secondaryColorBlue", a -> "255")); + secondaryColor = (r << 16) + (g << 8) + b; + } saveConfig(file); } catch (Exception e) { e.printStackTrace(); reach = 12; crossLevel = 7; + secondaryLevel = -1; lineWidth = 1.0F; redColor = 0xFF0000; yellowColor = 0xFFFF00; + secondaryColor = 0x0000FF; + caching = false; showNumber = false; smoothLines = true; underwater = false; @@ -303,6 +357,9 @@ public class LightOverlay implements ClientModInitializer { ex.printStackTrace(); } } + if (secondaryLevel >= crossLevel) System.err.println("[Light Overlay] Secondary Level is higher than Cross Level"); + lowerCrossLevel = Math.min(crossLevel, secondaryLevel); + higherCrossLevel = Math.max(crossLevel, secondaryLevel); CHUNK_MAP.clear(); POS.clear(); } @@ -315,6 +372,10 @@ public class LightOverlay implements ClientModInitializer { fos.write("\n".getBytes()); fos.write(("crossLevel=" + crossLevel).getBytes()); fos.write("\n".getBytes()); + fos.write(("secondaryLevel=" + secondaryLevel).getBytes()); + fos.write("\n".getBytes()); + fos.write(("caching=" + caching).getBytes()); + fos.write("\n".getBytes()); fos.write(("showNumber=" + showNumber).getBytes()); fos.write("\n".getBytes()); fos.write(("smoothLines=" + smoothLines).getBytes()); @@ -334,9 +395,19 @@ public class LightOverlay implements ClientModInitializer { fos.write(("redColorGreen=" + ((redColor >> 8) & 255)).getBytes()); fos.write("\n".getBytes()); fos.write(("redColorBlue=" + (redColor & 255)).getBytes()); + fos.write("\n".getBytes()); + fos.write(("secondaryColorRed=" + ((secondaryColor >> 16) & 255)).getBytes()); + fos.write("\n".getBytes()); + fos.write(("secondaryColorGreen=" + ((secondaryColor >> 8) & 255)).getBytes()); + fos.write("\n".getBytes()); + fos.write(("secondaryColorBlue=" + (secondaryColor & 255)).getBytes()); fos.close(); } + private static KeyBinding createKeyBinding(Identifier id, InputUtil.Type type, int code, String category) { + return KeyBindingHelper.registerKeyBinding(new KeyBinding("key." + id.getNamespace() + "." + id.getPath(), type, code, category)); + } + @Override public void onInitializeClient() { // Load Config @@ -344,72 +415,25 @@ public class LightOverlay implements ClientModInitializer { // Setup testingEntityType = EntityType.Builder.create(EntityCategory.MONSTER).setDimensions(0f, 0f).disableSaving().build(null); - MinecraftClient client = MinecraftClient.getInstance(); - KeyBindingRegistry.INSTANCE.addCategory(KEYBIND_CATEGORY); - KeyBindingRegistry.INSTANCE.register(enableOverlay = FabricKeyBinding.Builder.create(ENABLE_OVERLAY_KEYBIND, InputUtil.Type.KEYSYM, 296, KEYBIND_CATEGORY).build()); - KeyBindingRegistry.INSTANCE.register(increaseReach = FabricKeyBinding.Builder.create(INCREASE_REACH_KEYBIND, InputUtil.Type.KEYSYM, -1, KEYBIND_CATEGORY).build()); - KeyBindingRegistry.INSTANCE.register(decreaseReach = FabricKeyBinding.Builder.create(DECREASE_REACH_KEYBIND, InputUtil.Type.KEYSYM, -1, KEYBIND_CATEGORY).build()); - KeyBindingRegistry.INSTANCE.register(increaseLineWidth = FabricKeyBinding.Builder.create(INCREASE_LINE_WIDTH_KEYBIND, InputUtil.Type.KEYSYM, -1, KEYBIND_CATEGORY).build()); - KeyBindingRegistry.INSTANCE.register(decreaseLineWidth = FabricKeyBinding.Builder.create(DECREASE_LINE_WIDTH_KEYBIND, InputUtil.Type.KEYSYM, -1, KEYBIND_CATEGORY).build()); - ClothClientHooks.HANDLE_INPUT.register(minecraftClient -> { - while (enableOverlay.wasPressed()) + ClientTickCallback.EVENT.register(minecraftClient -> { + while (ENABLE_OVERLAY.wasPressed()) enabled = !enabled; - while (increaseReach.wasPressed()) { - if (reach < 64) - reach++; - try { - saveConfig(configFile); - } catch (IOException e) { - e.printStackTrace(); - } - client.player.addChatMessage(new TranslatableText("text.lightoverlay.current_reach", reach), false); - } - while (decreaseReach.wasPressed()) { - if (reach > 1) - reach--; - try { - saveConfig(configFile); - } catch (IOException e) { - e.printStackTrace(); - } - client.player.addChatMessage(new TranslatableText("text.lightoverlay.current_reach", reach), false); - } - while (increaseLineWidth.wasPressed()) { - if (lineWidth < 7) - lineWidth += 0.1f; - try { - saveConfig(configFile); - } catch (IOException e) { - e.printStackTrace(); - } - client.player.addChatMessage(new TranslatableText("text.lightoverlay.current_line_width", FORMAT.format(lineWidth)), false); - } - while (decreaseLineWidth.wasPressed()) { - if (lineWidth > 1) - lineWidth -= 0.1F; - try { - saveConfig(configFile); - } catch (IOException e) { - e.printStackTrace(); - } - client.player.addChatMessage(new TranslatableText("text.lightoverlay.current_line_width", FORMAT.format(lineWidth)), false); - } }); ClothClientHooks.DEBUG_RENDER_PRE.register(() -> { if (LightOverlay.enabled) { - PlayerEntity playerEntity = client.player; + PlayerEntity playerEntity = CLIENT.player; int playerPosX = ((int) playerEntity.getX()) >> 4; int playerPosZ = ((int) playerEntity.getZ()) >> 4; EntityContext entityContext = EntityContext.of(playerEntity); - World world = client.world; + World world = CLIENT.world; BlockPos playerPos = new BlockPos(playerEntity.getX(), playerEntity.getY(), playerEntity.getZ()); - Camera camera = MinecraftClient.getInstance().gameRenderer.getCamera(); + Camera camera = CLIENT.gameRenderer.getCamera(); if (showNumber) { RenderSystem.enableTexture(); RenderSystem.depthMask(true); BlockPos.Mutable mutable = new BlockPos.Mutable(); for (Map.Entry> entry : CHUNK_MAP.entrySet()) { - if (MathHelper.abs(entry.getKey().x - playerPosX) > getChunkRange() || MathHelper.abs(entry.getKey().z - playerPosZ) > getChunkRange()) { + if (caching && (MathHelper.abs(entry.getKey().x - playerPosX) > getChunkRange() || MathHelper.abs(entry.getKey().z - playerPosZ) > getChunkRange())) { continue; } for (Map.Entry objectEntry : entry.getValue().entrySet()) { @@ -417,26 +441,23 @@ public class LightOverlay implements ClientModInitializer { mutable.set(BlockPos.unpackLongX(objectEntry.getKey()), BlockPos.unpackLongY(objectEntry.getKey()), BlockPos.unpackLongZ(objectEntry.getKey())); if (mutable.isWithinDistance(playerPos, reach)) { BlockPos down = mutable.down(); - LightOverlay.renderLevel(client, camera, world, mutable, down, (Integer) objectEntry.getValue(), entityContext); + LightOverlay.renderLevel(CLIENT, camera, world, mutable, down, (Integer) objectEntry.getValue(), entityContext); } } } } - RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); RenderSystem.enableDepthTest(); } else { RenderSystem.enableDepthTest(); RenderSystem.disableTexture(); RenderSystem.enableBlend(); RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE_MINUS_SRC_ALPHA); - RenderSystem.disableLighting(); if (smoothLines) GL11.glEnable(GL11.GL_LINE_SMOOTH); - RenderSystem.lineWidth(lineWidth); - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder buffer = tessellator.getBuffer(); + GL11.glLineWidth(lineWidth); + GL11.glBegin(GL11.GL_LINES); BlockPos.Mutable mutable = new BlockPos.Mutable(); for (Map.Entry> entry : CHUNK_MAP.entrySet()) { - if (MathHelper.abs(entry.getKey().x - playerPosX) > getChunkRange() || MathHelper.abs(entry.getKey().z - playerPosZ) > getChunkRange()) { + if (caching && (MathHelper.abs(entry.getKey().x - playerPosX) > getChunkRange() || MathHelper.abs(entry.getKey().z - playerPosZ) > getChunkRange())) { continue; } for (Map.Entry objectEntry : entry.getValue().entrySet()) { @@ -444,12 +465,13 @@ public class LightOverlay implements ClientModInitializer { mutable.set(BlockPos.unpackLongX(objectEntry.getKey()), BlockPos.unpackLongY(objectEntry.getKey()), BlockPos.unpackLongZ(objectEntry.getKey())); if (mutable.isWithinDistance(playerPos, reach)) { BlockPos down = mutable.down(); - int color = objectEntry.getValue() == CrossType.RED ? redColor : yellowColor; - LightOverlay.renderCross(tessellator, buffer, camera, world, mutable, color, entityContext); + int color = objectEntry.getValue() == CrossType.RED ? redColor : objectEntry.getValue() == CrossType.YELLOW ? yellowColor : secondaryColor; + LightOverlay.renderCross(camera, world, mutable, color, entityContext); } } } } + GL11.glEnd(); RenderSystem.disableBlend(); RenderSystem.enableTexture(); if (smoothLines) GL11.glDisable(GL11.GL_LINE_SMOOTH); @@ -461,6 +483,7 @@ public class LightOverlay implements ClientModInitializer { private enum CrossType { YELLOW, RED, + SECONDARY, NONE } } diff --git a/fabric/src/main/java/me/shedaniel/lightoverlay/fabric/mixin/MixinClientConnection.java b/fabric/src/main/java/me/shedaniel/lightoverlay/fabric/mixin/MixinClientConnection.java index 013e3d1..fad16dc 100644 --- a/fabric/src/main/java/me/shedaniel/lightoverlay/fabric/mixin/MixinClientConnection.java +++ b/fabric/src/main/java/me/shedaniel/lightoverlay/fabric/mixin/MixinClientConnection.java @@ -7,6 +7,7 @@ import net.minecraft.network.listener.PacketListener; import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket; import net.minecraft.network.packet.s2c.play.ChunkDataS2CPacket; import net.minecraft.network.packet.s2c.play.ChunkDeltaUpdateS2CPacket; +import net.minecraft.network.packet.s2c.play.LightUpdateS2CPacket; import net.minecraft.util.math.ChunkPos; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -23,6 +24,8 @@ public class MixinClientConnection { LightOverlay.queueChunkAndNear(new ChunkPos(((ChunkDataS2CPacket) packet).getX(), ((ChunkDataS2CPacket) packet).getZ())); } else if (packet instanceof ChunkDeltaUpdateS2CPacket) { LightOverlay.queueChunkAndNear(new ChunkPos(((ChunkDeltaUpdateS2CPacket) packet).chunkPos.x, ((ChunkDeltaUpdateS2CPacket) packet).chunkPos.z)); + } else if (packet instanceof LightUpdateS2CPacket) { + LightOverlay.queueChunk(new ChunkPos(((LightUpdateS2CPacket) packet).getChunkX(), ((LightUpdateS2CPacket) packet).getChunkZ())); } } } diff --git a/fabric/src/main/resources/assets/lightoverlay/lang/en_us.json b/fabric/src/main/resources/assets/lightoverlay/lang/en_us.json index 4d55bbc..5346550 100755 --- a/fabric/src/main/resources/assets/lightoverlay/lang/en_us.json +++ b/fabric/src/main/resources/assets/lightoverlay/lang/en_us.json @@ -1,20 +1,18 @@ { "key.lightoverlay.category": "Light Overlay", "key.lightoverlay.enable_overlay": "Toggle Light Overlay", - "key.lightoverlay.decrease_reach": "Decrease Light Overlay's Reach", - "key.lightoverlay.increase_reach": "Increase Light Overlay's Reach", - "key.lightoverlay.increase_line_width": "Increase Light Overlay's Line Width", - "key.lightoverlay.decrease_line_width": "Decrease Light Overlay's Line Width", - "text.lightoverlay.current_reach": "The current reach is %d!", - "text.lightoverlay.current_line_width": "The current line width is %s!", + "description.lightoverlay.caching": "Caching is recommended if the reach is above 16 or if you are running on a potato.", "config.lightoverlay.general": "General", "config.lightoverlay.reach": "Reach:", + "config.lightoverlay.caching": "Caching:", "config.lightoverlay.crossLevel": "Light Level:", + "config.lightoverlay.secondaryLevel": "Secondary Light Level:", "config.lightoverlay.showNumber": "Show Number Instead:", "config.lightoverlay.smoothLines": "Smooth Lines:", "config.lightoverlay.underwater": "Display Underwater:", "config.lightoverlay.lineWidth": "Line Width:", "config.lightoverlay.yellowColor": "Yellow Color:", + "config.lightoverlay.secondaryColor": "Secondary Color:", "config.lightoverlay.redColor": "Red Color:", "config.lightoverlay.invalidColor": "Invalid Color" } \ No newline at end of file diff --git a/forge/src/main/java/me/shedaniel/lightoverlay/forge/LightOverlayClient.java b/forge/src/main/java/me/shedaniel/lightoverlay/forge/LightOverlayClient.java index a9c36c8..62d5d72 100644 --- a/forge/src/main/java/me/shedaniel/lightoverlay/forge/LightOverlayClient.java +++ b/forge/src/main/java/me/shedaniel/lightoverlay/forge/LightOverlayClient.java @@ -2,14 +2,17 @@ package me.shedaniel.lightoverlay.forge; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.client.gui.FontRenderer; -import net.minecraft.client.renderer.*; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.client.renderer.ActiveRenderInfo; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.TransformationMatrix; import net.minecraft.client.settings.KeyBinding; import net.minecraft.client.util.InputMappings; import net.minecraft.client.world.ClientWorld; @@ -20,6 +23,7 @@ import net.minecraft.network.IPacket; import net.minecraft.network.play.server.SChangeBlockPacket; import net.minecraft.network.play.server.SChunkDataPacket; import net.minecraft.network.play.server.SMultiBlockChangePacket; +import net.minecraft.network.play.server.SUpdateLightPacket; import net.minecraft.tags.BlockTags; import net.minecraft.util.Direction; import net.minecraft.util.ResourceLocation; @@ -29,7 +33,6 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; -import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.world.IBlockReader; import net.minecraft.world.LightType; import net.minecraft.world.World; @@ -61,23 +64,23 @@ import java.util.concurrent.Executors; public class LightOverlayClient { static final DecimalFormat FORMAT = new DecimalFormat("#.#"); - private static final String KEYBIND_CATEGORY = "key.lightoverlay-forge.category"; - private static final ResourceLocation ENABLE_OVERLAY_KEYBIND = new ResourceLocation("lightoverlay-forge", "enable_overlay"); - private static final ResourceLocation INCREASE_REACH_KEYBIND = new ResourceLocation("lightoverlay-forge", "increase_reach"); - private static final ResourceLocation DECREASE_REACH_KEYBIND = new ResourceLocation("lightoverlay-forge", "decrease_reach"); - private static final ResourceLocation INCREASE_LINE_WIDTH_KEYBIND = new ResourceLocation("lightoverlay-forge", "increase_line_width"); - private static final ResourceLocation DECREASE_LINE_WIDTH_KEYBIND = new ResourceLocation("lightoverlay-forge", "decrease_line_width"); + private static final String KEYBIND_CATEGORY = "key.lightoverlay.category"; + private static final ResourceLocation ENABLE_OVERLAY_KEYBIND = new ResourceLocation("lightoverlay", "enable_overlay"); static int reach = 12; static int crossLevel = 7; + static int secondaryLevel = -1; + static int lowerCrossLevel = -1; + static int higherCrossLevel = -1; + static boolean caching = false; static boolean showNumber = false; static boolean smoothLines = true; static boolean underwater = false; - static EntityType testingEntityType; static float lineWidth = 1.0F; - static int yellowColor = 0xFFFF00, redColor = 0xFF0000; + static int yellowColor = 0xFFFF00, redColor = 0xFF0000, secondaryColor = 0x0000FF; static File configFile = new File(new File(Minecraft.getInstance().gameDir, "config"), "lightoverlay.properties"); - private static KeyBinding enableOverlay, increaseReach, decreaseReach, increaseLineWidth, decreaseLineWidth; + private static final KeyBinding ENABLE_OVERLAY; private static boolean enabled = false; + private static EntityType testingEntityType; private static int threadNumber = 0; private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), r -> { Thread thread = new Thread(r, "light-overlay-" + threadNumber++); @@ -88,17 +91,16 @@ public class LightOverlayClient { private static final Map> CHUNK_MAP = Maps.newConcurrentMap(); private static long ticks = 0; + static { + ENABLE_OVERLAY = registerKeybind(ENABLE_OVERLAY_KEYBIND, InputMappings.Type.KEYSYM, 296, KEYBIND_CATEGORY); + } + public static void register() { // Load Config loadConfig(configFile); // Setup testingEntityType = EntityType.Builder.create(EntityClassification.MONSTER).size(0f, 0f).disableSerialization().build(null); - enableOverlay = registerKeybind(ENABLE_OVERLAY_KEYBIND, InputMappings.Type.KEYSYM, 296, KEYBIND_CATEGORY); - increaseReach = registerKeybind(INCREASE_REACH_KEYBIND, InputMappings.Type.KEYSYM, -1, KEYBIND_CATEGORY); - decreaseReach = registerKeybind(DECREASE_REACH_KEYBIND, InputMappings.Type.KEYSYM, -1, KEYBIND_CATEGORY); - increaseLineWidth = registerKeybind(INCREASE_LINE_WIDTH_KEYBIND, InputMappings.Type.KEYSYM, -1, KEYBIND_CATEGORY); - decreaseLineWidth = registerKeybind(DECREASE_LINE_WIDTH_KEYBIND, InputMappings.Type.KEYSYM, -1, KEYBIND_CATEGORY); MinecraftForge.EVENT_BUS.register(LightOverlayClient.class); try { @@ -115,7 +117,6 @@ public class LightOverlayClient { VoxelShape upperCollisionShape = blockUpperState.getCollisionShape(reader, pos, selectionContext); if (!underwater && !blockUpperState.getFluidState().isEmpty()) return CrossType.NONE; - /* WorldEntitySpawner.func_222266_a */ // Check if the outline is full if (Block.doesSideFillSquare(upperCollisionShape, Direction.UP)) return CrossType.NONE; @@ -130,11 +131,13 @@ public class LightOverlayClient { // Check block state allow spawning (excludes bedrock and barriers automatically) if (!blockBelowState.canEntitySpawn(reader, down, testingEntityType)) return CrossType.NONE; - if (block.getLightFor(pos) > crossLevel) + int blockLightLevel = block.getLightFor(pos); + int skyLightLevel = sky.getLightFor(pos); + if (blockLightLevel > higherCrossLevel) return CrossType.NONE; - if (sky.getLightFor(pos) > crossLevel) + if (skyLightLevel > higherCrossLevel) return CrossType.YELLOW; - return CrossType.RED; + return lowerCrossLevel >= 0 && blockLightLevel > lowerCrossLevel ? CrossType.SECONDARY : CrossType.RED; } public static int getCrossLevel(BlockPos pos, BlockPos down, IBlockReader reader, IWorldLightListener light, ISelectionContext context) { @@ -153,22 +156,24 @@ public class LightOverlayClient { return light.getLightFor(pos); } - public static void renderCross(ActiveRenderInfo info, Tessellator tessellator, BufferBuilder buffer, World world, BlockPos pos, int color, ISelectionContext context) { + public static void renderCross(ActiveRenderInfo info, World world, BlockPos pos, int color, ISelectionContext context) { double d0 = info.getProjectedView().x; double d1 = info.getProjectedView().y - .005D; VoxelShape upperOutlineShape = world.getBlockState(pos).getShape(world, pos, context); if (!upperOutlineShape.isEmpty()) d1 -= upperOutlineShape.getEnd(Direction.Axis.Y); double d2 = info.getProjectedView().z; - buffer.begin(1, DefaultVertexFormats.POSITION_COLOR); int red = (color >> 16) & 255; int green = (color >> 8) & 255; int blue = color & 255; - buffer.pos(pos.getX() + .01 - d0, pos.getY() - d1, pos.getZ() + .01 - d2).color(red, green, blue, 255).endVertex(); - buffer.pos(pos.getX() - .01 + 1 - d0, pos.getY() - d1, pos.getZ() - .01 + 1 - d2).color(red, green, blue, 255).endVertex(); - buffer.pos(pos.getX() - .01 + 1 - d0, pos.getY() - d1, pos.getZ() + .01 - d2).color(red, green, blue, 255).endVertex(); - buffer.pos(pos.getX() + .01 - d0, pos.getY() - d1, pos.getZ() - .01 + 1 - d2).color(red, green, blue, 255).endVertex(); - tessellator.draw(); + int x = pos.getX(); + int y = pos.getY(); + int z = pos.getZ(); + RenderSystem.color4f(red / 255f, green / 255f, blue / 255f, 1f); + GL11.glVertex3d(x + .01 - d0, y - d1, z + .01 - d2); + GL11.glVertex3d(x - .01 + 1 - d0, y - d1, z - .01 + 1 - d2); + GL11.glVertex3d(x - .01 + 1 - d0, y - d1, z + .01 - d2); + GL11.glVertex3d(x + .01 - d0, y - d1, z - .01 + 1 - d2); } public static void renderLevel(Minecraft minecraft, ActiveRenderInfo info, World world, BlockPos pos, BlockPos down, int level, ISelectionContext context) { @@ -189,55 +194,15 @@ public class LightOverlayClient { float float_3 = (float) (-fontRenderer.getStringWidth(string_1)) / 2.0F + 0.4f; RenderSystem.enableAlphaTest(); IRenderTypeBuffer.Impl vertexConsumerProvider$Immediate_1 = IRenderTypeBuffer.getImpl(Tessellator.getInstance().getBuffer()); - fontRenderer.renderString(string_1, float_3, -3.5f, level > crossLevel ? 0xff042404 : 0xff731111, false, TransformationMatrix.identity().getMatrix(), vertexConsumerProvider$Immediate_1, false, 0, 15728880); + fontRenderer.renderString(string_1, float_3, -3.5f, level > higherCrossLevel ? 0xff042404 : (lowerCrossLevel >= 0 && level > lowerCrossLevel ? 0xff0066ff : 0xff731111), false, TransformationMatrix.identity().getMatrix(), vertexConsumerProvider$Immediate_1, false, 0, 15728880); vertexConsumerProvider$Immediate_1.finish(); RenderSystem.popMatrix(); } @SubscribeEvent(receiveCanceled = true) public static void handleInput(InputEvent.KeyInputEvent event) { - if (enableOverlay.isPressed()) + if (ENABLE_OVERLAY.isPressed()) enabled = !enabled; - if (increaseReach.isPressed()) { - if (reach < 64) - reach++; - try { - saveConfig(configFile); - } catch (IOException e) { - e.printStackTrace(); - } - Minecraft.getInstance().player.sendStatusMessage(new TranslationTextComponent("text.lightoverlay-forge.current_reach", reach), false); - } - if (decreaseReach.isPressed()) { - if (reach > 1) - reach--; - try { - saveConfig(configFile); - } catch (IOException e) { - e.printStackTrace(); - } - Minecraft.getInstance().player.sendStatusMessage(new TranslationTextComponent("text.lightoverlay-forge.current_reach", reach), false); - } - if (increaseLineWidth.isPressed()) { - if (lineWidth < 7) - lineWidth += 0.1f; - try { - saveConfig(configFile); - } catch (IOException e) { - e.printStackTrace(); - } - Minecraft.getInstance().player.sendStatusMessage(new TranslationTextComponent("text.lightoverlay-forge.current_line_width", FORMAT.format(lineWidth)), false); - } - if (decreaseLineWidth.isPressed()) { - if (lineWidth > 1) - lineWidth -= 0.1F; - try { - saveConfig(configFile); - } catch (IOException e) { - e.printStackTrace(); - } - Minecraft.getInstance().player.sendStatusMessage(new TranslationTextComponent("text.lightoverlay-forge.current_line_width", FORMAT.format(lineWidth)), false); - } } public static void queueChunkAndNear(ChunkPos pos) { @@ -249,8 +214,9 @@ public class LightOverlayClient { } public static void queueChunk(ChunkPos pos) { - if (!POS.contains(pos)) - POS.add(0, pos); + if (caching) + if (!POS.contains(pos)) + POS.add(0, pos); } public static int getChunkRange() { @@ -267,40 +233,72 @@ public class LightOverlayClient { POS.clear(); CHUNK_MAP.clear(); } else { - ClientPlayerEntity player = minecraft.player; - ClientWorld world = minecraft.world; - ISelectionContext selectionContext = ISelectionContext.forEntity(player); - Vec3d[] playerPos = {null}; - int playerPosX = ((int) player.getPosX()) >> 4; - int playerPosZ = ((int) player.getPosZ()) >> 4; - if (ticks % 20 == 0) { - for (int chunkX = playerPosX - getChunkRange(); chunkX <= playerPosX + getChunkRange(); chunkX++) { - for (int chunkZ = playerPosZ - getChunkRange(); chunkZ <= playerPosZ + getChunkRange(); chunkZ++) { - ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); - if (!CHUNK_MAP.containsKey(chunkPos)) - queueChunk(chunkPos); + if (!caching) { + POS.clear(); + CHUNK_MAP.clear(); + ClientPlayerEntity player = minecraft.player; + ClientWorld world = minecraft.world; + BlockPos playerPos = player.getPosition(); + ISelectionContext entityContext = ISelectionContext.forEntity(player); + IWorldLightListener block = world.getLightManager().getLightEngine(LightType.BLOCK); + IWorldLightListener sky = showNumber ? null : world.getLightManager().getLightEngine(LightType.SKY); + BlockPos.Mutable downPos = new BlockPos.Mutable(); + Iterable iterate = BlockPos.getAllInBoxMutable(playerPos.getX() - reach, playerPos.getY() - reach, playerPos.getZ() - reach, + playerPos.getX() + reach, playerPos.getY() + reach, playerPos.getZ() + reach); + HashMap map = Maps.newHashMap(); + CHUNK_MAP.put(new ChunkPos(0, 0), map); + for (BlockPos blockPos : iterate) { + downPos.setPos(blockPos.getX(), blockPos.getY() - 1, blockPos.getZ()); + if (showNumber) { + int level = getCrossLevel(blockPos, downPos, world, block, entityContext); + if (level >= 0) { + map.put(blockPos.toLong(), level); + } + } else { + CrossType type = getCrossType(blockPos, downPos, world, block, sky, entityContext); + if (type != CrossType.NONE) { + map.put(blockPos.toLong(), type); + } } } - } - if (!POS.isEmpty()) { - if (playerPos[0] == null) { - playerPos[0] = player.getPositionVec(); + } else { + ClientPlayerEntity player = minecraft.player; + ClientWorld world = minecraft.world; + ISelectionContext selectionContext = ISelectionContext.forEntity(player); + Vec3d[] playerPos = {null}; + int playerPosX = ((int) player.getPosX()) >> 4; + int playerPosZ = ((int) player.getPosZ()) >> 4; + if (ticks % 20 == 0) { + for (int chunkX = playerPosX - getChunkRange(); chunkX <= playerPosX + getChunkRange(); chunkX++) { + for (int chunkZ = playerPosZ - getChunkRange(); chunkZ <= playerPosZ + getChunkRange(); chunkZ++) { + ChunkPos chunkPos = new ChunkPos(chunkX, chunkZ); + if (!CHUNK_MAP.containsKey(chunkPos)) + queueChunk(chunkPos); + } + } } - ChunkPos pos = POS.stream().min(Comparator.comparingDouble(value -> value.getBlock(8, 0, 8).distanceSq(playerPos[0].x, 0, playerPos[0].z, false))).get(); - EXECUTOR.submit(() -> { - if (MathHelper.abs(pos.x - playerPosX) <= getChunkRange() && MathHelper.abs(pos.z - playerPosZ) <= getChunkRange()) { - calculateChunk(world.getChunkProvider().getChunk(pos.x, pos.z, ChunkStatus.FULL, false), world, pos, selectionContext); - } else { - CHUNK_MAP.remove(pos); + if (!POS.isEmpty()) { + if (playerPos[0] == null) { + playerPos[0] = player.getPositionVec(); + } + ChunkPos pos = POS.stream().min(Comparator.comparingDouble(value -> value.getBlock(8, 0, 8).distanceSq(playerPos[0].x, 0, playerPos[0].z, false))).get(); + EXECUTOR.submit(() -> { + if (MathHelper.abs(pos.x - playerPosX) <= getChunkRange() && MathHelper.abs(pos.z - playerPosZ) <= getChunkRange()) { + calculateChunk(world.getChunkProvider().getChunk(pos.x, pos.z, ChunkStatus.FULL, false), world, pos, selectionContext); + } else { + CHUNK_MAP.remove(pos); + } + }); + POS.remove(pos); + } + if (ticks % 50 == 0) { + Iterator>> chunkMapIterator = CHUNK_MAP.entrySet().iterator(); + while (chunkMapIterator.hasNext()) { + Map.Entry> pos = chunkMapIterator.next(); + if (MathHelper.abs(pos.getKey().x - playerPosX) > getChunkRange() * 2 || MathHelper.abs(pos.getKey().z - playerPosZ) > getChunkRange() * 2) { + chunkMapIterator.remove(); + } } - }); - POS.remove(pos); - } - Iterator>> chunkMapIterator = CHUNK_MAP.entrySet().iterator(); - while (chunkMapIterator.hasNext()) { - Map.Entry> pos = chunkMapIterator.next(); - if (MathHelper.abs(pos.getKey().x - playerPosX) > getChunkRange() * 2 || MathHelper.abs(pos.getKey().z - playerPosZ) > getChunkRange() * 2) { - chunkMapIterator.remove(); } } } @@ -352,7 +350,7 @@ public class LightOverlayClient { RenderSystem.depthMask(true); BlockPos.Mutable mutable = new BlockPos.Mutable(); for (Map.Entry> entry : CHUNK_MAP.entrySet()) { - if (MathHelper.abs(entry.getKey().x - playerPosX) > getChunkRange() || MathHelper.abs(entry.getKey().z - playerPosZ) > getChunkRange()) { + if (caching && (MathHelper.abs(entry.getKey().x - playerPosX) > getChunkRange() || MathHelper.abs(entry.getKey().z - playerPosZ) > getChunkRange())) { continue; } for (Map.Entry objectEntry : entry.getValue().entrySet()) { @@ -369,18 +367,15 @@ public class LightOverlayClient { RenderSystem.enableDepthTest(); } else { RenderSystem.enableDepthTest(); - RenderSystem.shadeModel(7425); - RenderSystem.enableAlphaTest(); - RenderSystem.defaultAlphaFunc(); RenderSystem.disableTexture(); - RenderSystem.disableBlend(); + RenderSystem.enableBlend(); + RenderSystem.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA); if (smoothLines) GL11.glEnable(GL11.GL_LINE_SMOOTH); - RenderSystem.lineWidth(lineWidth); - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder buffer = tessellator.getBuffer(); + GL11.glLineWidth(lineWidth); + GL11.glBegin(GL11.GL_LINES); BlockPos.Mutable mutable = new BlockPos.Mutable(); for (Map.Entry> entry : CHUNK_MAP.entrySet()) { - if (MathHelper.abs(entry.getKey().x - playerPosX) > getChunkRange() || MathHelper.abs(entry.getKey().z - playerPosZ) > getChunkRange()) { + if (caching && (MathHelper.abs(entry.getKey().x - playerPosX) > getChunkRange() || MathHelper.abs(entry.getKey().z - playerPosZ) > getChunkRange())) { continue; } for (Map.Entry objectEntry : entry.getValue().entrySet()) { @@ -388,15 +383,15 @@ public class LightOverlayClient { mutable.setPos(BlockPos.unpackX(objectEntry.getKey()), BlockPos.unpackY(objectEntry.getKey()), BlockPos.unpackZ(objectEntry.getKey())); if (mutable.withinDistance(playerPos, reach)) { BlockPos down = mutable.down(); - int color = objectEntry.getValue() == CrossType.RED ? redColor : yellowColor; - LightOverlayClient.renderCross(info, tessellator, buffer, world, mutable, color, selectionContext); + int color = objectEntry.getValue() == CrossType.RED ? redColor : objectEntry.getValue() == CrossType.YELLOW ? yellowColor : secondaryColor; + renderCross(info, world, mutable, color, selectionContext); } } } } - RenderSystem.enableBlend(); + GL11.glEnd(); + RenderSystem.disableBlend(); RenderSystem.enableTexture(); - RenderSystem.shadeModel(7424); if (smoothLines) GL11.glDisable(GL11.GL_LINE_SMOOTH); } RenderSystem.popMatrix(); @@ -413,6 +408,7 @@ public class LightOverlayClient { try { redColor = 0xFF0000; yellowColor = 0xFFFF00; + secondaryColor = 0x0000FF; if (!file.exists() || !file.canRead()) saveConfig(file); FileInputStream fis = new FileInputStream(file); @@ -421,6 +417,8 @@ public class LightOverlayClient { fis.close(); reach = Integer.parseInt((String) properties.computeIfAbsent("reach", a -> "12")); crossLevel = Integer.parseInt((String) properties.computeIfAbsent("crossLevel", a -> "7")); + secondaryLevel = Integer.parseInt((String) properties.computeIfAbsent("secondaryLevel", a -> "-1")); + caching = ((String) properties.computeIfAbsent("caching", a -> "false")).equalsIgnoreCase("true"); showNumber = ((String) properties.computeIfAbsent("showNumber", a -> "false")).equalsIgnoreCase("true"); smoothLines = ((String) properties.computeIfAbsent("smoothLines", a -> "true")).equalsIgnoreCase("true"); underwater = ((String) properties.computeIfAbsent("underwater", a -> "false")).equalsIgnoreCase("true"); @@ -439,13 +437,24 @@ public class LightOverlayClient { b = Integer.parseInt((String) properties.computeIfAbsent("redColorBlue", a -> "0")); redColor = (r << 16) + (g << 8) + b; } + { + int r, g, b; + r = Integer.parseInt((String) properties.computeIfAbsent("secondaryColorRed", a -> "0")); + g = Integer.parseInt((String) properties.computeIfAbsent("secondaryColorGreen", a -> "0")); + b = Integer.parseInt((String) properties.computeIfAbsent("secondaryColorBlue", a -> "255")); + secondaryColor = (r << 16) + (g << 8) + b; + } saveConfig(file); } catch (Exception e) { e.printStackTrace(); reach = 12; + crossLevel = 7; + secondaryLevel = -1; lineWidth = 1.0F; redColor = 0xFF0000; yellowColor = 0xFFFF00; + secondaryColor = 0x0000FF; + caching = false; showNumber = false; smoothLines = true; underwater = false; @@ -455,6 +464,11 @@ public class LightOverlayClient { ex.printStackTrace(); } } + if (secondaryLevel >= crossLevel) System.err.println("[Light Overlay] Secondary Level is higher than Cross Level"); + lowerCrossLevel = Math.min(crossLevel, secondaryLevel); + higherCrossLevel = Math.max(crossLevel, secondaryLevel); + CHUNK_MAP.clear(); + POS.clear(); } static void saveConfig(File file) throws IOException { @@ -465,6 +479,10 @@ public class LightOverlayClient { fos.write("\n".getBytes()); fos.write(("crossLevel=" + crossLevel).getBytes()); fos.write("\n".getBytes()); + fos.write(("secondaryLevel=" + secondaryLevel).getBytes()); + fos.write("\n".getBytes()); + fos.write(("caching=" + caching).getBytes()); + fos.write("\n".getBytes()); fos.write(("showNumber=" + showNumber).getBytes()); fos.write("\n".getBytes()); fos.write(("smoothLines=" + smoothLines).getBytes()); @@ -484,6 +502,12 @@ public class LightOverlayClient { fos.write(("redColorGreen=" + ((redColor >> 8) & 255)).getBytes()); fos.write("\n".getBytes()); fos.write(("redColorBlue=" + (redColor & 255)).getBytes()); + fos.write("\n".getBytes()); + fos.write(("secondaryColorRed=" + ((secondaryColor >> 16) & 255)).getBytes()); + fos.write("\n".getBytes()); + fos.write(("secondaryColorGreen=" + ((secondaryColor >> 8) & 255)).getBytes()); + fos.write("\n".getBytes()); + fos.write(("secondaryColorBlue=" + (secondaryColor & 255)).getBytes()); fos.close(); } @@ -495,12 +519,15 @@ public class LightOverlayClient { } else if (packet instanceof SMultiBlockChangePacket) { ChunkPos chunkPos = ObfuscationReflectionHelper.getPrivateValue(SMultiBlockChangePacket.class, (SMultiBlockChangePacket) packet, "field_148925_b"); LightOverlayClient.queueChunkAndNear(new ChunkPos(chunkPos.x, chunkPos.z)); + } else if (packet instanceof SUpdateLightPacket) { + LightOverlayClient.queueChunkAndNear(new ChunkPos(((SUpdateLightPacket) packet).getChunkX(), ((SUpdateLightPacket) packet).getChunkZ())); } } private enum CrossType { YELLOW, RED, + SECONDARY, NONE } } diff --git a/forge/src/main/java/me/shedaniel/lightoverlay/forge/LightOverlayCloth.java b/forge/src/main/java/me/shedaniel/lightoverlay/forge/LightOverlayCloth.java index 3c22c9e..cbfb1a4 100644 --- a/forge/src/main/java/me/shedaniel/lightoverlay/forge/LightOverlayCloth.java +++ b/forge/src/main/java/me/shedaniel/lightoverlay/forge/LightOverlayCloth.java @@ -3,25 +3,38 @@ package me.shedaniel.lightoverlay.forge; import me.shedaniel.forge.clothconfig2.api.ConfigBuilder; import me.shedaniel.forge.clothconfig2.api.ConfigCategory; import me.shedaniel.forge.clothconfig2.api.ConfigEntryBuilder; +import me.shedaniel.forge.clothconfig2.gui.entries.IntegerSliderEntry; +import net.minecraft.client.resources.I18n; import net.minecraft.util.math.MathHelper; import net.minecraftforge.fml.ExtensionPoint; import net.minecraftforge.fml.ModLoadingContext; +import java.util.Optional; + public class LightOverlayCloth { public static void register() { ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.CONFIGGUIFACTORY, () -> (client, parent) -> { ConfigBuilder builder = ConfigBuilder.create().setParentScreen(parent).setTitle("key.lightoverlay.category"); ConfigEntryBuilder eb = builder.getEntryBuilder(); - ConfigCategory general = builder.getOrCreateCategory("config.lightoverlay-forge.general"); - general.addEntry(eb.startIntSlider("config.lightoverlay-forge.reach", LightOverlayClient.reach, 1, 64).setDefaultValue(12).setTextGetter(integer -> "Reach: " + integer + " Blocks").setSaveConsumer(integer -> LightOverlayClient.reach = integer).build()); - general.addEntry(eb.startIntSlider("config.lightoverlay-forge.crossLevel", LightOverlayClient.crossLevel, 0, 15).setDefaultValue(7).setTextGetter(integer -> "Cross Level: " + integer).setSaveConsumer(integer -> LightOverlayClient.crossLevel = integer).build()); - general.addEntry(eb.startBooleanToggle("config.lightoverlay-forge.showNumber", LightOverlayClient.showNumber).setDefaultValue(false).setSaveConsumer(bool -> LightOverlayClient.showNumber = bool).build()); - general.addEntry(eb.startBooleanToggle("config.lightoverlay-forge.smoothLines", LightOverlayClient.smoothLines).setDefaultValue(true).setSaveConsumer(bool -> LightOverlayClient.smoothLines = bool).build()); - general.addEntry(eb.startBooleanToggle("config.lightoverlay-forge.underwater", LightOverlayClient.underwater).setDefaultValue(false).setSaveConsumer(bool -> LightOverlayClient.underwater = bool).build()); - general.addEntry(eb.startIntSlider("config.lightoverlay-forge.lineWidth", MathHelper.floor(LightOverlayClient.lineWidth * 100), 100, 700).setDefaultValue(100).setTextGetter(integer -> "Light Width: " + LightOverlayClient.FORMAT.format(integer / 100d)).setSaveConsumer(integer -> LightOverlayClient.lineWidth = integer / 100f).build()); - general.addEntry(eb.startColorField("config.lightoverlay-forge.yellowColor", LightOverlayClient.yellowColor).setDefaultValue(0xFFFF00).setSaveConsumer(color -> LightOverlayClient.yellowColor = color).build()); - general.addEntry(eb.startColorField("config.lightoverlay-forge.redColor", LightOverlayClient.redColor).setDefaultValue(0xFF0000).setSaveConsumer(color -> LightOverlayClient.redColor = color).build()); + ConfigCategory general = builder.getOrCreateCategory("config.lightoverlay.general"); + general.addEntry(eb.startTextDescription("§7" + I18n.format("description.lightoverlay.caching")).build()); + general.addEntry(eb.startBooleanToggle("config.lightoverlay.caching", LightOverlayClient.caching).setDefaultValue(false).setSaveConsumer(bool -> LightOverlayClient.caching = bool).build()); + general.addEntry(eb.startIntSlider("config.lightoverlay.reach", LightOverlayClient.reach, 1, 64).setDefaultValue(12).setTextGetter(integer -> "Reach: " + integer + " Blocks").setSaveConsumer(integer -> LightOverlayClient.reach = integer).build()); + IntegerSliderEntry crossLevel = eb.startIntSlider("config.lightoverlay.crossLevel", LightOverlayClient.crossLevel, 0, 15).setDefaultValue(7).setTextGetter(integer -> "Cross Level: " + integer).setSaveConsumer(integer -> LightOverlayClient.crossLevel = integer).build(); + general.addEntry(crossLevel); + general.addEntry(eb.startIntSlider("config.lightoverlay.secondaryLevel", LightOverlayClient.secondaryLevel, -1, 15) + .setErrorSupplier(integer -> { + if (integer >= 0 && integer >= crossLevel.getValue()) return Optional.of("Secondary Level cannot be higher than Cross Level!"); + return Optional.empty(); + }).setDefaultValue(-1).setTextGetter(integer -> integer < 0 ? "Off" : "Level: " + integer).setSaveConsumer(integer -> LightOverlayClient.secondaryLevel = integer).build()); + general.addEntry(eb.startBooleanToggle("config.lightoverlay.showNumber", LightOverlayClient.showNumber).setDefaultValue(false).setSaveConsumer(bool -> LightOverlayClient.showNumber = bool).build()); + general.addEntry(eb.startBooleanToggle("config.lightoverlay.smoothLines", LightOverlayClient.smoothLines).setDefaultValue(true).setSaveConsumer(bool -> LightOverlayClient.smoothLines = bool).build()); + general.addEntry(eb.startBooleanToggle("config.lightoverlay.underwater", LightOverlayClient.underwater).setDefaultValue(false).setSaveConsumer(bool -> LightOverlayClient.underwater = bool).build()); + general.addEntry(eb.startIntSlider("config.lightoverlay.lineWidth", MathHelper.floor(LightOverlayClient.lineWidth * 100), 100, 700).setDefaultValue(100).setTextGetter(integer -> "Light Width: " + LightOverlayClient.FORMAT.format(integer / 100d)).setSaveConsumer(integer -> LightOverlayClient.lineWidth = integer / 100f).build()); + general.addEntry(eb.startColorField("config.lightoverlay.yellowColor", LightOverlayClient.yellowColor).setDefaultValue(0xFFFF00).setSaveConsumer(color -> LightOverlayClient.yellowColor = color).build()); + general.addEntry(eb.startColorField("config.lightoverlay.redColor", LightOverlayClient.redColor).setDefaultValue(0xFF0000).setSaveConsumer(color -> LightOverlayClient.redColor = color).build()); + general.addEntry(eb.startColorField("config.lightoverlay.secondaryColor", LightOverlayClient.secondaryColor).setDefaultValue(0x0000FF).setSaveConsumer(color -> LightOverlayClient.secondaryColor = color).build()); return builder.setSavingRunnable(() -> { try { diff --git a/forge/src/main/resources/META-INF/NetworkManager.js b/forge/src/main/resources/META-INF/NetworkManager.js index 134c427..6f586f1 100644 --- a/forge/src/main/resources/META-INF/NetworkManager.js +++ b/forge/src/main/resources/META-INF/NetworkManager.js @@ -23,7 +23,7 @@ function initializeCoreMod() { if (instruction instanceof LabelNode) { instructions.insertBefore(instruction, new LabelNode()); instructions.insertBefore(instruction, new VarInsnNode(Opcodes.ALOAD, 0)); - instructions.insertBefore(instruction, new MethodInsnNode(Opcodes.INVOKESTATIC, "me/shedaniel/lightoverlay/LightOverlay", "processPacket", "(Lnet/minecraft/network/IPacket;)V", false)); + instructions.insertBefore(instruction, new MethodInsnNode(Opcodes.INVOKESTATIC, "me/shedaniel/lightoverlay/forge/LightOverlay", "processPacket", "(Lnet/minecraft/network/IPacket;)V", false)); break; } } diff --git a/forge/src/main/resources/META-INF/WorldRenderer.js b/forge/src/main/resources/META-INF/WorldRenderer.js index 0282268..8ec0e75 100644 --- a/forge/src/main/resources/META-INF/WorldRenderer.js +++ b/forge/src/main/resources/META-INF/WorldRenderer.js @@ -23,7 +23,7 @@ function initializeCoreMod() { if (instruction instanceof LabelNode) { instructions.insertBefore(instruction, new LabelNode()); instructions.insertBefore(instruction, new VarInsnNode(Opcodes.ALOAD, 0)); - instructions.insertBefore(instruction, new MethodInsnNode(Opcodes.INVOKESTATIC, "me/shedaniel/lightoverlay/LightOverlayClient", "renderWorldLast", "()V", false)); + instructions.insertBefore(instruction, new MethodInsnNode(Opcodes.INVOKESTATIC, "me/shedaniel/lightoverlay/forge/LightOverlayClient", "renderWorldLast", "()V", false)); break; } } diff --git a/forge/src/main/resources/assets/lightoverlay/lang/en_us.json b/forge/src/main/resources/assets/lightoverlay/lang/en_us.json index 4d55bbc..5346550 100755 --- a/forge/src/main/resources/assets/lightoverlay/lang/en_us.json +++ b/forge/src/main/resources/assets/lightoverlay/lang/en_us.json @@ -1,20 +1,18 @@ { "key.lightoverlay.category": "Light Overlay", "key.lightoverlay.enable_overlay": "Toggle Light Overlay", - "key.lightoverlay.decrease_reach": "Decrease Light Overlay's Reach", - "key.lightoverlay.increase_reach": "Increase Light Overlay's Reach", - "key.lightoverlay.increase_line_width": "Increase Light Overlay's Line Width", - "key.lightoverlay.decrease_line_width": "Decrease Light Overlay's Line Width", - "text.lightoverlay.current_reach": "The current reach is %d!", - "text.lightoverlay.current_line_width": "The current line width is %s!", + "description.lightoverlay.caching": "Caching is recommended if the reach is above 16 or if you are running on a potato.", "config.lightoverlay.general": "General", "config.lightoverlay.reach": "Reach:", + "config.lightoverlay.caching": "Caching:", "config.lightoverlay.crossLevel": "Light Level:", + "config.lightoverlay.secondaryLevel": "Secondary Light Level:", "config.lightoverlay.showNumber": "Show Number Instead:", "config.lightoverlay.smoothLines": "Smooth Lines:", "config.lightoverlay.underwater": "Display Underwater:", "config.lightoverlay.lineWidth": "Line Width:", "config.lightoverlay.yellowColor": "Yellow Color:", + "config.lightoverlay.secondaryColor": "Secondary Color:", "config.lightoverlay.redColor": "Red Color:", "config.lightoverlay.invalidColor": "Invalid Color" } \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 32d1762..fa35d95 100755 --- a/gradle.properties +++ b/gradle.properties @@ -1,15 +1,15 @@ org.gradle.jvmargs=-Xmx3G org.gradle.daemon=false -mod_version=4.6.2 +mod_version=4.7.0 # fabric fabric_minecraft_version=1.15.2 yarn_build=15 -fabric_loader_version=0.8.2+build.194 -fabric_api_version=0.5.1+build.294-1.15 +fabric_loader_version=0.8.8+build.202 +fabric_api_version=0.13.0+build.315-1.15 cloth_events_version=1.2.0 -cloth_config_version=2.14.0 +cloth_config_version=2.14.2 modmenu_version=1.10.2+build.32 # forge -- 2.44.0