Skip to content

Commit ae03de4

Browse files
authored
Merge pull request #124 from dima-dencep/1.21.x/dev
5.1.0
2 parents 08662c9 + cd082db commit ae03de4

16 files changed

Lines changed: 541 additions & 42 deletions

File tree

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ jobs:
107107
${{ steps.read_property.outputs.minecraft_version }}
108108
109109
dependencies: |
110-
forge-config-api-port
110+
forge-config-api-port{modrinth:ohNO6lps}{curseforge:547434}
111111
112112
java: |
113113
21

common/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ loom {
88

99
dependencies {
1010
modImplementation "net.fabricmc:fabric-loader:${rootProject.loader_version}"
11+
1112
modApi "fuzs.forgeconfigapiport:forgeconfigapiport-common-neoforgeapi:${rootProject.fcapip_version}"
13+
modCompileOnly("fuzs.forgeconfigapiport:forgeconfigapiport-fabric:${rootProject.fcapip_version}") {
14+
transitive false
15+
}
1216
}
1317

1418
jar {

common/src/main/java/org/redlance/dima_dencep/mods/rrls/RrlsConfig.java

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.redlance.dima_dencep.mods.rrls.config.DoubleLoad;
1616
import org.redlance.dima_dencep.mods.rrls.config.HideType;
1717
import org.redlance.dima_dencep.mods.rrls.config.Type;
18+
import org.redlance.dima_dencep.mods.rrls.utils.Ease;
1819

1920
public class RrlsConfig {
2021
public static final Pair<RrlsConfig, ModConfigSpec> CONFIG_SPEC_PAIR = new ModConfigSpec.Builder()
@@ -32,6 +33,12 @@ public class RrlsConfig {
3233
public final ModConfigSpec.ConfigValue<String> reloadText;
3334
public final ModConfigSpec.ConfigValue<Double> animationSpeed;
3435

36+
// Interpolation
37+
public final ModConfigSpec.BooleanValue interpolateProgress;
38+
public final ModConfigSpec.BooleanValue interpolateAtEnd;
39+
public final ModConfigSpec.EnumValue<Ease> ease;
40+
public final ModConfigSpec.ConfigValue<Double> easingArg;
41+
3542
// Other
3643
public final ModConfigSpec.BooleanValue resetResources;
3744
public final ModConfigSpec.BooleanValue reInitScreen;
@@ -56,6 +63,13 @@ protected RrlsConfig(ModConfigSpec.Builder builder) {
5663
this.animationSpeed = builder.define("animationSpeed", 1000.0);
5764
builder.pop();
5865

66+
builder.push("interpolation");
67+
this.interpolateProgress = builder.define("interpolateProgress", false);
68+
this.interpolateAtEnd = builder.define("interpolateAtEnd", true);
69+
this.ease = builder.defineEnum("ease", Ease.INOUTQUINT);
70+
this.easingArg = builder.define("easingArg", Double.NaN, RrlsConfig::isFloatLike);
71+
builder.pop();
72+
5973
builder.push("other");
6074
this.resetResources = builder.define("resetResources", true);
6175
this.reInitScreen = builder.define("reInitScreen", true);
@@ -96,6 +110,27 @@ public static String reloadText() {
96110
return CONFIG_SPEC_PAIR.getKey().reloadText.get();
97111
}
98112

113+
public static boolean interpolateProgress() {
114+
return CONFIG_SPEC_PAIR.getKey().interpolateProgress.get();
115+
}
116+
117+
public static boolean interpolateAtEnd() {
118+
return CONFIG_SPEC_PAIR.getKey().interpolateAtEnd.get();
119+
}
120+
121+
public static Ease easing() {
122+
return CONFIG_SPEC_PAIR.getKey().ease.get();
123+
}
124+
125+
public static Float easingArg() {
126+
float easingArg = CONFIG_SPEC_PAIR.getKey().easingArg.get().floatValue();
127+
if (Float.isNaN(easingArg)) {
128+
return null;
129+
}
130+
131+
return easingArg;
132+
}
133+
99134
public static float animationSpeed() {
100135
return CONFIG_SPEC_PAIR.getKey().animationSpeed.get()
101136
.floatValue();
@@ -120,4 +155,24 @@ public static DoubleLoad doubleLoad() {
120155
public static boolean skipForgeOverlay() {
121156
return CONFIG_SPEC_PAIR.getKey().skipForgeOverlay.get();
122157
}
158+
159+
private static boolean isFloatLike(Object obj) {
160+
if (obj == null) {
161+
return false;
162+
}
163+
164+
return switch (obj) {
165+
case Float ignored -> true;
166+
case Double ignored -> true;
167+
case String str -> {
168+
try {
169+
Float.valueOf(str);
170+
yield true;
171+
} catch (Throwable th) {
172+
yield false;
173+
}
174+
}
175+
default -> false;
176+
};
177+
}
123178
}

common/src/main/java/org/redlance/dima_dencep/mods/rrls/duck/OverlayExtender.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ public interface OverlayExtender {
1818
OverlayHelper.State rrls$getState();
1919
void rrls$setState(OverlayHelper.State state);
2020

21-
default void rrls$miniRender(GuiGraphics graphics) {
21+
default void rrls$miniRender(GuiGraphics graphics, float partialTick) {
2222
throw new UnsupportedOperationException("The '" + getClass().getCanonicalName() + "' overlay doesn't have a mini-render!");
2323
}
24+
25+
default void rrls$resetProgress() {
26+
// NO-OP
27+
}
2428
}

common/src/main/java/org/redlance/dima_dencep/mods/rrls/mixins/GameRendererMixin.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public class GameRendererMixin {
5252
));
5353

5454
if (RrlsConfig.miniRender())
55-
overlay.rrls$miniRender(graphics);
55+
overlay.rrls$miniRender(graphics, deltaTracker.getGameTimeDeltaTicks());
5656
}
5757

5858
} catch (RuntimeException ex) {

common/src/main/java/org/redlance/dima_dencep/mods/rrls/mixins/LoadingOverlayMixin.java

Lines changed: 84 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
package org.redlance.dima_dencep.mods.rrls.mixins;
1212

1313
import com.llamalad7.mixinextras.sugar.Local;
14+
import net.minecraft.Util;
1415
import net.minecraft.client.gui.components.FocusableTextWidget;
1516
import net.minecraft.network.chat.Component;
17+
import net.minecraft.util.ARGB;
1618
import net.minecraft.util.Mth;
19+
import org.objectweb.asm.Opcodes;
1720
import org.redlance.dima_dencep.mods.rrls.RrlsConfig;
1821
import org.redlance.dima_dencep.mods.rrls.config.Type;
1922
import org.redlance.dima_dencep.mods.rrls.utils.DummyGuiGraphics;
@@ -47,16 +50,18 @@ public abstract class LoadingOverlayMixin extends Overlay {
4750
@Final
4851
private Minecraft minecraft;
4952
@Shadow
50-
protected abstract void drawProgressBar(GuiGraphics guiGraphics, int minX, int minY, int maxX, int maxY, float partialTick);
53+
public float currentProgress;
5154
@Shadow
52-
private static int replaceAlpha(int color, int alpha) {
53-
return 0;
54-
}
55+
private long fadeOutStart;
56+
@Shadow
57+
private long fadeInStart;
58+
@Shadow
59+
public abstract void drawProgressBar(GuiGraphics guiGraphics, int minX, int minY, int maxX, int maxY, float partialTick);
5560

5661
@Unique
5762
private FocusableTextWidget rrls$textWidget;
5863
@Unique
59-
private float rrls$fadeOutTime;
64+
private boolean rrls$isFinished;
6065

6166
@Inject(
6267
method = "<init>",
@@ -72,37 +77,50 @@ private static int replaceAlpha(int color, int alpha) {
7277
}
7378

7479
@Override
75-
public void rrls$miniRender(GuiGraphics graphics) {
80+
public void rrls$miniRender(GuiGraphics graphics, float partialTick) {
7681
int i = graphics.guiWidth();
7782
int j = graphics.guiHeight();
7883

84+
float ease = 1.0F;
85+
if (RrlsConfig.interpolateProgress()) {
86+
ease -= RrlsConfig.easing().invoke(this.currentProgress, RrlsConfig.easingArg());
87+
88+
} else if (this.fadeOutStart > -1L) {
89+
float f = (float)(Util.getMillis() - this.fadeOutStart) / RrlsConfig.animationSpeed();
90+
ease -= RrlsConfig.easing().invoke(Mth.clamp(f, 0.0F, 1.0F), RrlsConfig.easingArg());
91+
}
92+
93+
int easeAlpha = Math.max(Math.round(ease * 255.0F), 4); // Fuck Font#adjustColor
94+
int easeColor = ARGB.color(easeAlpha, 255, 255, 255);
95+
7996
switch (RrlsConfig.type()) {
8097
case Type.PROGRESS -> {
8198
int s = (int) ((double) j * 0.8325);
8299
int r = (int) (Math.min(i * 0.75, j) * 0.5);
83100

84-
this.drawProgressBar(graphics, i / 2 - r, s - 5, i / 2 + r, s + 5, this.rrls$fadeOutTime);
101+
this.drawProgressBar(graphics, i / 2 - r, s - 5, i / 2 + r, s + 5, ease);
85102
}
86103

87104
case Type.TEXT -> graphics.drawCenteredString(
88105
minecraft.font, RrlsConfig.reloadText(), i / 2, 70,
89-
RrlsConfig.rgbProgress() ? RainbowUtils.rainbowColor() : -1
106+
RrlsConfig.rgbProgress() ? RainbowUtils.rainbowColor(easeAlpha) : easeColor
90107
);
91108

92109
case Type.TEXT_WITH_BACKGROUND -> {
93110
if (rrls$textWidget != null) {
94111
rrls$textWidget.setMaxWidth(i);
95112
rrls$textWidget.setX(i / 2 - rrls$textWidget.getWidth() / 2);
96113
rrls$textWidget.setY(j - j / 3);
114+
rrls$textWidget.setColor(easeColor);
97115

98116
if (RrlsConfig.rgbProgress())
99-
rrls$textWidget.setColor(RainbowUtils.rainbowColor());
117+
rrls$textWidget.setColor(RainbowUtils.rainbowColor(easeAlpha));
100118

101119
// This will make sure the widget is rendered above other widgets in Pause screen
102120
graphics.pose().pushPose();
103-
graphics.pose().translate(0, 0,255);
121+
graphics.pose().translate(0, 0, 255);
104122

105-
rrls$textWidget.render(graphics, 0, 0, this.rrls$fadeOutTime);
123+
rrls$textWidget.render(graphics, 0, 0, partialTick);
106124

107125
graphics.pose().popPose();
108126
}
@@ -111,15 +129,11 @@ private static int replaceAlpha(int color, int alpha) {
111129
}
112130
}
113131

114-
@Inject(
115-
method = "render",
116-
at = @At(
117-
value = "INVOKE",
118-
target = "Lnet/minecraft/client/Minecraft;setOverlay(Lnet/minecraft/client/gui/screens/Overlay;)V"
119-
)
120-
)
121-
public void rrls$onLoadDone(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci) {
122-
this.rrls$textWidget = null;
132+
@Override
133+
public void rrls$resetProgress() {
134+
this.currentProgress = 0;
135+
this.fadeOutStart = -1L;
136+
this.fadeInStart = -1L;
123137
}
124138

125139
@Inject(
@@ -133,18 +147,6 @@ private static int replaceAlpha(int color, int alpha) {
133147
rrls$setState(OverlayHelper.lookupState(minecraft.screen, rrls$getState() != OverlayHelper.State.WAIT));
134148
}
135149

136-
@Inject(
137-
method = "render",
138-
at = @At(
139-
value = "FIELD",
140-
target = "Lnet/minecraft/client/gui/screens/LoadingOverlay;fadeInStart:J",
141-
ordinal = 2
142-
)
143-
)
144-
public void rrls$hookPartialTick(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick, CallbackInfo ci, @Local(ordinal = 1) float f) {
145-
this.rrls$fadeOutTime = 1.0F - Mth.clamp(f, 0.0F, 1.0F);
146-
}
147-
148150
@WrapWithCondition(
149151
method = "render",
150152
at = @At(
@@ -197,21 +199,69 @@ private static int replaceAlpha(int color, int alpha) {
197199
original.call(red, green, blue, alpha);
198200
}
199201

202+
@WrapOperation(
203+
method = "drawProgressBar",
204+
at = @At(
205+
value = "INVOKE",
206+
target = "Ljava/lang/Math;round(F)I"
207+
)
208+
)
209+
public int rrls$lerp(float i, Operation<Integer> original, @Local(argsOnly = true) float partialTick) {
210+
if (RrlsConfig.interpolateProgress()) {
211+
return Mth.ceil(Mth.lerp(partialTick, 0.0F, 255.0F));
212+
}
213+
214+
return original.call(i);
215+
}
216+
200217
@WrapOperation(
201218
method = "drawProgressBar",
202219
at = @At(
203220
value = "INVOKE",
204221
target = "Lnet/minecraft/util/ARGB;color(IIII)I"
205222
)
206223
)
207-
public int rrls$rainbowProgress(int alpha, int red, int green, int blue, Operation<Integer> original) {
224+
public int rrls$rainbowProgress(int alpha, int red, int green, int blue, Operation<Integer> original, @Local(argsOnly = true) float partialTick) {
208225
if (RrlsConfig.rgbProgress() && rrls$getState() != OverlayHelper.State.DEFAULT) {
209-
return replaceAlpha(RainbowUtils.rainbowColor(), alpha);
226+
return RainbowUtils.rainbowColor(partialTick);
210227
}
211228

212229
return original.call(alpha, red, green, blue);
213230
}
214231

232+
@WrapOperation(
233+
method = "render",
234+
at = @At(
235+
value = "FIELD",
236+
target = "Lnet/minecraft/client/gui/screens/LoadingOverlay;fadeOutStart:J",
237+
ordinal = 2
238+
)
239+
)
240+
public long rrls$interpolateAtEnd(LoadingOverlay instance, Operation<Long> original) {
241+
if (this.fadeOutStart == -1L && this.currentProgress >= 0.999F) {
242+
this.fadeOutStart = Util.getMillis();
243+
}
244+
if (RrlsConfig.interpolateAtEnd()) {
245+
return this.rrls$isFinished ? 1L : -1L;
246+
}
247+
return original.call(instance);
248+
}
249+
250+
@WrapOperation(
251+
method = "render",
252+
at = @At(
253+
value = "FIELD",
254+
target = "Lnet/minecraft/client/gui/screens/LoadingOverlay;fadeOutStart:J",
255+
opcode = Opcodes.PUTFIELD
256+
)
257+
)
258+
public void rrls$(LoadingOverlay instance, long value, Operation<Void> original) {
259+
this.rrls$isFinished = true;
260+
if (!RrlsConfig.interpolateAtEnd()) {
261+
original.call(instance, value);
262+
}
263+
}
264+
215265
@ModifyConstant(
216266
method = "render",
217267
constant = {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2023 - 2024 dima_dencep.
3+
*
4+
* Licensed under the Open Software License, Version 3.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
*
7+
* You may obtain a copy of the License at
8+
* https://spdx.org/licenses/OSL-3.0.txt
9+
*/
10+
11+
package org.redlance.dima_dencep.mods.rrls.screens;
12+
13+
import com.electronwill.nightconfig.core.UnmodifiableConfig;
14+
import net.minecraft.client.gui.screens.Screen;
15+
import net.minecraft.network.chat.Component;
16+
import net.neoforged.fml.config.ModConfig;
17+
import net.neoforged.neoforge.client.gui.ConfigurationScreen;
18+
import org.jetbrains.annotations.NotNull;
19+
import org.jetbrains.annotations.Nullable;
20+
import org.redlance.dima_dencep.mods.rrls.Rrls;
21+
22+
public class ConfigurationSectionScreenProxy extends ConfigurationScreen.ConfigurationSectionScreen {
23+
public ConfigurationSectionScreenProxy(Screen parent, ModConfig.Type type, ModConfig modConfig, Component title) {
24+
super(parent, type, modConfig, title);
25+
}
26+
27+
@Override
28+
protected @Nullable Element createSection(@NotNull String key, @NotNull UnmodifiableConfig subconfig, @NotNull UnmodifiableConfig subsection) {
29+
ConfigurationScreen.ConfigurationSectionScreen currentSection = this.sectionCache.get(key);
30+
if (currentSection instanceof ConfigurationSectionScreenWithOverlay) {
31+
return super.createSection(key, subconfig, subsection);
32+
}
33+
34+
ConfigurationScreen.ConfigurationSectionScreen old = this.sectionCache.put(key, new ConfigurationSectionScreenWithOverlay(
35+
this.context, this, subconfig.valueMap(), key, subsection.entrySet(), Component.translatable(getTranslationKey(key))
36+
).rebuild());
37+
if (old != null) {
38+
Rrls.LOGGER.warn("Removed section ({}) from config!", old);
39+
}
40+
41+
return super.createSection(key, subconfig, subsection);
42+
}
43+
}

0 commit comments

Comments
 (0)