Created basic Mod Menu Integration and made different fog types toggleable

This commit is contained in:
2025-04-07 10:32:39 +02:00
parent d99467d953
commit 8c3798d456
7 changed files with 201 additions and 5 deletions

View File

@ -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();
}
}

View File

@ -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;
}

View File

@ -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());
}
}
}

View File

@ -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<Fog> 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));
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -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"
}
}