Added custom config

This commit is contained in:
coolGi2007
2021-12-06 02:57:56 +00:00
parent ed6dff3b5e
commit faf8579b41
21 changed files with 406 additions and 1401 deletions
+1 -7
View File
@@ -18,8 +18,7 @@ configurations {
}
repositories {
// Required for ModMenu and ClothAPI
maven { url "https://maven.shedaniel.me/" }
// Required for ModMenu
maven { url "https://maven.terraformersmc.com/" }
}
@@ -36,11 +35,6 @@ dependencies {
exclude(group: "net.fabricmc.fabric-api")
}
// Cloth Config (including Auto Config)
modApi("me.shedaniel.cloth:cloth-config-fabric:5.0.38") {
exclude(group: "net.fabricmc.fabric-api")
}
common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowMe(project(path: ":common", configuration: "transformProductionFabric")) { transitive false }
@@ -19,8 +19,8 @@
package com.seibel.lod.fabric;
import com.seibel.lod.common.Config;
import com.seibel.lod.core.api.EventApi;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.lod.common.wrappers.chunk.ChunkWrapper;
import com.seibel.lod.common.wrappers.world.DimensionTypeWrapper;
import com.seibel.lod.common.wrappers.world.WorldWrapper;
@@ -33,7 +33,6 @@ import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents;
import net.minecraft.client.KeyMapping;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.BlockEventData;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.chunk.LevelChunk;
@@ -1,251 +0,0 @@
/*
* This file is part of the Distant Horizon mod (formerly the LOD Mod),
* licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.fabric;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.enums.config.*;
import com.seibel.lod.core.enums.rendering.*;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IAdvanced.*;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IGraphics.*;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton.IClient.IWorldGenerator;
import com.seibel.lod.fabric.wrappers.config.ConfigGui;
import me.shedaniel.autoconfig.ConfigData;
import me.shedaniel.autoconfig.annotation.ConfigEntry;
/**
* This handles any configuration the user has access to.
* @author coolGi2007
* @version 12-02-2021
*/
@me.shedaniel.autoconfig.annotation.Config(name = ModInfo.ID)
public class Config implements ConfigData
//public class Config extends ConfigGui
{
// CONFIG STRUCTURE
// -> Client
// |
// |-> Graphics
// | |-> Quality
// | |-> FogQuality
// | |-> AdvancedGraphics
// |
// |-> World Generation
// |
// |-> Advanced
// |-> Threads
// |-> Buffers
// |-> Debugging
// Since the original config system uses forge stuff, that means we have to rewrite the whole config system
@ConfigEntry.Gui.CollapsibleObject
public Client client = new Client();
public static class Client
{
@ConfigEntry.Gui.CollapsibleObject
public Graphics graphics = new Graphics();
@ConfigEntry.Gui.CollapsibleObject
public WorldGenerator worldGenerator = new WorldGenerator();
@ConfigEntry.Gui.CollapsibleObject
public Advanced advanced = new Advanced();
public static class Graphics
{
@ConfigEntry.Gui.CollapsibleObject
public Quality quality = new Quality();
@ConfigEntry.Gui.CollapsibleObject
public FogQuality fogQuality = new FogQuality();
@ConfigEntry.Gui.CollapsibleObject
public AdvancedGraphics advancedGraphicsOption = new AdvancedGraphics();
public static class Quality
{
@ConfigEntry.Category("lod.Graphics.QualityOption")
@ConfigEntry.Gui.Tooltip
public static HorizontalResolution drawResolution = IQuality.DRAW_RESOLUTION_DEFAULT;
@ConfigEntry.Category("lod.Graphics.QualityOption")
@ConfigEntry.Gui.Tooltip
@ConfigEntry.BoundedDiscrete(min = 16, max = 1024)
public static int lodChunkRenderDistance = IQuality.LOD_CHUNK_RENDER_DISTANCE_MIN_DEFAULT_MAX.defaultValue;
@ConfigEntry.Category("lod.Graphics.QualityOption")
@ConfigEntry.Gui.Tooltip
public static VerticalQuality verticalQuality = IQuality.VERTICAL_QUALITY_DEFAULT;
@ConfigEntry.Category("lod.Graphics.QualityOption")
@ConfigEntry.Gui.Tooltip
public static HorizontalScale horizontalScale = IQuality.HORIZONTAL_SCALE_DEFAULT;
@ConfigEntry.Category("lod.Graphics.QualityOption")
@ConfigEntry.Gui.Tooltip
public static HorizontalQuality horizontalQuality = IQuality.HORIZONTAL_QUALITY_DEFAULT;
}
public static class FogQuality
{
@ConfigEntry.Category("lod.Graphics.FogQualityOption")
@ConfigEntry.Gui.Tooltip
public static FogDistance fogDistance = IFogQuality.FOG_DISTANCE_DEFAULT;
@ConfigEntry.Category("lod.Graphics.FogQualityOption")
@ConfigEntry.Gui.Tooltip
public static FogDrawMode fogDrawMode = IFogQuality.FOG_DRAW_MODE_DEFAULT;
@ConfigEntry.Category("lod.Graphics.FogQualityOption")
@ConfigEntry.Gui.Tooltip
public static FogColorMode fogColorMode = IFogQuality.FOG_COLOR_MODE_DEFAULT;
@ConfigEntry.Category("lod.Graphics.FogQualityOption")
@ConfigEntry.Gui.Tooltip
public static boolean disableVanillaFog = IFogQuality.DISABLE_VANILLA_FOG_DEFAULT;
}
public static class AdvancedGraphics
{
@ConfigEntry.Category("lod.Graphics.AdvancedGraphicsOption")
@ConfigEntry.Gui.Tooltip
public static LodTemplate lodTemplate = IAdvancedGraphics.LOD_TEMPLATE_DEFAULT;
@ConfigEntry.Category("lod.Graphics.AdvancedGraphicsOption")
@ConfigEntry.Gui.Tooltip
public static boolean disableDirectionalCulling = IAdvancedGraphics.DISABLE_DIRECTIONAL_CULLING_DEFAULT;
@ConfigEntry.Category("lod.Graphics.AdvancedGraphicsOption")
@ConfigEntry.Gui.Tooltip
public static boolean alwaysDrawAtMaxQuality = IAdvancedGraphics.ALWAYS_DRAW_AT_MAD_QUALITY_DEFAULT;
@ConfigEntry.Category("lod.Graphics.AdvancedGraphicsOption")
@ConfigEntry.Gui.Tooltip
public static VanillaOverdraw vanillaOverdraw = IAdvancedGraphics.VANILLA_OVERDRAW_DEFAULT;
@ConfigEntry.Category("lod.Graphics.AdvancedGraphicsOption")
@ConfigEntry.Gui.Tooltip
public static boolean useExtendedNearClipPlane = IAdvancedGraphics.USE_EXTENDED_NEAR_CLIP_PLANE_DEFAULT;
}
}
//========================//
// WorldGenerator Configs //
//========================//
public static class WorldGenerator
{
@ConfigEntry.Category("lod.WorldGenerator")
@ConfigEntry.Gui.Tooltip
public static GenerationPriority generationPriority = IWorldGenerator.GENERATION_PRIORITY_DEFAULT;
@ConfigEntry.Category("lod.WorldGenerator")
@ConfigEntry.Gui.Tooltip
public static DistanceGenerationMode distanceGenerationMode = IWorldGenerator.DISTANCE_GENERATION_MODE_DEFAULT;
@ConfigEntry.Category("lod.WorldGenerator")
@ConfigEntry.Gui.Tooltip
public static boolean allowUnstableFeatureGeneration = IWorldGenerator.ALLOW_UNSTABLE_FEATURE_GENERATION_DEFAULT;
@ConfigEntry.Category("lod.WorldGenerator")
@ConfigEntry.Gui.Tooltip
public static BlocksToAvoid blocksToAvoid = IWorldGenerator.BLOCKS_TO_AVOID_DEFAULT;
/*
@ConfigEntry.Category("lod.WorldGenerator")
@ConfigEntry.Gui.Tooltip
public static boolean useExperimentalPreGenLoading = false;
*/
}
//==================//
// Advanced Configs //
//==================//
public static class Advanced
{
@ConfigEntry.Gui.CollapsibleObject
public Threading threading = new Threading();
@ConfigEntry.Gui.CollapsibleObject
public Debugging debugging = new Debugging();
@ConfigEntry.Gui.CollapsibleObject
public Buffers buffers = new Buffers();
public static class Threading
{
@ConfigEntry.Category("lod.AdvancedModOptions.Threading")
@ConfigEntry.Gui.Tooltip
// Find a way to set the max to a variable
@ConfigEntry.BoundedDiscrete(min = 1, max = 50)
public static int numberOfWorldGenerationThreads = IThreading.NUMBER_OF_WORLD_GENERATION_THREADS_DEFAULT.defaultValue;
@ConfigEntry.Category("lod.AdvancedModOptions.Threading")
@ConfigEntry.Gui.Tooltip
// Find a way to set the max to a variable
@ConfigEntry.BoundedDiscrete(min = 1, max = 50)
public static int numberOfBufferBuilderThreads = IThreading.NUMBER_OF_BUFFER_BUILDER_THREADS_MIN_DEFAULT_MAX.defaultValue;
}
//===============//
// Debug Options //
//===============//
public static class Debugging
{
@ConfigEntry.Category("lod.AdvancedModOptions.Debugging")
@ConfigEntry.Gui.Tooltip
public static boolean drawLods = IDebugging.DRAW_LODS_DEFAULT;
@ConfigEntry.Category("lod.AdvancedModOptions.Debugging")
@ConfigEntry.Gui.Tooltip
public static DebugMode debugMode = IDebugging.DEBUG_MODE_DEFAULT;
@ConfigEntry.Category("lod.AdvancedModOptions.Debugging")
@ConfigEntry.Gui.Tooltip
public static boolean enableDebugKeybindings = IDebugging.DEBUG_KEYBINDINGS_ENABLED_DEFAULT;
}
public static class Buffers
{
@ConfigEntry.Category("lod.Graphics.AdvancedGraphicsOption")
@ConfigEntry.Gui.Tooltip
public static GpuUploadMethod gpuUploadMethod = IBuffers.GPU_UPLOAD_METHOD_DEFAULT;
@ConfigEntry.Category("lod.Graphics.AdvancedGraphicsOption")
@ConfigEntry.Gui.Tooltip
@ConfigEntry.BoundedDiscrete(min = 0, max = 5000)
public static int gpuUploadTimeoutInMilleseconds = IBuffers.GPU_UPLOAD_TIMEOUT_IN_MILLISECONDS_DEFAULT.defaultValue;
@ConfigEntry.Category("lod.AdvancedModOptions.Buffers")
@ConfigEntry.Gui.Tooltip
public static BufferRebuildTimes rebuildTimes = IBuffers.REBUILD_TIMES_DEFAULT;
}
}
}
}
@@ -19,16 +19,14 @@
package com.seibel.lod.fabric;
import com.seibel.lod.common.Config;
import com.seibel.lod.common.LodCommonMain;
import com.seibel.lod.common.wrappers.config.ConfigGui;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.fabric.wrappers.DependencySetup;
import com.seibel.lod.fabric.wrappers.config.ConfigGui;
import me.shedaniel.autoconfig.AutoConfig;
import me.shedaniel.autoconfig.serializer.Toml4jConfigSerializer;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
/**
* Initialize and setup the Mod. <br>
@@ -48,8 +46,6 @@ public class Main implements ClientModInitializer
public static ClientProxy client_proxy;
public static final Config CONFIG = AutoConfig.register(Config.class, Toml4jConfigSerializer::new).getConfig();
// Do if implements ClientModInitializer
// This loads the mod before minecraft loads which causes a lot of issues
@@ -60,7 +56,7 @@ public class Main implements ClientModInitializer
// This loads the mod after minecraft loads which doesn't causes a lot of issues
public static void init() {
// ConfigGui.init(ModInfo.ID, Config.class);
initConfig();
LodCommonMain.startup(null);
DependencySetup.createInitialBindings();
ClientApi.LOGGER.info(ModInfo.READABLE_NAME + ", Version: " + ModInfo.VERSION);
@@ -69,4 +65,19 @@ public class Main implements ClientModInitializer
client_proxy = new ClientProxy();
client_proxy.registerEvents();
}
// TODO[CONFIG]: Find a better way to initialise everything
private static void initConfig() {
ConfigGui.init(ModInfo.ID, Config.class);
ConfigGui.init(ModInfo.ID, Config.Client.class);
ConfigGui.init(ModInfo.ID, Config.Client.Graphics.class);
ConfigGui.init(ModInfo.ID, Config.Client.Graphics.Quality.class);
ConfigGui.init(ModInfo.ID, Config.Client.Graphics.FogQuality.class);
ConfigGui.init(ModInfo.ID, Config.Client.Graphics.AdvancedGraphics.class);
ConfigGui.init(ModInfo.ID, Config.Client.WorldGenerator.class);
ConfigGui.init(ModInfo.ID, Config.Client.Advanced.class);
ConfigGui.init(ModInfo.ID, Config.Client.Advanced.Threading.class);
ConfigGui.init(ModInfo.ID, Config.Client.Advanced.Debugging.class);
ConfigGui.init(ModInfo.ID, Config.Client.Advanced.Buffers.class);
}
}
@@ -1,10 +1,8 @@
package com.seibel.lod.fabric.mixins;
import com.seibel.lod.common.wrappers.config.ConfigGui;
import com.seibel.lod.common.wrappers.config.TexturedButtonWidget;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.fabric.Config;
import com.seibel.lod.fabric.wrappers.config.TexturedButtonWidget;
import me.shedaniel.autoconfig.AutoConfig;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.gui.screens.OptionsScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.network.chat.Component;
@@ -43,8 +41,7 @@ public class MixinOptionsScreen extends Screen {
// Some textuary stuff
20, ICON_TEXTURE, 20, 40,
// Create the button and tell it where to go
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(AutoConfig.getConfigScreen(Config.class, this).get()),
// (buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(Config.getScreen(this, ModInfo.ID)),
(buttonWidget) -> Objects.requireNonNull(minecraft).setScreen(ConfigGui.getScreen(this, ModInfo.ID, "")),
// Add a title to the screen
new TranslatableComponent("text.autoconfig." + ModInfo.ID + ".title")));
}
@@ -48,42 +48,6 @@ import net.minecraft.client.renderer.RenderType;
@Mixin(LevelRenderer.class)
public class MixinWorldRenderer
{
/*
private static float previousPartialTicks = 0;
@Inject(at = @At("RETURN"), method = "renderClouds")
private void renderClouds(PoseStack poseStack, Matrix4f matrix4f, float f, double d, double e, double g, CallbackInfo ci)
// private void renderClouds(PoseStack matrixStackIn, float partialTicks, CallbackInfo callback)
{
// get the partial ticks since renderBlockLayer doesn't
// have access to them
previousPartialTicks = f;
}
@Inject(at = @At("HEAD"), method = "renderChunkLayer")
private void renderChunkLayer(RenderType renderType, PoseStack matrixStackIn, double d, double e, double f, Matrix4f matrix4f, CallbackInfo ci)
{
// only render if LODs are enabled and
// only render before solid blocks
if (renderType.equals(RenderType.solid()))
{
// get MC's current projection matrix
float[] mcProjMatrixRaw = new float[16];
GL15.glGetFloatv(GL15.GL_PROJECTION_MATRIX, mcProjMatrixRaw);
Mat4f mcProjectionMatrix = new Mat4f(mcProjMatrixRaw);
// OpenGl outputs their matrices in col,row form instead of row,col
// (or maybe vice versa I have no idea :P)
mcProjectionMatrix.transpose();
Mat4f mcModelViewMatrix = McObjectConverter.Convert(matrixStackIn.last().pose());
ClientApi.INSTANCE.renderLods(mcModelViewMatrix, mcProjectionMatrix, previousPartialTicks);
}
}
*/
private static float previousPartialTicks = 0;
@Inject(at = @At("RETURN"), method = "renderClouds(Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/math/Matrix4f;FDDD)V")
@@ -2,7 +2,7 @@ package com.seibel.lod.fabric.wrappers;
import com.seibel.lod.core.util.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.fabric.wrappers.config.LodConfigWrapperSingleton;
import com.seibel.lod.common.wrappers.config.LodConfigWrapperSingleton;
/**
* Binds all necessary dependencies, so we
@@ -1,470 +0,0 @@
package com.seibel.lod.fabric.wrappers.config;
import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.mojang.blaze3d.vertex.PoseStack;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.fabric.Config;
import jdk.dynalink.beans.StaticClass;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiComponent;
import net.minecraft.client.gui.components.AbstractWidget;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.components.ContainerObjectSelectionList;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.components.events.GuiEventListener;
import net.minecraft.client.gui.narration.NarratableEntry;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.resources.language.I18n;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Pattern;
/**
* Handles the configs gui
* Based upon MidnightConfig
* https://github.com/TeamMidnightDust/MidnightLib/blob/main/src/main/java/eu/midnightdust/lib/config/
* which is based upon TinyConfig
* https://github.com/Minenash/TinyConfig
*
* Credits to Minenash, TeamMidnightDust & Motschen
*
* @author coolGi2007
* @version 12-03-2021
*/
@SuppressWarnings("unchecked")
public abstract class ConfigGui {
/*
Small wiki on how to use this config
Create a new class that extends this class
Every time you want to add a button put a @Entry before it and if you want it to be within a range then do @Entry(min = 0, max = 10)
MAKE SURE THE VARIABLE YOU ARE PUTTING IN IS A STATIC VARIABLE
If you want to make a config asking if you want coolness then do this
public class Config extends ConfigGui {
@Entry
public static bool coolness = false;
}
If you want a comment then do this
@Comment public static Comment text1;
FOR THE CONFIG TO SHOW
you need to have this somewhere in the main class
ConfigGui.init(ModInfo.ID, Config.class);
For putting nested classes do @ScreenEntry for example
public class Config extends ConfigGui {
@Entry
public static bool coolness = false;
public static NestedScreen nestedScreen = new NestedScreen();
public static void NestedScreen() {
@Entry(min = 0, max = 100)
public static int howMuchCoolness = 0;
}
}
*/
private static final Pattern INTEGER_ONLY = Pattern.compile("(-?[0-9]*)");
private static final Pattern DECIMAL_ONLY = Pattern.compile("-?([\\d]+\\.?[\\d]*|[\\d]*\\.?[\\d]+|\\.)");
private static final List<EntryInfo> entries = new ArrayList<>();
protected static class EntryInfo {
Field field;
Object widget;
int width;
int max;
Map.Entry<EditBox, Component> error;
Object defaultValue;
Object value;
String tempValue;
boolean inLimits = true;
String id;
TranslatableComponent name;
int index;
}
public static final Map<String,Class<?>> configClass = new HashMap<>();
private static Path path;
private static final Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).excludeFieldsWithModifiers(Modifier.PRIVATE).addSerializationExclusionStrategy(new HiddenAnnotationExclusionStrategy()).setPrettyPrinting().create();
public static void init(String modid, Class<?> config) {
path = FabricLoader.getInstance().getConfigDir().resolve(modid + ".json");
configClass.put(modid, config);
for (Field field : config.getFields()) {
EntryInfo info = new EntryInfo();
if (field.isAnnotationPresent(Entry.class) || field.isAnnotationPresent(Comment.class) || field.isAnnotationPresent(ScreenEntry.class))
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) initClient(modid, field, info);
if (field.isAnnotationPresent(Entry.class))
try {
info.defaultValue = field.get(null);
} catch (IllegalAccessException ignored) {}
}
try { gson.fromJson(Files.newBufferedReader(path), config); }
catch (Exception e) { write(modid); }
for (EntryInfo info : entries) {
if (info.field.isAnnotationPresent(Entry.class))
try {
info.value = info.field.get(null);
info.tempValue = info.value.toString();
} catch (IllegalAccessException ignored) {
}
}
}
@Environment(EnvType.CLIENT)
private static void initClient(String modid, Field field, EntryInfo info) {
Class<?> type = field.getType();
Entry e = field.getAnnotation(Entry.class);
ScreenEntry s = field.getAnnotation(ScreenEntry.class);
info.width = e != null ? e.width() : 0;
info.field = field;
info.id = modid;
if (e != null) {
if (!e.name().equals(""))
info.name = new TranslatableComponent(e.name());
if (type == int.class)
textField(info, Integer::parseInt, INTEGER_ONLY, e.min(), e.max(), true);
else if (type == double.class)
textField(info, Double::parseDouble, DECIMAL_ONLY, e.min(), e.max(), false);
else if (type == String.class || type == List.class) {
info.max = e.max() == Double.MAX_VALUE ? Integer.MAX_VALUE : (int) e.max();
textField(info, String::length, null, Math.min(e.min(), 0), Math.max(e.max(), 1), true);
} else if (type == boolean.class) {
Function<Object, Component> func = value -> new TextComponent((Boolean) value ? "True" : "False").withStyle((Boolean) value ? ChatFormatting.GREEN : ChatFormatting.RED);
info.widget = new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(button -> {
info.value = !(Boolean) info.value;
button.setMessage(func.apply(info.value));
}, func);
} else if (type.isEnum()) {
List<?> values = Arrays.asList(field.getType().getEnumConstants());
Function<Object, Component> func = value -> new TranslatableComponent(modid + ".config." + "enum." + type.getSimpleName() + "." + info.value.toString());
info.widget = new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(button -> {
int index = values.indexOf(info.value) + 1;
info.value = values.get(index >= values.size() ? 0 : index);
button.setMessage(func.apply(info.value));
}, func);
}
} else if (s != null) {
if (!s.name().equals("")) info.name = new TranslatableComponent(s.name());
Function<Object, Component> func = value -> new TextComponent((Boolean) value ? "True" : "False").withStyle((Boolean) value ? ChatFormatting.GREEN : ChatFormatting.RED);
info.widget = new AbstractMap.SimpleEntry<Button.OnPress, Function<Object, Component>>(button -> {
button.setMessage(info.name);
}, func);
}
entries.add(info);
}
private static void textField(EntryInfo info, Function<String,Number> f, Pattern pattern, double min, double max, boolean cast) {
boolean isNumber = pattern != null;
info.widget = (BiFunction<EditBox, Button, Predicate<String>>) (t, b) -> s -> {
s = s.trim();
if (!(s.isEmpty() || !isNumber || pattern.matcher(s).matches())) return false;
Number value = 0;
boolean inLimits = false;
info.error = null;
if (!(isNumber && s.isEmpty()) && !s.equals("-") && !s.equals(".")) {
value = f.apply(s);
inLimits = value.doubleValue() >= min && value.doubleValue() <= max;
info.error = inLimits? null : new AbstractMap.SimpleEntry<>(t, new TextComponent(value.doubleValue() < min ?
"§cMinimum " + (isNumber? "value" : "length") + (cast? " is " + (int)min : " is " + min) :
"§cMaximum " + (isNumber? "value" : "length") + (cast? " is " + (int)max : " is " + max)));
}
info.tempValue = s;
t.setTextColor(inLimits? 0xFFFFFFFF : 0xFFFF7777);
info.inLimits = inLimits;
b.active = entries.stream().allMatch(e -> e.inLimits);
if (inLimits && info.field.getType() != List.class)
info.value = isNumber? value : s;
else if (inLimits) {
if (((List<String>) info.value).size() == info.index) ((List<String>) info.value).add("");
((List<String>) info.value).set(info.index, Arrays.stream(info.tempValue.replace("[", "").replace("]", "").split(", ")).toList().get(0));
}
return true;
};
}
// TODO[CONFIG]: Change to .toml
public static void write(String modid) {
path = FabricLoader.getInstance().getConfigDir().resolve(modid + ".json");
try {
if (!Files.exists(path)) Files.createFile(path);
Files.write(path, gson.toJson(configClass.get(modid).getDeclaredConstructor().newInstance()).getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
@Environment(EnvType.CLIENT)
public static Screen getScreen(Screen parent, String modid) {
return new ConfigScreen(parent, modid);
}
@Environment(EnvType.CLIENT)
private static class ConfigScreen extends Screen {
protected ConfigScreen(Screen parent, String modid) {
super(new TranslatableComponent(modid + ".config.title"));
this.parent = parent;
this.modid = modid;
this.translationPrefix = modid + ".config.";
}
private final String translationPrefix;
private final Screen parent;
private final String modid;
private ConfigListWidget list;
private boolean reload = false;
// Real Time config update //
@Override
public void tick() {
super.tick();
for (EntryInfo info : entries) {
try {info.field.set(null, info.value);} catch (IllegalAccessException ignored) {}
}
}
private void loadValues() {
try { gson.fromJson(Files.newBufferedReader(path), configClass.get(modid)); }
catch (Exception e) { write(modid); }
for (EntryInfo info : entries) {
if (info.field.isAnnotationPresent(Entry.class))
try {
info.value = info.field.get(null);
info.tempValue = info.value.toString();
} catch (IllegalAccessException ignored) {}
}
}
@Override
protected void init() {
super.init();
if (!reload) loadValues();
this.addRenderableWidget(new Button(this.width / 2 - 154, this.height - 28, 150, 20, CommonComponents.GUI_CANCEL, button -> {
loadValues();
Objects.requireNonNull(minecraft).setScreen(parent);
}));
Button done = this.addRenderableWidget(new Button(this.width / 2 + 4, this.height - 28, 150, 20, CommonComponents.GUI_DONE, (button) -> {
for (EntryInfo info : entries)
if (info.id.equals(modid)) {
try {
info.field.set(null, info.value);
} catch (IllegalAccessException ignored) {}
}
write(modid);
Objects.requireNonNull(minecraft).setScreen(parent);
}));
this.list = new ConfigListWidget(this.minecraft, this.width, this.height, 32, this.height - 32, 25);
if (this.minecraft != null && this.minecraft.level != null) this.list.setRenderBackground(false);
this.addWidget(this.list);
for (EntryInfo info : entries) {
if (info.id.equals(modid)) {
TranslatableComponent name = Objects.requireNonNullElseGet(info.name, () -> new TranslatableComponent(translationPrefix + info.field.getName()));
Button resetButton = new Button(width - 205, 0, 40, 20, new TextComponent("Reset").withStyle(ChatFormatting.RED), (button -> {
info.value = info.defaultValue;
info.tempValue = info.defaultValue.toString();
info.index = 0;
double scrollAmount = list.getScrollAmount();
this.reload = true;
Objects.requireNonNull(minecraft).setScreen(this);
list.setScrollAmount(scrollAmount);
}));
if (info.widget instanceof Map.Entry) {
Map.Entry<Button.OnPress, Function<Object, Component>> widget = (Map.Entry<Button.OnPress, Function<Object, Component>>) info.widget;
if (info.field.getType().isEnum()) widget.setValue(value -> new TranslatableComponent(translationPrefix + "enum." + info.field.getType().getSimpleName() + "." + info.value.toString()));
this.list.addButton(new Button(width - 160, 0,150, 20, widget.getValue().apply(info.value), widget.getKey()),resetButton, null,name);
} else if (info.field.getType() == List.class) {
if (!reload) info.index = 0;
EditBox widget = new EditBox(font, width - 160, 0, 150, 20, null);
widget.setMaxLength(info.width);
if (info.index < ((List<String>)info.value).size()) widget.insertText((String.valueOf(((List<String>)info.value).get(info.index))));
else widget.insertText("");
Predicate<String> processor = ((BiFunction<EditBox, Button, Predicate<String>>) info.widget).apply(widget, done);
widget.setFilter(processor);
resetButton.setWidth(20);
resetButton.setMessage(new TextComponent("R").withStyle(ChatFormatting.RED));
Button cycleButton = new Button(width - 185, 0, 20, 20, new TextComponent(String.valueOf(info.index)).withStyle(ChatFormatting.GOLD), (button -> {
((List<String>)info.value).remove("");
double scrollAmount = list.getScrollAmount();
this.reload = true;
info.index = info.index + 1;
if (info.index > ((List<String>)info.value).size()) info.index = 0;
Objects.requireNonNull(minecraft).setScreen(this);
list.setScrollAmount(scrollAmount);
}));
this.list.addButton(widget, resetButton, cycleButton, name);
} else if (info.widget != null) {
EditBox widget = new EditBox(font, width - 160, 0, 150, 20, null);
widget.setMaxLength(info.width);
widget.insertText(info.tempValue);
Predicate<String> processor = ((BiFunction<EditBox, Button, Predicate<String>>) info.widget).apply(widget, done);
widget.setFilter(processor);
this.list.addButton(widget, resetButton, null, name);
} else {
this.list.addButton(null,null,null,name);
}
}
}
}
@Override
public void render(PoseStack matrices, int mouseX, int mouseY, float delta) {
this.renderBackground(matrices);
this.list.render(matrices, mouseX, mouseY, delta);
drawCenteredString(matrices, font, title, width / 2, 15, 0xFFFFFF);
for (EntryInfo info : entries) {
if (info.id.equals(modid)) {
if (list.getHoveredButton(mouseX,mouseY).isPresent()) {
AbstractWidget buttonWidget = list.getHoveredButton(mouseX,mouseY).get();
Component text = ButtonEntry.buttonsWithText.get(buttonWidget);
TranslatableComponent name = new TranslatableComponent(this.translationPrefix + info.field.getName());
String key = translationPrefix + info.field.getName() + ".tooltip";
if (info.error != null && text.equals(name)) renderTooltip(matrices, info.error.getValue(), mouseX, mouseY);
else if (I18n.exists(key) && text.equals(name)) {
List<Component> list = new ArrayList<>();
for (String str : I18n.get(key).split("\n"))
list.add(new TextComponent(str));
renderTooltip(matrices, (Component) list, mouseX, mouseY);
}
}
}
}
super.render(matrices,mouseX,mouseY,delta);
}
}
@Environment(EnvType.CLIENT)
public static class ConfigListWidget extends ContainerObjectSelectionList<ButtonEntry> {
Font textRenderer;
public ConfigListWidget(Minecraft minecraftClient, int i, int j, int k, int l, int m) {
super(minecraftClient, i, j, k, l, m);
this.centerListVertically = false;
textRenderer = minecraftClient.font;
}
// @Override
public int getScrollbarPositionX() { return this.width -7; }
public void addButton(AbstractWidget button, AbstractWidget resetButton, AbstractWidget indexButton, Component text) {
this.addEntry(ButtonEntry.create(button, text, resetButton, indexButton));
}
@Override
public int getRowWidth() { return 10000; }
public Optional<AbstractWidget> getHoveredButton(double mouseX, double mouseY) {
for (ButtonEntry buttonEntry : this.children()) {
if (buttonEntry.button != null && buttonEntry.button.isMouseOver(mouseX, mouseY)) {
return Optional.of(buttonEntry.button);
}
}
return Optional.empty();
}
}
public static class ButtonEntry extends ContainerObjectSelectionList.Entry<ButtonEntry> {
private static final Font textRenderer = Minecraft.getInstance().font;
public final AbstractWidget button;
private final AbstractWidget resetButton;
private final AbstractWidget indexButton;
private final Component text;
private final List<AbstractWidget> children = new ArrayList<>();
public static final Map<AbstractWidget, Component> buttonsWithText = new HashMap<>();
private ButtonEntry(AbstractWidget button, Component text, AbstractWidget resetButton, AbstractWidget indexButton) {
buttonsWithText.put(button,text);
this.button = button;
this.resetButton = resetButton;
this.text = text;
this.indexButton = indexButton;
if (button != null) children.add(button);
if (resetButton != null) children.add(resetButton);
if (indexButton != null) children.add(indexButton);
}
public static ButtonEntry create(AbstractWidget button, Component text, AbstractWidget resetButton, AbstractWidget indexButton) {
return new ButtonEntry(button, text, resetButton, indexButton);
}
public void render(PoseStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
if (button != null) {
button.y = y;
button.render(matrices, mouseX, mouseY, tickDelta);
}
if (resetButton != null) {
resetButton.y = y;
resetButton.render(matrices, mouseX, mouseY, tickDelta);
}
if (indexButton != null) {
indexButton.y = y;
indexButton.render(matrices, mouseX, mouseY, tickDelta);
}
if (text != null && (!text.getString().contains("spacer") || button != null))
GuiComponent.drawString(matrices,textRenderer, text,12,y+5,0xFFFFFF);
}
@Override
public List<? extends GuiEventListener> children() {return children;}
@Override
public List<? extends NarratableEntry> narratables() {return children;}
}
// Where the @Entry is defined
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Entry {
int width() default 100;
double min() default Double.MIN_NORMAL;
double max() default Double.MAX_VALUE;
String name() default "";
}
// Where the @ScreenEntry is defined
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ScreenEntry {
String name() default "";
}
// Where the @Comment is defined
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Comment {}
public static class HiddenAnnotationExclusionStrategy implements ExclusionStrategy {
public boolean shouldSkipClass(Class<?> clazz) { return false; }
public boolean shouldSkipField(FieldAttributes fieldAttributes) {
return fieldAttributes.getAnnotation(Entry.class) == null;
}
}
}
@@ -1,489 +0,0 @@
package com.seibel.lod.fabric.wrappers.config;
import com.seibel.lod.core.enums.config.*;
import com.seibel.lod.core.enums.rendering.*;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.fabric.Config;
/**
* This holds the config defaults and setters/getters
* that should be hooked into the host mod loader (Fabric, Forge, etc.).
*
* @author James Seibel
* @version 11-16-2021
*/
public class LodConfigWrapperSingleton implements ILodConfigWrapperSingleton
{
public static final LodConfigWrapperSingleton INSTANCE = new LodConfigWrapperSingleton();
private static final Client client = new Client();
@Override
public IClient client()
{
return client;
}
public static class Client implements IClient
{
public final IGraphics graphics;
public final IWorldGenerator worldGenerator;
public final IAdvanced advanced;
@Override
public IGraphics graphics()
{
return graphics;
}
@Override
public IWorldGenerator worldGenerator()
{
return worldGenerator;
}
@Override
public IAdvanced advanced()
{
return advanced;
}
//================//
// Client Configs //
//================//
public Client()
{
graphics = new Graphics();
worldGenerator = new WorldGenerator();
advanced = new Advanced();
}
//==================//
// Graphics Configs //
//==================//
public static class Graphics implements IGraphics
{
public final IQuality quality;
public final IFogQuality fogQuality;
public final IAdvancedGraphics advancedGraphics;
@Override
public IQuality quality()
{
return quality;
}
@Override
public IFogQuality fogQuality()
{
return fogQuality;
}
@Override
public IAdvancedGraphics advancedGraphics()
{
return advancedGraphics;
}
Graphics()
{
quality = new Quality();
advancedGraphics = new AdvancedGraphics();
fogQuality = new FogQuality();
}
public static class Quality implements IQuality
{
@Override
public HorizontalResolution getDrawResolution()
{
return Config.Client.Graphics.Quality.drawResolution;
}
@Override
public void setDrawResolution(HorizontalResolution newHorizontalResolution)
{
Config.Client.Graphics.Quality.drawResolution = newHorizontalResolution;
}
@Override
public int getLodChunkRenderDistance()
{
return Config.Client.Graphics.Quality.lodChunkRenderDistance;
}
@Override
public void setLodChunkRenderDistance(int newLodChunkRenderDistance)
{
Config.Client.Graphics.Quality.lodChunkRenderDistance = newLodChunkRenderDistance;
}
@Override
public VerticalQuality getVerticalQuality()
{
return Config.Client.Graphics.Quality.verticalQuality;
}
@Override
public void setVerticalQuality(VerticalQuality newVerticalQuality)
{
Config.Client.Graphics.Quality.verticalQuality = newVerticalQuality;
}
@Override
public HorizontalScale getHorizontalScale()
{
return Config.Client.Graphics.Quality.horizontalScale;
}
@Override
public void setHorizontalScale(HorizontalScale newHorizontalScale)
{
Config.Client.Graphics.Quality.horizontalScale = newHorizontalScale;
}
@Override
public HorizontalQuality getHorizontalQuality()
{
return Config.Client.Graphics.Quality.horizontalQuality;
}
@Override
public void setHorizontalQuality(HorizontalQuality newHorizontalQuality)
{
Config.Client.Graphics.Quality.horizontalQuality = newHorizontalQuality;
}
}
public static class FogQuality implements IFogQuality
{
@Override
public FogDistance getFogDistance()
{
return Config.Client.Graphics.FogQuality.fogDistance;
}
@Override
public void setFogDistance(FogDistance newFogDistance)
{
Config.Client.Graphics.FogQuality.fogDistance = newFogDistance;
}
@Override
public FogDrawMode getFogDrawMode()
{
return Config.Client.Graphics.FogQuality.fogDrawMode;
}
@Override
public void setFogDrawMode(FogDrawMode setFogDrawMode)
{
Config.Client.Graphics.FogQuality.fogDrawMode = setFogDrawMode;
}
@Override
public FogColorMode getFogColorMode()
{
return Config.Client.Graphics.FogQuality.fogColorMode;
}
@Override
public void setFogColorMode(FogColorMode newFogColorMode)
{
Config.Client.Graphics.FogQuality.fogColorMode = newFogColorMode;
}
@Override
public boolean getDisableVanillaFog()
{
return Config.Client.Graphics.FogQuality.disableVanillaFog;
}
@Override
public void setDisableVanillaFog(boolean newDisableVanillaFog)
{
Config.Client.Graphics.FogQuality.disableVanillaFog = newDisableVanillaFog;
}
}
public static class AdvancedGraphics implements IAdvancedGraphics
{
@Override
public LodTemplate getLodTemplate()
{
return Config.Client.Graphics.AdvancedGraphics.lodTemplate;
}
@Override
public void setLodTemplate(LodTemplate newLodTemplate)
{
Config.Client.Graphics.AdvancedGraphics.lodTemplate = newLodTemplate;
}
@Override
public boolean getDisableDirectionalCulling()
{
return Config.Client.Graphics.AdvancedGraphics.disableDirectionalCulling;
}
@Override
public void setDisableDirectionalCulling(boolean newDisableDirectionalCulling)
{
Config.Client.Graphics.AdvancedGraphics.disableDirectionalCulling = newDisableDirectionalCulling;
}
@Override
public boolean getAlwaysDrawAtMaxQuality()
{
return Config.Client.Graphics.AdvancedGraphics.alwaysDrawAtMaxQuality;
}
@Override
public void setAlwaysDrawAtMaxQuality(boolean newAlwaysDrawAtMaxQuality)
{
Config.Client.Graphics.AdvancedGraphics.alwaysDrawAtMaxQuality = newAlwaysDrawAtMaxQuality;
}
@Override
public VanillaOverdraw getVanillaOverdraw()
{
return Config.Client.Graphics.AdvancedGraphics.vanillaOverdraw;
}
@Override
public void setVanillaOverdraw(VanillaOverdraw newVanillaOverdraw)
{
Config.Client.Graphics.AdvancedGraphics.vanillaOverdraw = newVanillaOverdraw;
}
@Override
public boolean getUseExtendedNearClipPlane()
{
return Config.Client.Graphics.AdvancedGraphics.useExtendedNearClipPlane;
}
@Override
public void setUseExtendedNearClipPlane(boolean newUseExtendedNearClipPlane)
{
Config.Client.Graphics.AdvancedGraphics.useExtendedNearClipPlane = newUseExtendedNearClipPlane;
}
}
}
//========================//
// WorldGenerator Configs //
//========================//
public static class WorldGenerator implements IWorldGenerator
{
@Override
public GenerationPriority getGenerationPriority()
{
return Config.Client.WorldGenerator.generationPriority;
}
@Override
public void setGenerationPriority(GenerationPriority newGenerationPriority)
{
Config.Client.WorldGenerator.generationPriority = newGenerationPriority;
}
@Override
public DistanceGenerationMode getDistanceGenerationMode()
{
return Config.Client.WorldGenerator.distanceGenerationMode;
}
@Override
public void setDistanceGenerationMode(DistanceGenerationMode newDistanceGenerationMode)
{
Config.Client.WorldGenerator.distanceGenerationMode = newDistanceGenerationMode;
}
@Override
public boolean getAllowUnstableFeatureGeneration()
{
return Config.Client.WorldGenerator.allowUnstableFeatureGeneration;
}
@Override
public void setAllowUnstableFeatureGeneration(boolean newAllowUnstableFeatureGeneration)
{
Config.Client.WorldGenerator.allowUnstableFeatureGeneration = newAllowUnstableFeatureGeneration;
}
@Override
public BlocksToAvoid getBlocksToAvoid()
{
return Config.Client.WorldGenerator.blocksToAvoid;
}
@Override
public void setBlockToAvoid(BlocksToAvoid newBlockToAvoid)
{
Config.Client.WorldGenerator.blocksToAvoid = newBlockToAvoid;
}
}
//============================//
// AdvancedModOptions Configs //
//============================//
public static class Advanced implements IAdvanced
{
public final IThreading threading;
public final IDebugging debugging;
public final IBuffers buffers;
@Override
public IThreading threading()
{
return threading;
}
@Override
public IDebugging debugging()
{
return debugging;
}
@Override
public IBuffers buffers()
{
return buffers;
}
public Advanced()
{
threading = new Threading();
debugging = new Debugging();
buffers = new Buffers();
}
public static class Threading implements IThreading
{
@Override
public int getNumberOfWorldGenerationThreads()
{
return Config.Client.Advanced.Threading.numberOfWorldGenerationThreads;
}
@Override
public void setNumberOfWorldGenerationThreads(int newNumberOfWorldGenerationThreads)
{
Config.Client.Advanced.Threading.numberOfWorldGenerationThreads = newNumberOfWorldGenerationThreads;
}
@Override
public int getNumberOfBufferBuilderThreads()
{
return Config.Client.Advanced.Threading.numberOfBufferBuilderThreads;
}
@Override
public void setNumberOfBufferBuilderThreads(int newNumberOfWorldBuilderThreads)
{
Config.Client.Advanced.Threading.numberOfBufferBuilderThreads = newNumberOfWorldBuilderThreads;
}
}
//===============//
// Debug Options //
//===============//
public static class Debugging implements IDebugging
{
@Override
public boolean getDrawLods()
{
return Config.Client.Advanced.Debugging.drawLods;
}
@Override
public void setDrawLods(boolean newDrawLods)
{
Config.Client.Advanced.Debugging.drawLods = newDrawLods;
}
@Override
public DebugMode getDebugMode()
{
return Config.Client.Advanced.Debugging.debugMode;
}
@Override
public void setDebugMode(DebugMode newDebugMode)
{
Config.Client.Advanced.Debugging.debugMode = newDebugMode;
}
@Override
public boolean getDebugKeybindingsEnabled()
{
return Config.Client.Advanced.Debugging.enableDebugKeybindings;
}
@Override
public void setDebugKeybindingsEnabled(boolean newEnableDebugKeybindings)
{
Config.Client.Advanced.Debugging.enableDebugKeybindings = newEnableDebugKeybindings;
}
}
public static class Buffers implements IBuffers
{
@Override
public GpuUploadMethod getGpuUploadMethod()
{
return Config.Client.Advanced.Buffers.gpuUploadMethod;
}
@Override
public void setGpuUploadMethod(GpuUploadMethod newDisableVanillaFog)
{
Config.Client.Advanced.Buffers.gpuUploadMethod = newDisableVanillaFog;
}
@Override
public int getGpuUploadTimeoutInMilliseconds()
{
return Config.Client.Advanced.Buffers.gpuUploadTimeoutInMilleseconds;
}
@Override
public void setGpuUploadTimeoutInMilliseconds(int newTimeoutInMilliseconds) {
Config.Client.Advanced.Buffers.gpuUploadTimeoutInMilleseconds = newTimeoutInMilliseconds;
}
@Override
public BufferRebuildTimes getRebuildTimes()
{
return Config.Client.Advanced.Buffers.rebuildTimes;
}
@Override
public void setRebuildTimes(BufferRebuildTimes newBufferRebuildTimes)
{
Config.Client.Advanced.Buffers.rebuildTimes = newBufferRebuildTimes;
}
}
}
}
}
@@ -1,9 +1,10 @@
package com.seibel.lod.fabric.wrappers.config;
import com.seibel.lod.fabric.Config;
import com.seibel.lod.common.wrappers.config.ConfigGui;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.common.Config;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import me.shedaniel.autoconfig.AutoConfig;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
@@ -15,23 +16,16 @@ import java.util.Map;
*/
@Environment(EnvType.CLIENT)
public class ModMenuIntegration implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return parent -> AutoConfig.getConfigScreen(Config.class, parent).get();
}
// For the custom config code
/*
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return parent -> Config.getScreen(parent, ModInfo.ID);
return parent -> Config.getScreen(parent, ModInfo.ID, "");
}
@Override
public Map<String, ConfigScreenFactory<?>> getProvidedConfigScreenFactories() {
HashMap<String, ConfigScreenFactory<?>> map = new HashMap<>();
Config.configClass.forEach((modid, cClass) -> map.put(modid, parent -> ConfigGui.getScreen(parent, modid)));
Config.configClass.forEach((modid, cClass) -> map.put(modid, parent -> ConfigGui.getScreen(parent, modid, "")));
return map;
}
*/
}
@@ -1,43 +0,0 @@
package com.seibel.lod.fabric.wrappers.config;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.client.gui.components.ImageButton;
/**
* Creates a button with a texture on it
*/
public class TexturedButtonWidget extends ImageButton {
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, ResourceLocation texture, OnPress pressAction) {
super(x, y, width, height, u, v, texture, pressAction);
}
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation texture, int textureWidth, int textureHeight, OnPress pressAction) {
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction);
}
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation texture, int textureWidth, int textureHeight, OnPress pressAction, Component text) {
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, text);
}
public TexturedButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, ResourceLocation texture, int textureWidth, int textureHeight, OnPress pressAction, OnTooltip tooltipSupplier, Component text) {
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, tooltipSupplier, text);
}
@Override
public void renderButton(PoseStack matrices, int mouseX, int mouseY, float delta) {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, WIDGETS_LOCATION);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha);
int i = this.getYImage(this.isHovered());
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
RenderSystem.enableDepthTest();
this.blit(matrices, this.x, this.y, 0, 46 + i * 20, this.width / 2, this.height);
this.blit(matrices, this.x + this.width / 2, this.y, 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height);
super.renderButton(matrices, mouseX, mouseY, delta);
}
}
+1 -3
View File
@@ -39,9 +39,7 @@
"fabricloader": ">=0.11.3",
"fabric": "*",
"minecraft": "1.17.x",
"java": ">=16",
"modmenu": ">=2.0.14",
"cloth-config2": ">=5.0.38"
"java": ">=16"
},
"suggests": {
"another-mod": "*"