Compare commits
5 Commits
1d0f7f0f05
...
38a244b023
Author | SHA1 | Date | |
---|---|---|---|
38a244b023 | |||
868e71eb10 | |||
2a106c9a03 | |||
8c3798d456 | |||
d99467d953 |
11
build.gradle
11
build.gradle
@ -11,11 +11,10 @@ base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
// Add repositories to retrieve artifacts from in here.
|
maven {
|
||||||
// You should only use this when depending on other mods because
|
name = "Terraformers"
|
||||||
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
|
url = "https://maven.terraformersmc.com/"
|
||||||
// See https://docs.gradle.org/current/userguide/declaring_repositories.html
|
}
|
||||||
// for more information about repositories.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loom {
|
loom {
|
||||||
@ -44,7 +43,7 @@ dependencies {
|
|||||||
|
|
||||||
// Fabric API. This is technically optional, but you probably want it anyway.
|
// Fabric API. This is technically optional, but you probably want it anyway.
|
||||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
|
||||||
|
modImplementation("com.terraformersmc:modmenu:${project.modmenu_version}")
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
@ -15,3 +15,5 @@ archives_base_name=survivalfabric
|
|||||||
|
|
||||||
# Dependencies
|
# Dependencies
|
||||||
fabric_version=0.119.0+1.21.4
|
fabric_version=0.119.0+1.21.4
|
||||||
|
|
||||||
|
modmenu_version=13.0.3
|
@ -1,12 +1,14 @@
|
|||||||
package wtf.hak.survivalfabric;
|
package wtf.hak.survivalfabric;
|
||||||
|
|
||||||
import net.fabricmc.api.ClientModInitializer;
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
import wtf.hak.survivalfabric.config.client.ClientConfigManager;
|
||||||
import wtf.hak.survivalfabric.features.AngleViewer;
|
import wtf.hak.survivalfabric.features.AngleViewer;
|
||||||
|
|
||||||
public class SurvivalFabricClient implements ClientModInitializer {
|
public class SurvivalFabricClient implements ClientModInitializer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitializeClient() {
|
public void onInitializeClient() {
|
||||||
|
ClientConfigManager.getConfig();
|
||||||
AngleViewer.register();
|
AngleViewer.register();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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;
|
||||||
|
}
|
@ -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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,20 +1,42 @@
|
|||||||
package wtf.hak.survivalfabric.mixin.client;
|
package wtf.hak.survivalfabric.mixin.client;
|
||||||
|
|
||||||
|
import net.minecraft.block.enums.CameraSubmersionType;
|
||||||
import net.minecraft.client.render.BackgroundRenderer;
|
import net.minecraft.client.render.BackgroundRenderer;
|
||||||
import net.minecraft.client.render.Camera;
|
import net.minecraft.client.render.Camera;
|
||||||
import net.minecraft.client.render.Fog;
|
import net.minecraft.client.render.Fog;
|
||||||
import net.minecraft.client.render.FogShape;
|
import net.minecraft.client.render.FogShape;
|
||||||
|
import net.minecraft.world.World;
|
||||||
import org.joml.Vector4f;
|
import org.joml.Vector4f;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
|
import static wtf.hak.survivalfabric.config.client.ClientConfigManager.getConfig;
|
||||||
|
|
||||||
@Mixin(value = BackgroundRenderer.class, priority = 910)
|
@Mixin(value = BackgroundRenderer.class, priority = 910)
|
||||||
public abstract class BackgroundRendererMixin {
|
public abstract class BackgroundRendererMixin {
|
||||||
|
|
||||||
@Inject(method = "applyFog", at = @At("RETURN"), cancellable = true)
|
@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) {
|
private static void applyFog(Camera camera, BackgroundRenderer.FogType fogType, Vector4f color, float viewDistance, boolean thickenFog, float tickProgress, CallbackInfoReturnable<Fog> cir) {
|
||||||
|
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));
|
cir.setReturnValue(new Fog(-8.0f, 1_000_000.0F, FogShape.CYLINDER, 0,0,0,0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,8 @@
|
|||||||
],
|
],
|
||||||
"contact": {
|
"contact": {
|
||||||
"homepage": "https://hak.wtf",
|
"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",
|
"license": "CC0-1.0",
|
||||||
"icon": "assets/survivalfabric/icon.png",
|
"icon": "assets/survivalfabric/icon.png",
|
||||||
@ -23,6 +24,9 @@
|
|||||||
],
|
],
|
||||||
"fabric-datagen": [
|
"fabric-datagen": [
|
||||||
"wtf.hak.survivalfabric.SurvivalFabricDataGenerator"
|
"wtf.hak.survivalfabric.SurvivalFabricDataGenerator"
|
||||||
|
],
|
||||||
|
"modmenu": [
|
||||||
|
"wtf.hak.survivalfabric.modmenu.ModMenuIntegration"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"mixins": [
|
"mixins": [
|
||||||
@ -38,7 +42,7 @@
|
|||||||
"java": ">=21",
|
"java": ">=21",
|
||||||
"fabric-api": "*"
|
"fabric-api": "*"
|
||||||
},
|
},
|
||||||
"suggests": {
|
"optional": {
|
||||||
"another-mod": "*"
|
"modmenu": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user