From 9cd7488f67cf8b3fab2891a6dca023888d72bff4 Mon Sep 17 00:00:00 2001 From: Markil3 <75867393+Markil3@users.noreply.github.com> Date: Tue, 2 Mar 2021 09:42:28 -0700 Subject: [PATCH] Adds support for configuring the timings via Clith Config and Mod Menu. --- build.gradle | 9 +- gradle.properties | 3 + .../markil3/immersive_hud/ConfigManager.java | 326 +++++++++++++++++ src/main/java/markil3/immersive_hud/Main.java | 175 +++++++++- .../markil3/immersive_hud/TimerUtils.java | 328 ++++++++++++------ .../immersive_hud/mixin/HeldItemHook.java | 2 +- .../markil3/immersive_hud/mixin/HudHook.java | 12 +- .../immersive_hud/mixin/ProfilerHook.java | 5 +- .../assets/immersive_hud/lang/en_us.json | 49 +++ src/main/resources/fabric.mod.json | 3 + 10 files changed, 795 insertions(+), 117 deletions(-) create mode 100644 src/main/java/markil3/immersive_hud/ConfigManager.java create mode 100644 src/main/resources/assets/immersive_hud/lang/en_us.json diff --git a/build.gradle b/build.gradle index 49b080e..ee0662a 100644 --- a/build.gradle +++ b/build.gradle @@ -11,11 +11,8 @@ version = project.mod_version + "-" + project.minecraft_version + "-fabric" group = project.maven_group repositories { - // Add repositories to retrieve artifacts from in here. - // You should only use this when depending on other mods because - // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. - // See https://docs.gradle.org/current/userguide/declaring_repositories.html - // for more information about repositories. + maven { url "https://maven.shedaniel.me/" } + maven { url "https://maven.terraformersmc.com/" } } dependencies { @@ -26,6 +23,8 @@ dependencies { // Fabric API. This is technically optional, but you probably want it anyway. modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + modApi "me.shedaniel.cloth:cloth-config-fabric:${project.cloth_version}" + modImplementation "com.terraformersmc:modmenu:${project.modmenu_version}" // PSA: Some older mods, compiled on Loom 0.2.1, might have outdated Maven POMs. // You may need to force-disable transitiveness on them. diff --git a/gradle.properties b/gradle.properties index b76bd6d..3957d9b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,6 +7,9 @@ org.gradle.jvmargs=-Xmx1G yarn_mappings=1.16.4+build.9 loader_version=0.11.1 +cloth_version=4.11.14 +modmenu_version=1.16.8 + # Mod Properties mod_version = 0.1 maven_group = markil3 diff --git a/src/main/java/markil3/immersive_hud/ConfigManager.java b/src/main/java/markil3/immersive_hud/ConfigManager.java new file mode 100644 index 0000000..7ff6242 --- /dev/null +++ b/src/main/java/markil3/immersive_hud/ConfigManager.java @@ -0,0 +1,326 @@ +package markil3.immersive_hud; + +import net.minecraft.util.math.MathHelper; + +import me.shedaniel.autoconfig.AutoConfig; +import me.shedaniel.autoconfig.ConfigData; +import me.shedaniel.autoconfig.annotation.Config; +import me.shedaniel.autoconfig.annotation.ConfigEntry; + +import static markil3.immersive_hud.Main.TICKS_PER_SECOND; + +/** + * Configuration manager of this mod, which reads from and writes to this mod's + * configuration file. + *
+ * The methods that change this mod's configuration do not automatically write
+ * those changes to the configuration file on disk. Instead, they only update
+ * the configuration in memory. To write any changes, use the {@link #save()}
+ * method.
+ *
+ * @author Markil 3
+ */
+@Config(name = "immersive_hud")
+public class ConfigManager implements ConfigData
+{
+ public static class TimeValues
+ {
+ private static final int SHOW_TIME = 6 * TICKS_PER_SECOND;
+ private static final int FADE_IN = TICKS_PER_SECOND / 2;
+ private static final int FADE_OUT = TICKS_PER_SECOND;
+
+ @ConfigEntry.Gui.Excluded
+ private final String name;
+ private int maxTime = SHOW_TIME;
+ private int fadeIn = FADE_IN;
+ private int fadeOut = FADE_OUT;
+
+ TimeValues(String name)
+ {
+ final int MAX_TIME = 10 * 60 * TICKS_PER_SECOND;
+
+ this.name = name;
+ }
+
+ public String getName()
+ {
+ return this.name;
+ }
+
+ /**
+ * Obtains the maximum time that the hotbar can be on the screen,
+ * including fading.
+ *
+ * @return The maximum hotbar display time.
+ */
+ public int getMaxTime()
+ {
+ return this.maxTime;
+ }
+
+ /**
+ * Obtains the time that the hotbar takes to fade in.
+ *
+ * @return The hotbar fade in time.
+ */
+ public int getFadeInTime()
+ {
+ return this.fadeIn;
+ }
+
+ /**
+ * Obtains the time that the hotbar takes to fade out.
+ *
+ * @return The hotbar fade out time.
+ */
+ public int getFadeOutTime()
+ {
+ return this.fadeOut;
+ }
+
+ public void setMaxTime(int time)
+ {
+ this.maxTime = time;
+ }
+
+ public void setFadeInTime(int time)
+ {
+ this.fadeIn = time;
+ }
+
+ public void setFadeOutTime(int time)
+ {
+ this.fadeOut = time;
+ }
+ }
+
+ @ConfigEntry.Gui.TransitiveObject
+ @ConfigEntry.Gui.Tooltip
+ @ConfigEntry.Gui.PrefixText
+ private TimeValues hotbarTime = new TimeValues("hotbar");
+ @ConfigEntry.Gui.TransitiveObject
+ @ConfigEntry.Gui.Tooltip
+ @ConfigEntry.Gui.PrefixText
+ private TimeValues experienceTime = new TimeValues("experience");
+ @ConfigEntry.Gui.TransitiveObject
+ @ConfigEntry.Gui.Tooltip
+ @ConfigEntry.Gui.PrefixText
+ private TimeValues jumpTime = new TimeValues("jump");
+ @ConfigEntry.Gui.TransitiveObject
+ @ConfigEntry.Gui.Tooltip
+ @ConfigEntry.Gui.PrefixText
+ private TimeValues healthTime = new TimeValues("health");
+ @ConfigEntry.Gui.TransitiveObject
+ @ConfigEntry.Gui.Tooltip
+ @ConfigEntry.Gui.PrefixText
+ private TimeValues hungerTime = new TimeValues("hunger");
+ @ConfigEntry.Gui.TransitiveObject
+ @ConfigEntry.Gui.Tooltip
+ @ConfigEntry.Gui.PrefixText
+ private TimeValues effectTime = new TimeValues("effect");
+ @ConfigEntry.Gui.Tooltip
+ @ConfigEntry.Gui.PrefixText
+ private int crosshairTime = 6 * TICKS_PER_SECOND;
+ @ConfigEntry.Gui.Tooltip
+ @ConfigEntry.Gui.PrefixText
+ private int handTime = 30 * TICKS_PER_SECOND;
+ @ConfigEntry.Gui.Tooltip
+ @ConfigEntry.Gui.PrefixText
+ private boolean showArmor = true;
+ @ConfigEntry.Gui.Tooltip
+ @ConfigEntry.Gui.PrefixText
+ private double minHealth = 0.5;
+ @ConfigEntry.Gui.Tooltip
+ @ConfigEntry.Gui.PrefixText
+ @ConfigEntry.BoundedDiscrete(max = 20)
+ private int minHunger = 17;
+
+ /**
+ * Returns the instance of this class.
+ *
+ * @return the instance of this class
+ */
+ public static ConfigManager getInstance()
+ {
+ return AutoConfig.getConfigHolder(ConfigManager.class).getConfig();
+ }
+
+ // Validations
+
+ /**
+ * Obtains time values related to the hotbar.
+ *
+ * @return The hotbar display time values.
+ */
+ public TimeValues getHotbarTime()
+ {
+ return this.hotbarTime;
+ }
+
+ /**
+ * Obtains time values related to the experience bar.
+ *
+ * @return The experience bar display time values.
+ */
+ public TimeValues getExperienceTime()
+ {
+ return this.experienceTime;
+ }
+
+ /**
+ * Obtains time values related to the jump bar.
+ *
+ * @return The jump display time values.
+ */
+ public TimeValues getJumpTime()
+ {
+ return this.jumpTime;
+ }
+
+ /**
+ * Obtains time values related to the health bar.
+ *
+ * @return The health display time values.
+ */
+ public TimeValues getHealthTime()
+ {
+ return this.healthTime;
+ }
+
+ /**
+ * Obtains time values related to the hunger bar.
+ *
+ * @return The hunger display time values.
+ */
+ public TimeValues getHungerTime()
+ {
+ return this.hungerTime;
+ }
+
+ /**
+ * Obtains time values related to potion effects.
+ *
+ * @return Potion display time values.
+ */
+ public TimeValues getPotionTime()
+ {
+ return this.effectTime;
+ }
+
+ /**
+ * Obtains the time that the crosshairs are allowed to display.
+ *
+ * @return The crosshair display time values.
+ */
+ public int getCrosshairTime()
+ {
+ return this.crosshairTime;
+ }
+
+ /**
+ * Obtains the time that the hands are allowed to display.
+ *
+ * @return The hand display time values.
+ */
+ public int getHandTime()
+ {
+ return this.handTime;
+ }
+
+ /**
+ * Checks whether the armor bar should render.
+ *
+ * @return Whether or not armor shows on the HUD.
+ */
+ public boolean shouldShowArmor()
+ {
+ return this.showArmor;
+ }
+
+ /**
+ * Obtains the minimum health for fading. Anything below that and the health
+ * always displays.
+ *
+ * @return The health boundary, from 0 to 1.
+ */
+ public double getMinHealth()
+ {
+ return this.minHealth;
+ }
+
+ /**
+ * Obtains the minimum hunger for fading. Anything below that and the hunger
+ * always displays.
+ *
+ * @return The hunger boundary, from 0 to 20.
+ */
+ public int getMinHunger()
+ {
+ return this.minHunger;
+ }
+
+ /**
+ * Sets the time that the hands are allowed to display.
+ *
+ * @param time - The hand display time values.
+ */
+ public void setCrosshairTime(int time)
+ {
+ this.crosshairTime = time;
+ }
+
+ /**
+ * Sets the time that the hands are allowed to display.
+ *
+ * @param time - The hand display time values.
+ */
+ public void setHandTime(int time)
+ {
+ this.handTime = time;
+ }
+
+ /**
+ * Determines whether the armor bar should render.
+ *
+ * @param show - Whether or not armor shows on the HUD.
+ */
+ public void shouldShowArmor(boolean show)
+ {
+ this.showArmor = show;
+ }
+
+ /**
+ * Sets the minimum health for fading. Anything below that and the health
+ * always displays.
+ *
+ * @param boundary - The health boundary, from 0 to 1.
+ */
+ public void setMinHealth(double boundary)
+ {
+ this.minHealth = MathHelper.clamp(boundary, 0, 1);
+ }
+
+ /**
+ * Sets the minimum hunger for fading. Anything below that and the hunger
+ * always displays.
+ *
+ * @param boundary - The hunger boundary, from 0 to 20.
+ */
+ public void setMinHunger(int boundary)
+ {
+ this.minHunger = MathHelper.clamp(boundary, 0, 20);
+ }
+
+ @Override
+ public void validatePostLoad() throws ValidationException
+ {
+ this.setMinHealth(this.minHealth);
+ }
+/**
+ * Saves changes to this mod's configuration.
+ */
+// public void save()
+// {
+// SPEC.save();
+// }
+}
diff --git a/src/main/java/markil3/immersive_hud/Main.java b/src/main/java/markil3/immersive_hud/Main.java
index 1292fd0..db06e84 100644
--- a/src/main/java/markil3/immersive_hud/Main.java
+++ b/src/main/java/markil3/immersive_hud/Main.java
@@ -17,9 +17,18 @@
*/
package markil3.immersive_hud;
+import com.terraformersmc.modmenu.api.ConfigScreenFactory;
+import com.terraformersmc.modmenu.api.ModMenuApi;
+
import net.fabricmc.api.ModInitializer;
-import net.minecraft.client.gui.DrawableHelper;
-import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.text.TranslatableText;
+
+import me.shedaniel.autoconfig.AutoConfig;
+import me.shedaniel.autoconfig.serializer.Toml4jConfigSerializer;
+import me.shedaniel.clothconfig2.api.ConfigBuilder;
+import me.shedaniel.clothconfig2.api.ConfigCategory;
+import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
+import me.shedaniel.clothconfig2.gui.entries.DoubleListEntry;
/**
* The main entry point for the Immersive HUD mod.
@@ -27,11 +36,158 @@ import net.minecraft.client.util.math.MatrixStack;
* @author Markil 3
* @version 0.1-1.16.4-fabric
*/
-public class Main implements ModInitializer
+public class Main implements ModInitializer, ModMenuApi
{
+ public static final int TICKS_PER_SECOND = 20;
+
@Override
public void onInitialize()
{
+ AutoConfig.register(ConfigManager.class, Toml4jConfigSerializer::new);
+ }
+
+ private void startTimeField(ConfigEntryBuilder entryBuilder,
+ ConfigCategory cat,
+ ConfigManager.TimeValues value)
+ {
+ final float SHOW_TIME = 6;
+ final float FADE_IN = 0.25F;
+ final float FADE_OUT = 0.5F;
+
+ DoubleListEntry maxTime =
+ entryBuilder.startDoubleField(new TranslatableText(
+ "option.immersive_hud." + value.getName() +
+ "MaxTime"),
+ (float) value.getMaxTime() / TICKS_PER_SECOND)
+ .setDefaultValue(SHOW_TIME)
+ .setMin(0)
+ .setMax(10 * 60 * TICKS_PER_SECOND) // 10 Minutes
+ .setTooltip(new TranslatableText(
+ "tooltip.immersive_hud." + value.getName() +
+ "MaxTime"))
+ .setSaveConsumer(val -> value.setMaxTime((int) (val * TICKS_PER_SECOND)))
+ .build();
+
+ DoubleListEntry fadeIn =
+ entryBuilder.startDoubleField(new TranslatableText(
+ "option.immersive_hud." + value.getName() +
+ "FadeIn"),
+ (float) value.getFadeInTime() / TICKS_PER_SECOND)
+ .setDefaultValue(FADE_IN)
+ .setMin(0)
+ .setMax(10 * 60 * TICKS_PER_SECOND)
+ .setTooltip(new TranslatableText(
+ "tooltip.immersive_hud." + value.getName() +
+ "FadeIn"))
+ .setSaveConsumer(val -> value.setFadeInTime((int) (val * TICKS_PER_SECOND)))
+ .build();
+
+ DoubleListEntry fadeOut =
+ entryBuilder.startDoubleField(new TranslatableText(
+ "option.immersive_hud." + value.getName() +
+ "FadeOut"),
+ (float) value.getFadeOutTime() / TICKS_PER_SECOND)
+ .setDefaultValue(FADE_OUT)
+ .setMin(0)
+ .setMax(10 * 60 * TICKS_PER_SECOND)
+ .setTooltip(new TranslatableText(
+ "tooltip.immersive_hud." + value.getName() +
+ "FadeOut"))
+ .setSaveConsumer(val -> value.setFadeOutTime((int) (val * TICKS_PER_SECOND)))
+ .build();
+
+ cat.addEntry(maxTime);
+ cat.addEntry(fadeIn);
+ cat.addEntry(fadeOut);
+ }
+
+ @Override
+ public ConfigScreenFactory> getModConfigScreenFactory()
+ {
+ return screen -> {
+ ConfigCategory general;
+ ConfigEntryBuilder entryBuilder;
+ ConfigManager instance = ConfigManager.getInstance();
+ final ConfigBuilder builder = ConfigBuilder.create()
+ .setParentScreen(screen)
+ .setTitle(new TranslatableText(
+ "immersive_hud.configGui.title"))
+ .setSavingRunnable(() -> {
+ AutoConfig.getConfigHolder(ConfigManager.class).save();
+ });
+ general =
+ builder.getOrCreateCategory(new TranslatableText(
+ "category.immersive_hud.general"));
+ entryBuilder = builder.entryBuilder();
+
+ startTimeField(entryBuilder,
+ general,
+ instance.getHotbarTime());
+ startTimeField(entryBuilder,
+ general,
+ instance.getExperienceTime());
+ startTimeField(entryBuilder,
+ general,
+ instance.getJumpTime());
+ startTimeField(entryBuilder,
+ general,
+ instance.getHealthTime());
+ startTimeField(entryBuilder,
+ general,
+ instance.getHungerTime());
+ startTimeField(entryBuilder,
+ general,
+ instance.getPotionTime());
+
+ general.addEntry(entryBuilder.startDoubleField(new TranslatableText(
+ "option.immersive_hud" +
+ ".crosshairTime"),
+ (float) instance.getCrosshairTime() / TICKS_PER_SECOND)
+ .setDefaultValue(6)
+ .setTooltip(new TranslatableText(
+ "tooltip.immersive_hud" +
+ ".crosshairTime"))
+ .setSaveConsumer(val -> instance.setCrosshairTime((int) (val * TICKS_PER_SECOND)))
+ .build());
+
+ general.addEntry(entryBuilder.startDoubleField(new TranslatableText(
+ "option.immersive_hud.handTime"),
+ (float) instance.getHandTime() / TICKS_PER_SECOND)
+ .setDefaultValue(30)
+ .setTooltip(new TranslatableText(
+ "tooltip.immersive_hud.handTime"))
+ .setSaveConsumer(val -> instance.setHandTime((int) (val * TICKS_PER_SECOND)))
+ .build());
+
+ general.addEntry(entryBuilder.startDoubleField(new TranslatableText(
+ "option.immersive_hud.minHealth"),
+ instance.getMinHealth())
+ .setDefaultValue(0.5)
+ .setTooltip(new TranslatableText(
+ "tooltip.immersive_hud.minHealth"))
+ .setSaveConsumer(val -> instance.setMinHealth(val))
+ .build());
+
+ general.addEntry(entryBuilder.startIntField(new TranslatableText(
+ "option.immersive_hud.minHunger"),
+ instance.getMinHunger())
+ .setDefaultValue(17)
+ .setTooltip(new TranslatableText(
+ "tooltip.immersive_hud.minHunger"))
+ .setSaveConsumer(val -> instance.setMinHunger(val))
+ .build());
+
+ general.addEntry(entryBuilder.startBooleanToggle(new TranslatableText(
+ "option.immersive_hud.showArmor"),
+ instance.shouldShowArmor())
+ .setDefaultValue(true)
+ .setTooltip(new TranslatableText(
+ "tooltip.immersive_hud.showArmor"))
+ .setSaveConsumer(val -> instance.shouldShowArmor(val))
+ .build());
+
+ return builder.build();
+ };
}
/**
@@ -45,9 +201,16 @@ public class Main implements ModInitializer
*
* @since 0.1-1.16.4-fabric
*/
- static float getAlpha(int renderTime)
+ static float getAlpha(double renderTime, double maxTime, double fadeInTime, double fadeOutTime)
{
- return Math.min(renderTime / 20.0F,
- 1.0F);
+ if (renderTime <= fadeOutTime)
+ {
+ return (float) (renderTime / fadeOutTime);
+ }
+ else if (renderTime > maxTime - fadeInTime)
+ {
+ return (float) ((maxTime - renderTime) / fadeInTime);
+ }
+ return 1F;
}
}
diff --git a/src/main/java/markil3/immersive_hud/TimerUtils.java b/src/main/java/markil3/immersive_hud/TimerUtils.java
index 3ab8f6c..b7e7fd8 100644
--- a/src/main/java/markil3/immersive_hud/TimerUtils.java
+++ b/src/main/java/markil3/immersive_hud/TimerUtils.java
@@ -45,9 +45,6 @@ import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.MathHelper;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -61,33 +58,17 @@ import java.util.Optional;
*/
public class TimerUtils
{
- /**
- * The number of ticks that the hand will be onscreen. Every tick is 1/20th
- * of a second.
- */
- private static final int HAND_TIME = 10 * 20;
- /**
- * The number of ticks most elements will be onscreen. Every tick is 1/20th
- * of a second.
- */
- private static final int VISUAL_TIME = 6 * 20;
- /**
- * The number of ticks that the health and hunger bars will be onscreen.
- * Every tick is 1/20th of a second.
- */
- private static final int HEALTH_TIME = (int) ((float) VISUAL_TIME * 2.5);
-
/**
* How many more ticks the hand will be onscreen. Every tick is 1/20th of a
* second.
*/
- private static int mainHandTime, offHandTime;
+ private static double mainHandTime, offHandTime;
/**
* How many more ticks the crosshair will be onscreen. Every tick is 1/20th
* of a second.
*/
- private static int crosshairTime;
+ private static double crosshairTime;
/**
* If true, then the hand (and crosshairs) will be locked onto the screen
* without disappearing until this flag is updated.
@@ -100,13 +81,13 @@ public class TimerUtils
*/
private static int mapLock;
- private static HashMap