diff --git a/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfig.java b/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfig.java index c4ae18f..99b166c 100644 --- a/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfig.java +++ b/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfig.java @@ -1,7 +1,7 @@ package wtf.hak.survivalfabric.config.client; public class ClientConfig { - public String configVersion = "1.1"; + public String configVersion = "1.2"; public boolean renderNetherFog = false; public boolean renderOverworldFog = false; @@ -17,4 +17,6 @@ public class ClientConfig { public float initialZoom = 20f; public boolean scrollToZoom = true; public float zoomStep = 2.5f; + public boolean enableFullBright = true; + public double fullBrightValue = 100f; } diff --git a/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfigManager.java b/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfigManager.java index 84f9da2..4bab12e 100644 --- a/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfigManager.java +++ b/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfigManager.java @@ -3,12 +3,18 @@ package wtf.hak.survivalfabric.config.client; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.option.SimpleOption; +import wtf.hak.survivalfabric.SurvivalFabric; +import wtf.hak.survivalfabric.SurvivalFabricClient; import wtf.hak.survivalfabric.config.Config; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; +import java.lang.reflect.Field; +import java.util.logging.Logger; public class ClientConfigManager { @@ -28,6 +34,7 @@ public class ClientConfigManager { try (FileReader reader = new FileReader(CONFIG_FILE)) { INSTANCE = GSON.fromJson(reader, ClientConfig.class); if (INSTANCE.configVersion.equalsIgnoreCase(new Config().configVersion)) { + apply(INSTANCE); return INSTANCE; } INSTANCE.configVersion = new ClientConfig().configVersion; @@ -51,5 +58,20 @@ public class ClientConfigManager { } catch (IOException e) { System.out.println("Error saving config: " + e.getMessage()); } + apply(config); + } + + public static void apply(ClientConfig config) { + if(config.enableFullBright) { + try { + SimpleOption gammaOption = MinecraftClient.getInstance().options.getGamma(); + Field valueField = SimpleOption.class.getDeclaredField("value"); + valueField.setAccessible(true); + valueField.set(gammaOption, config.fullBrightValue); + } catch (Exception e) { + SurvivalFabric.LOGGER.error("Failed to set fullbright value!"); + } + } else if(MinecraftClient.getInstance().options.getGamma().getValue() == config.fullBrightValue) + MinecraftClient.getInstance().options.getGamma().setValue(1d); } } diff --git a/src/client/java/wtf/hak/survivalfabric/modmenu/YACLConfigScreen.java b/src/client/java/wtf/hak/survivalfabric/modmenu/YACLConfigScreen.java index 407bdb8..2cc691a 100644 --- a/src/client/java/wtf/hak/survivalfabric/modmenu/YACLConfigScreen.java +++ b/src/client/java/wtf/hak/survivalfabric/modmenu/YACLConfigScreen.java @@ -1,181 +1,105 @@ package wtf.hak.survivalfabric.modmenu; import dev.isxander.yacl3.api.*; +import dev.isxander.yacl3.api.controller.DoubleSliderControllerBuilder; import dev.isxander.yacl3.api.controller.FloatSliderControllerBuilder; import dev.isxander.yacl3.api.controller.IntegerSliderControllerBuilder; import dev.isxander.yacl3.api.controller.TickBoxControllerBuilder; import net.minecraft.client.gui.screen.Screen; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import wtf.hak.survivalfabric.config.client.ClientConfig; import wtf.hak.survivalfabric.config.client.ClientConfigManager; public class YACLConfigScreen { public static Screen createConfigScreen(Screen parent) { + ClientConfig defaultConfig = new ClientConfig(); return YetAnotherConfigLib.createBuilder() .title(Text.literal("Survival Fabric Configuration").formatted(Formatting.BOLD)) - .category(createMainCategory()) + .category(createMainCategory(defaultConfig)) + .category(createRenderingCategory(defaultConfig)) .save(ClientConfigManager::save) .build() .generateScreen(parent); } - private static ConfigCategory createMainCategory() { + private static ConfigCategory createMainCategory(ClientConfig defaultConfig) { ConfigCategory.Builder categoryBuilder = ConfigCategory.createBuilder() .name(Text.literal("General Settings").formatted(Formatting.YELLOW)) .tooltip(Text.literal("Common configuration options for Survival Fabric")); - // Create groups for different types of options - OptionGroup.Builder renderingGroup = OptionGroup.createBuilder() - .name(Text.literal("Rendering Options")) - .description(OptionDescription.of(Text.literal("Options that control fog rendering and visual effects"))) - .collapsed(false); - OptionGroup.Builder gameplayGroup = OptionGroup.createBuilder() .name(Text.literal("Gameplay Options")) .description(OptionDescription.of(Text.literal("Options that affect gameplay mechanics"))) .collapsed(false); - OptionGroup.Builder cameraGroup = OptionGroup.createBuilder() - .name(Text.literal("Camera & Zoom")) - .description(OptionDescription.of(Text.literal("Camera and zoom-related settings"))) + OptionGroup.Builder zoomGroup = OptionGroup.createBuilder() + .name(Text.literal("Zoom Options")) + .description(OptionDescription.of(Text.literal("Zoom-related settings"))) .collapsed(false); - // === RENDERING OPTIONS === - - // Nether Fog - renderingGroup.option(Option.createBuilder() - .name(Text.literal("Render Nether Fog")) - .description(OptionDescription.of(Text.literal("Enable or disable fog rendering in the Nether dimension"))) - .binding( - false, // default - () -> ClientConfigManager.getConfig().renderNetherFog, - newValue -> ClientConfigManager.getConfig().renderNetherFog = newValue - ) - .controller(TickBoxControllerBuilder::create) - .build()); - - // Overworld Fog - renderingGroup.option(Option.createBuilder() - .name(Text.literal("Render Overworld Fog")) - .description(OptionDescription.of(Text.literal("Enable or disable fog rendering in the Overworld dimension"))) - .binding( - false, // default - () -> ClientConfigManager.getConfig().renderOverworldFog, - newValue -> ClientConfigManager.getConfig().renderOverworldFog = newValue - ) - .controller(TickBoxControllerBuilder::create) - .build()); - - // End Fog - renderingGroup.option(Option.createBuilder() - .name(Text.literal("Render End Fog")) - .description(OptionDescription.of(Text.literal("Enable or disable fog rendering in the End dimension"))) - .binding( - false, // default - () -> ClientConfigManager.getConfig().renderEndFog, - newValue -> ClientConfigManager.getConfig().renderEndFog = newValue - ) - .controller(TickBoxControllerBuilder::create) - .build()); - - // Lava Fog - renderingGroup.option(Option.createBuilder() - .name(Text.literal("Render Lava Fog")) - .description(OptionDescription.of(Text.literal("Enable or disable fog when submerged in lava"))) - .binding( - false, // default - () -> ClientConfigManager.getConfig().renderLavaFog, - newValue -> ClientConfigManager.getConfig().renderLavaFog = newValue - ) - .controller(TickBoxControllerBuilder::create) - .build()); - - // Water Fog - renderingGroup.option(Option.createBuilder() - .name(Text.literal("Render Water Fog")) - .description(OptionDescription.of(Text.literal("Enable or disable fog when submerged in water"))) - .binding( - false, // default - () -> ClientConfigManager.getConfig().renderWaterFog, - newValue -> ClientConfigManager.getConfig().renderWaterFog = newValue - ) - .controller(TickBoxControllerBuilder::create) - .build()); - - // Snow Fog - renderingGroup.option(Option.createBuilder() - .name(Text.literal("Render Snow Fog")) - .description(OptionDescription.of(Text.literal("Enable or disable fog during snow weather"))) - .binding( - false, // default - () -> ClientConfigManager.getConfig().renderSnowFog, - newValue -> ClientConfigManager.getConfig().renderSnowFog = newValue - ) - .controller(TickBoxControllerBuilder::create) - .build()); + //#region Gameplay Options // Remove Darkness Effect - renderingGroup.option(Option.createBuilder() + gameplayGroup.option(Option.createBuilder() .name(Text.literal("Remove Darkness Effect")) .description(OptionDescription.of(Text.literal("Remove the darkness effect applied by the Warden and sculk shriekers"))) .binding( - true, // default + defaultConfig.removeDarknessEffect, // default () -> ClientConfigManager.getConfig().removeDarknessEffect, newValue -> ClientConfigManager.getConfig().removeDarknessEffect = newValue ) .controller(TickBoxControllerBuilder::create) .build()); - // === GAMEPLAY OPTIONS === - // Lock Teleport Head Movement gameplayGroup.option(Option.createBuilder() .name(Text.literal("Lock Teleport Head Movement")) - .description(OptionDescription.of(Text.literal("Prevent head movement changes during teleportation"))) + .description(OptionDescription.of(Text.literal("Prevent head movement changes during angle teleportation"))) .binding( - true, // default + defaultConfig.lockTeleportHeadMovement, // default () -> ClientConfigManager.getConfig().lockTeleportHeadMovement, newValue -> ClientConfigManager.getConfig().lockTeleportHeadMovement = newValue ) .controller(TickBoxControllerBuilder::create) .build()); - // Manipulate Block Entity Distance gameplayGroup.option(Option.createBuilder() - .name(Text.literal("Manipulate Block Entity Distance")) - .description(OptionDescription.of(Text.literal("Enable custom block entity rendering distance"))) + .name(Text.literal("Enable Fullbright")) + .description(OptionDescription.of(Text.literal("See everything without constantly needing torches"))) .binding( - true, // default - () -> ClientConfigManager.getConfig().manipulateBlockEntityDistance, - newValue -> ClientConfigManager.getConfig().manipulateBlockEntityDistance = newValue + defaultConfig.enableFullBright, // default + () -> ClientConfigManager.getConfig().enableFullBright, + newValue -> ClientConfigManager.getConfig().enableFullBright = newValue ) .controller(TickBoxControllerBuilder::create) .build()); - // Block Entity Range - gameplayGroup.option(Option.createBuilder() - .name(Text.literal("Block Entity Range")) - .description(OptionDescription.of(Text.literal("Maximum distance for block entity rendering (in blocks)"))) + gameplayGroup.option(Option.createBuilder() + .name(Text.literal("Fullbright Value")) + .description(OptionDescription.of(Text.literal("Select how bright you want the fullbright to be"))) .binding( - 512, // default - () -> ClientConfigManager.getConfig().blockEntityRange, - newValue -> ClientConfigManager.getConfig().blockEntityRange = newValue + defaultConfig.fullBrightValue, // default + () -> ClientConfigManager.getConfig().fullBrightValue, + newValue -> ClientConfigManager.getConfig().fullBrightValue = newValue ) - .controller(opt -> IntegerSliderControllerBuilder.create(opt) - .range(16, 2048) - .step(16) - .formatValue(value -> Text.literal(value + " blocks"))) + .controller(opt -> DoubleSliderControllerBuilder.create(opt) + .range(1d, 100d) + .step(1d) + .formatValue(value -> Text.literal(String.format("%.0f", value)))) .build()); - // === CAMERA & ZOOM OPTIONS === + //#endregion + + //#region Zoom Options // Smooth Camera - cameraGroup.option(Option.createBuilder() + zoomGroup.option(Option.createBuilder() .name(Text.literal("Smooth Camera")) .description(OptionDescription.of(Text.literal("Enable smooth camera transitions"))) .binding( - true, // default + defaultConfig.smoothCamera, // default () -> ClientConfigManager.getConfig().smoothCamera, newValue -> ClientConfigManager.getConfig().smoothCamera = newValue ) @@ -183,26 +107,26 @@ public class YACLConfigScreen { .build()); // Initial Zoom - cameraGroup.option(Option.createBuilder() + zoomGroup.option(Option.createBuilder() .name(Text.literal("Initial Zoom Level")) .description(OptionDescription.of(Text.literal("Default zoom level when activating zoom"))) .binding( - 20f, // default + defaultConfig.initialZoom, // default () -> ClientConfigManager.getConfig().initialZoom, newValue -> ClientConfigManager.getConfig().initialZoom = newValue ) .controller(opt -> FloatSliderControllerBuilder.create(opt) .range(1.0f, 50.0f) .step(0.5f) - .formatValue(value -> Text.literal(String.format("%.1fx", value)))) + .formatValue(value -> Text.literal(String.format("%.1f", value)))) .build()); // Scroll to Zoom - cameraGroup.option(Option.createBuilder() + zoomGroup.option(Option.createBuilder() .name(Text.literal("Scroll to Zoom")) .description(OptionDescription.of(Text.literal("Allow using mouse wheel to adjust zoom level"))) .binding( - true, // default + defaultConfig.scrollToZoom, // default () -> ClientConfigManager.getConfig().scrollToZoom, newValue -> ClientConfigManager.getConfig().scrollToZoom = newValue ) @@ -210,11 +134,11 @@ public class YACLConfigScreen { .build()); // Zoom Step - cameraGroup.option(Option.createBuilder() + zoomGroup.option(Option.createBuilder() .name(Text.literal("Zoom Step")) .description(OptionDescription.of(Text.literal("Amount of zoom change per scroll wheel step"))) .binding( - 2.5f, // default + defaultConfig.zoomStep, // default () -> ClientConfigManager.getConfig().zoomStep, newValue -> ClientConfigManager.getConfig().zoomStep = newValue ) @@ -224,10 +148,139 @@ public class YACLConfigScreen { .formatValue(value -> Text.literal(String.format("%.1f", value)))) .build()); + //#endregion + return categoryBuilder - .group(renderingGroup.build()) .group(gameplayGroup.build()) - .group(cameraGroup.build()) + .group(zoomGroup.build()) + .build(); + } + + private static ConfigCategory createRenderingCategory(ClientConfig defaultConfig) { + ConfigCategory.Builder categoryBuilder = ConfigCategory.createBuilder() + .name(Text.literal("Rendering Settings").formatted(Formatting.YELLOW)) + .tooltip(Text.literal("Common configuration options for Survival Fabric")); + + OptionGroup.Builder fogGroup = OptionGroup.createBuilder() + .name(Text.literal("Fog Options")) + .description(OptionDescription.of(Text.literal("Options that control fog rendering"))) + .collapsed(false); + + OptionGroup.Builder distanceGroup = OptionGroup.createBuilder() + .name(Text.literal("Render Distance Options")) + .description(OptionDescription.of(Text.literal("Options that control render distance related things"))) + .collapsed(false); + + //#region Fog Options + + // Nether Fog + fogGroup.option(Option.createBuilder() + .name(Text.literal("Render Nether Fog")) + .description(OptionDescription.of(Text.literal("Enable or disable fog rendering in the Nether dimension"))) + .binding( + defaultConfig.renderNetherFog, // default + () -> ClientConfigManager.getConfig().renderNetherFog, + newValue -> ClientConfigManager.getConfig().renderNetherFog = newValue + ) + .controller(TickBoxControllerBuilder::create) + .build()); + + // Overworld Fog + fogGroup.option(Option.createBuilder() + .name(Text.literal("Render Overworld Fog")) + .description(OptionDescription.of(Text.literal("Enable or disable fog rendering in the Overworld dimension"))) + .binding( + defaultConfig.renderOverworldFog, // default + () -> ClientConfigManager.getConfig().renderOverworldFog, + newValue -> ClientConfigManager.getConfig().renderOverworldFog = newValue + ) + .controller(TickBoxControllerBuilder::create) + .build()); + + // End Fog + fogGroup.option(Option.createBuilder() + .name(Text.literal("Render End Fog")) + .description(OptionDescription.of(Text.literal("Enable or disable fog rendering in the End dimension"))) + .binding( + defaultConfig.renderEndFog, // default + () -> ClientConfigManager.getConfig().renderEndFog, + newValue -> ClientConfigManager.getConfig().renderEndFog = newValue + ) + .controller(TickBoxControllerBuilder::create) + .build()); + + // Lava Fog + fogGroup.option(Option.createBuilder() + .name(Text.literal("Render Lava Fog")) + .description(OptionDescription.of(Text.literal("Enable or disable fog when submerged in lava"))) + .binding( + defaultConfig.renderLavaFog, // default + () -> ClientConfigManager.getConfig().renderLavaFog, + newValue -> ClientConfigManager.getConfig().renderLavaFog = newValue + ) + .controller(TickBoxControllerBuilder::create) + .build()); + + // Water Fog + fogGroup.option(Option.createBuilder() + .name(Text.literal("Render Water Fog")) + .description(OptionDescription.of(Text.literal("Enable or disable fog when submerged in water"))) + .binding( + defaultConfig.renderWaterFog, // default + () -> ClientConfigManager.getConfig().renderWaterFog, + newValue -> ClientConfigManager.getConfig().renderWaterFog = newValue + ) + .controller(TickBoxControllerBuilder::create) + .build()); + + // Snow Fog + fogGroup.option(Option.createBuilder() + .name(Text.literal("Render Snow Fog")) + .description(OptionDescription.of(Text.literal("Enable or disable fog during snow weather"))) + .binding( + defaultConfig.renderSnowFog, // default + () -> ClientConfigManager.getConfig().renderSnowFog, + newValue -> ClientConfigManager.getConfig().renderSnowFog = newValue + ) + .controller(TickBoxControllerBuilder::create) + .build()); + + //#endregion + + //#region Render Distance Options + + // Manipulate Block Entity Distance + distanceGroup.option(Option.createBuilder() + .name(Text.literal("Manipulate Block Entity Distance")) + .description(OptionDescription.of(Text.literal("Enable custom block entity rendering distance"))) + .binding( + defaultConfig.manipulateBlockEntityDistance, // default + () -> ClientConfigManager.getConfig().manipulateBlockEntityDistance, + newValue -> ClientConfigManager.getConfig().manipulateBlockEntityDistance = newValue + ) + .controller(TickBoxControllerBuilder::create) + .build()); + + // Block Entity Range + distanceGroup.option(Option.createBuilder() + .name(Text.literal("Block Entity Range")) + .description(OptionDescription.of(Text.literal("Maximum distance for block entity rendering (in blocks)"))) + .binding( + defaultConfig.blockEntityRange, // default + () -> ClientConfigManager.getConfig().blockEntityRange, + newValue -> ClientConfigManager.getConfig().blockEntityRange = newValue + ) + .controller(opt -> IntegerSliderControllerBuilder.create(opt) + .range(16, 1024) + .step(16) + .formatValue(value -> Text.literal(value + " blocks"))) + .build()); + + //#endregion + + return categoryBuilder + .group(fogGroup.build()) + .group(distanceGroup.build()) .build(); } } \ No newline at end of file