From 8c3798d4561096af0602b4b9851e75aeb6afb6f5 Mon Sep 17 00:00:00 2001 From: Hedzer Kuijlman Date: Mon, 7 Apr 2025 10:32:39 +0200 Subject: [PATCH] Created basic Mod Menu Integration and made different fog types toggleable --- .../survivalfabric/SurvivalFabricClient.java | 2 + .../config/client/ClientConfig.java | 12 +++ .../config/client/ClientConfigManager.java | 55 ++++++++++++ .../mixin/client/BackgroundRendererMixin.java | 24 ++++- .../survivalfabric/modmenu/ConfigScreen.java | 88 +++++++++++++++++++ .../modmenu/ModMenuIntegration.java | 16 ++++ src/main/resources/fabric.mod.json | 9 +- 7 files changed, 201 insertions(+), 5 deletions(-) create mode 100644 src/client/java/wtf/hak/survivalfabric/config/client/ClientConfig.java create mode 100644 src/client/java/wtf/hak/survivalfabric/config/client/ClientConfigManager.java create mode 100644 src/client/java/wtf/hak/survivalfabric/modmenu/ConfigScreen.java create mode 100644 src/client/java/wtf/hak/survivalfabric/modmenu/ModMenuIntegration.java diff --git a/src/client/java/wtf/hak/survivalfabric/SurvivalFabricClient.java b/src/client/java/wtf/hak/survivalfabric/SurvivalFabricClient.java index b5a76b4..4757a5c 100644 --- a/src/client/java/wtf/hak/survivalfabric/SurvivalFabricClient.java +++ b/src/client/java/wtf/hak/survivalfabric/SurvivalFabricClient.java @@ -1,12 +1,14 @@ package wtf.hak.survivalfabric; import net.fabricmc.api.ClientModInitializer; +import wtf.hak.survivalfabric.config.client.ClientConfigManager; import wtf.hak.survivalfabric.features.AngleViewer; public class SurvivalFabricClient implements ClientModInitializer { @Override public void onInitializeClient() { + ClientConfigManager.getConfig(); AngleViewer.register(); } } \ No newline at end of file diff --git a/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfig.java b/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfig.java new file mode 100644 index 0000000..86c9799 --- /dev/null +++ b/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfig.java @@ -0,0 +1,12 @@ +package wtf.hak.survivalfabric.config.client; + +public class ClientConfig { + public String configVersion = "1.0"; + + public boolean renderNetherFog = false; + public boolean renderOverworldFog = false; + public boolean renderEndFog = false; + public boolean renderLavaFog = false; + public boolean renderWaterFog = false; + public boolean renderSnowFog = false; +} diff --git a/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfigManager.java b/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfigManager.java new file mode 100644 index 0000000..d0cedfd --- /dev/null +++ b/src/client/java/wtf/hak/survivalfabric/config/client/ClientConfigManager.java @@ -0,0 +1,55 @@ +package wtf.hak.survivalfabric.config.client; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import net.fabricmc.loader.api.FabricLoader; +import wtf.hak.survivalfabric.config.Config; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +public class ClientConfigManager { + + private static final File CONFIG_FILE = FabricLoader.getInstance().getConfigDir().resolve("survivalfabric-client.json").toFile(); + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); + + private static ClientConfig INSTANCE; + + public static ClientConfig getConfig() { + if (INSTANCE == null) { + return load(); + } else + return INSTANCE; + } + + public static ClientConfig load() { + try(FileReader reader = new FileReader(CONFIG_FILE)) { + INSTANCE = GSON.fromJson(reader, ClientConfig.class); + if (INSTANCE.configVersion.equalsIgnoreCase(new Config().configVersion)) { + return INSTANCE; + } + INSTANCE.configVersion = new ClientConfig().configVersion; + save(INSTANCE); + return INSTANCE; + } catch (IOException e) { + ClientConfig config = new ClientConfig(); + INSTANCE = config; + save(config); + return config; + } + } + + public static void save(){ + save(INSTANCE); + } + + public static void save(ClientConfig config) { + try(FileWriter writer = new FileWriter(CONFIG_FILE)) { + GSON.toJson(config, writer); + } catch (IOException e) { + System.out.println("Error saving config: " + e.getMessage()); + } + } +} diff --git a/src/client/java/wtf/hak/survivalfabric/mixin/client/BackgroundRendererMixin.java b/src/client/java/wtf/hak/survivalfabric/mixin/client/BackgroundRendererMixin.java index 1101914..bc6fccc 100644 --- a/src/client/java/wtf/hak/survivalfabric/mixin/client/BackgroundRendererMixin.java +++ b/src/client/java/wtf/hak/survivalfabric/mixin/client/BackgroundRendererMixin.java @@ -1,20 +1,42 @@ package wtf.hak.survivalfabric.mixin.client; +import net.minecraft.block.enums.CameraSubmersionType; import net.minecraft.client.render.BackgroundRenderer; import net.minecraft.client.render.Camera; import net.minecraft.client.render.Fog; import net.minecraft.client.render.FogShape; +import net.minecraft.world.World; import org.joml.Vector4f; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import static wtf.hak.survivalfabric.config.client.ClientConfigManager.getConfig; + @Mixin(value = BackgroundRenderer.class, priority = 910) public abstract class BackgroundRendererMixin { @Inject(method = "applyFog", at = @At("RETURN"), cancellable = true) private static void applyFog(Camera camera, BackgroundRenderer.FogType fogType, Vector4f color, float viewDistance, boolean thickenFog, float tickProgress, CallbackInfoReturnable cir) { - cir.setReturnValue(new Fog(-8.0f, 1_000_000.0F, FogShape.CYLINDER, 0,0,0,0)); + boolean renderFog = true; + CameraSubmersionType subType = camera.getSubmersionType(); + if(subType == CameraSubmersionType.NONE) { + World world = camera.getFocusedEntity().getWorld(); + if(world.getRegistryKey() == World.OVERWORLD && !getConfig().renderOverworldFog) + renderFog = false; + else if(world.getRegistryKey() == World.NETHER && !getConfig().renderNetherFog) + renderFog = false; + else if(world.getRegistryKey() == World.END && !getConfig().renderEndFog) + renderFog = false; + } else if(subType == CameraSubmersionType.WATER && !getConfig().renderWaterFog) + renderFog = false; + else if(subType == CameraSubmersionType.LAVA && !getConfig().renderLavaFog) + renderFog = false; + else if(subType == CameraSubmersionType.POWDER_SNOW && !getConfig().renderSnowFog) + renderFog = false; + + if(!renderFog) + cir.setReturnValue(new Fog(-8.0f, 1_000_000.0F, FogShape.CYLINDER, 0,0,0,0)); } } diff --git a/src/client/java/wtf/hak/survivalfabric/modmenu/ConfigScreen.java b/src/client/java/wtf/hak/survivalfabric/modmenu/ConfigScreen.java new file mode 100644 index 0000000..907c154 --- /dev/null +++ b/src/client/java/wtf/hak/survivalfabric/modmenu/ConfigScreen.java @@ -0,0 +1,88 @@ +package wtf.hak.survivalfabric.modmenu; + +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.text.Text; +import wtf.hak.survivalfabric.config.client.ClientConfig; +import wtf.hak.survivalfabric.config.client.ClientConfigManager; + +import java.lang.reflect.Field; + +public class ConfigScreen extends Screen { + + private final Screen parent; + + public ConfigScreen(Screen parent) { + super(Text.literal("Survival Fabric - Client Config")); + this.parent = parent; + } + + @Override + protected void init() { + int buttonWidth = 200; + int buttonHeight = 20; + int spacing = 5; + int startY = 40; + int i = 0; + + for (Field field : ClientConfig.class.getFields()) { + if (field.getType() == boolean.class) { + int y = startY + i * (buttonHeight + spacing); + try { + boolean value = field.getBoolean(ClientConfigManager.getConfig()); + String label = formatFieldName(field.getName()) + ": " + (value ? "ON" : "OFF"); + + ButtonWidget button = ButtonWidget.builder( + Text.literal(label), + b -> { + try { + boolean current = field.getBoolean(ClientConfigManager.getConfig()); + field.setBoolean(ClientConfigManager.getConfig(), !current); + b.setMessage(Text.literal(formatFieldName(field.getName()) + ": " + (!current ? "ON" : "OFF"))); + ClientConfigManager.save(); // Save if needed + } catch (Exception e) { + e.printStackTrace(); + } + } + ).dimensions(this.width / 2 - buttonWidth / 2, y, buttonWidth, buttonHeight).build(); + + this.addDrawableChild(button); + i++; + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + // Done button + this.addDrawableChild(ButtonWidget.builder( + Text.translatable("gui.done"), + button -> this.client.setScreen(parent) + ).dimensions(this.width / 2 - 75, startY + i * (buttonHeight + spacing) + 10, 150, 20).build()); + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + context.fill(0, 0, this.width, this.height, 0xC0101010); + + int titleX = (this.width / 2) - (this.textRenderer.getWidth(this.title) / 2); + context.drawTextWithShadow(this.textRenderer, this.title, titleX, 20, 0xFFFFFF); + + super.render(context, mouseX, mouseY, delta); + } + + private String formatFieldName(String rawName) { + StringBuilder result = new StringBuilder(); + char[] chars = rawName.toCharArray(); + result.append(Character.toUpperCase(chars[0])); + for (int i = 1; i < chars.length; i++) { + if (Character.isUpperCase(chars[i])) { + result.append(' '); + } + result.append(chars[i]); + } + return result.toString(); + } + +} diff --git a/src/client/java/wtf/hak/survivalfabric/modmenu/ModMenuIntegration.java b/src/client/java/wtf/hak/survivalfabric/modmenu/ModMenuIntegration.java new file mode 100644 index 0000000..d2f93d7 --- /dev/null +++ b/src/client/java/wtf/hak/survivalfabric/modmenu/ModMenuIntegration.java @@ -0,0 +1,16 @@ +package wtf.hak.survivalfabric.modmenu; + +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +@Environment(EnvType.CLIENT) +public class ModMenuIntegration implements ModMenuApi { + + @Override + public ConfigScreenFactory getModConfigScreenFactory() { + System.out.println("Does ModMenuIntegration even load?"); + return parent -> new ConfigScreen(parent); + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index ba6d9a3..b9e6b2f 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -9,7 +9,8 @@ ], "contact": { "homepage": "https://hak.wtf", - "sources": "https://git.hak.wtf/hkuijlman/SurvivalFabric" + "sources": "https://git.hak.wtf/hkuijlman/SurvivalFabric", + "issues": "https://git.hak.wtf/hkuijlman/SurvivalFabric/issues", }, "license": "CC0-1.0", "icon": "assets/survivalfabric/icon.png", @@ -23,6 +24,9 @@ ], "fabric-datagen": [ "wtf.hak.survivalfabric.SurvivalFabricDataGenerator" + ], + "modmenu": [ + "wtf.hak.survivalfabric.modmenu.ModMenuIntegration" ] }, "mixins": [ @@ -40,8 +44,5 @@ }, "optional": { "modmenu": "*" - }, - "custom": { - "modmenu:api": "wtf.hak.survivalfabric.modmenu.ModMenuIntegration" } } \ No newline at end of file