prepare 1.20.1 backport

This commit is contained in:
maloryware
2025-08-03 03:08:22 +01:00
parent a1ad6dd1f0
commit aea8559831
23 changed files with 196 additions and 328 deletions

View File

@@ -3,7 +3,7 @@ import groovy.json.JsonOutput
plugins { plugins {
id "architectury-plugin" version "3.4-SNAPSHOT" id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "1.7-SNAPSHOT" apply false id "dev.architectury.loom" version "1.10-SNAPSHOT" apply false
id "me.shedaniel.unified-publishing" version "0.1.+" apply false id "me.shedaniel.unified-publishing" version "0.1.+" apply false
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
} }
@@ -20,7 +20,7 @@ subprojects {
// The following line declares the yarn mappings you may select this one as well. // The following line declares the yarn mappings you may select this one as well.
mappings loom.layered { mappings loom.layered {
it.mappings("net.fabricmc:yarn:$rootProject.yarn_mappings:v2") it.mappings("net.fabricmc:yarn:$rootProject.yarn_mappings:v2")
it.mappings("dev.architectury:yarn-mappings-patch-neoforge:$rootProject.yarn_mappings_patch_neoforge_version") // it.mappings("dev.architectury:yarn-mappings-patch-neoforge:$rootProject.yarn_mappings_patch_neoforge_version")
} }
} }
} }
@@ -44,7 +44,7 @@ allprojects {
tasks.withType(JavaCompile) { tasks.withType(JavaCompile) {
options.encoding = "UTF-8" options.encoding = "UTF-8"
options.release = 21 options.release = 17
} }
ext { ext {
releaseChangelog = { releaseChangelog = {

View File

@@ -1,49 +1,30 @@
package eu.midnightdust.core.mixin; package eu.midnightdust.core.mixin;
import eu.midnightdust.core.config.MidnightLibConfig;
import eu.midnightdust.core.screen.MidnightConfigOverviewScreen; import eu.midnightdust.core.screen.MidnightConfigOverviewScreen;
import eu.midnightdust.lib.util.PlatformFunctions;
import eu.midnightdust.lib.util.screen.TexturedOverlayButtonWidget;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.option.OptionsScreen; import net.minecraft.client.gui.screen.option.OptionsScreen;
import net.minecraft.client.gui.widget.TextIconButtonWidget;
import net.minecraft.client.gui.widget.ThreePartsLayoutWidget;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
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.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Objects; import java.util.Objects;
import static eu.midnightdust.core.MidnightLib.MOD_ID;
import static eu.midnightdust.core.config.MidnightLibConfig.shouldShowButton;
@Mixin(OptionsScreen.class) @Mixin(OptionsScreen.class)
public abstract class MixinOptionsScreen extends Screen { public class MixinOptionsScreen extends Screen {
@Shadow @Final private ThreePartsLayoutWidget layout; private static final Identifier MIDNIGHTLIB_ICON_TEXTURE = new Identifier("midnightlib","textures/gui/midnightlib_button.png");
@Unique TextIconButtonWidget midnightlib$button = TextIconButtonWidget.builder(Text.translatable("midnightlib.overview.title"), ( protected MixinOptionsScreen(Text title) {
buttonWidget) -> Objects.requireNonNull(client).setScreen(new MidnightConfigOverviewScreen(this)), true) super(title);
.texture(Identifier.of(MOD_ID,"icon/"+MOD_ID), 16, 16).dimension(20, 20).build();
private MixinOptionsScreen(Text title) {super(title);}
@Inject(at = @At("HEAD"), method = "init")
public void midnightlib$onInit(CallbackInfo ci) {
if (shouldShowButton()) {
this.midnightlib$setButtonPos();
this.addDrawableChild(midnightlib$button);
}
} }
@Inject(at = @At("TAIL"), method = "refreshWidgetPositions") @Inject(at = @At("HEAD"),method = "init")
public void midnightlib$onResize(CallbackInfo ci) { private void midnightlib$init(CallbackInfo ci) {
if (shouldShowButton()) this.midnightlib$setButtonPos(); if (MidnightLibConfig.config_screen_list.equals(MidnightLibConfig.ConfigButton.TRUE) || (MidnightLibConfig.config_screen_list.equals(MidnightLibConfig.ConfigButton.MODMENU) && !PlatformFunctions.isModLoaded("modmenu")))
this.addDrawableChild(new TexturedOverlayButtonWidget(this.width / 2 + 158, this.height / 6 - 12, 20, 20, 0, 0, 20, MIDNIGHTLIB_ICON_TEXTURE, 32, 64, (buttonWidget) -> Objects.requireNonNull(client).setScreen(new MidnightConfigOverviewScreen(this)), Text.translatable("midnightlib.overview.title")));
} }
}
@Unique
public void midnightlib$setButtonPos() {
midnightlib$button.setPosition(layout.getWidth() / 2 + 158, layout.getY() + layout.getFooterHeight() - 4);
}
}

View File

@@ -4,18 +4,16 @@ import eu.midnightdust.core.MidnightLib;
import eu.midnightdust.lib.config.MidnightConfig; import eu.midnightdust.lib.config.MidnightConfig;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.Selectable;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.gui.widget.*;
import net.minecraft.screen.ScreenTexts; import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text; import net.minecraft.text.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import static eu.midnightdust.lib.config.MidnightConfig.MidnightConfigListWidget;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class MidnightConfigOverviewScreen extends Screen { public class MidnightConfigOverviewScreen extends Screen {
@@ -25,26 +23,64 @@ public class MidnightConfigOverviewScreen extends Screen {
this.parent = parent; this.parent = parent;
} }
private final Screen parent; private final Screen parent;
private MidnightConfigListWidget list; private MidnightOverviewListWidget list;
@Override @Override
protected void init() { protected void init() {
this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, (button) -> Objects.requireNonNull(client).setScreen(parent)).dimensions(this.width / 2 - 100, this.height - 26, 200, 20).build()); this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, (button) -> Objects.requireNonNull(client).setScreen(parent)).dimensions(this.width / 2 - 100, this.height - 28, 200, 20).build());
this.addSelectableChild(this.list = new MidnightConfigListWidget(this.client, this.width, this.height - 57, 24, 25)); this.list = new MidnightOverviewListWidget(this.client, this.width, this.height, 32, this.height - 32, 25);
if (this.client != null && this.client.world != null) this.list.setRenderBackground(false);
this.addSelectableChild(this.list);
List<String> sortedMods = new ArrayList<>(MidnightConfig.configClass.keySet()); List<String> sortedMods = new ArrayList<>(MidnightConfig.configClass.keySet());
Collections.sort(sortedMods); Collections.sort(sortedMods);
sortedMods.forEach((modid) -> { sortedMods.forEach((modid) -> {
if (!MidnightLib.hiddenMods.contains(modid)) { if (!MidnightLib.hiddenMods.contains(modid)) {
list.addButton(List.of(ButtonWidget.builder(Text.translatable(modid +".midnightconfig.title"), (button) -> list.addButton(ButtonWidget.builder(Text.translatable(modid +".midnightconfig.title"), (button) ->
Objects.requireNonNull(client).setScreen(MidnightConfig.getScreen(this, modid))).dimensions(this.width / 2 - 125, this.height - 28, 250, 20).build()), null, null); Objects.requireNonNull(client).setScreen(MidnightConfig.getScreen(this,modid))).dimensions(this.width / 2 - 125, this.height - 28, 250, 20).build());
}}); }
});
super.init(); super.init();
} }
@Override @Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) { public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta); this.renderBackground(context);
this.list.render(context, mouseX, mouseY, delta); this.list.render(context, mouseX, mouseY, delta);
context.drawCenteredTextWithShadow(textRenderer, title, width / 2, 10, 0xFFFFFF); context.drawCenteredTextWithShadow(textRenderer, title, width / 2, 15, 0xFFFFFF);
super.render(context, mouseX, mouseY, delta);
}
@Environment(EnvType.CLIENT)
public static class MidnightOverviewListWidget extends ElementListWidget<OverviewButtonEntry> {
TextRenderer textRenderer;
public MidnightOverviewListWidget(MinecraftClient minecraftClient, int i, int j, int k, int l, int m) {
super(minecraftClient, i, j, k, l, m);
this.centerListVertically = false;
textRenderer = minecraftClient.textRenderer;
}
@Override
public int getScrollbarPositionX() {return this.width-7;}
public void addButton(ClickableWidget button) {
this.addEntry(OverviewButtonEntry.create(button));
}
@Override
public int getRowWidth() { return 400; }
}
public static class OverviewButtonEntry extends ElementListWidget.Entry<OverviewButtonEntry> {
private final ClickableWidget button;
private final List<ClickableWidget> buttonList = new ArrayList<>();
private OverviewButtonEntry(ClickableWidget button) {
this.button = button;
this.buttonList.add(button);
}
public static OverviewButtonEntry create(ClickableWidget button) {return new OverviewButtonEntry(button);}
public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
button.setY(y);
button.render(context, mouseX, mouseY, tickDelta);
}
public List<? extends Element> children() {return buttonList;}
public List<? extends Selectable> selectableChildren() {return buttonList;}
} }
} }

View File

@@ -2,14 +2,16 @@ package eu.midnightdust.lib.config;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.gson.*; import com.google.gson.stream.*; import com.google.gson.*; import com.google.gson.stream.*;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.serialization.DataResult;
import eu.midnightdust.lib.util.PlatformFunctions; import eu.midnightdust.lib.util.PlatformFunctions;
import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.DrawContext; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.Element; import net.minecraft.client.gui.Selectable; import net.minecraft.client.gui.Element; import net.minecraft.client.gui.Selectable;
import net.minecraft.client.gui.screen.ConfirmLinkScreen; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ConfirmLinkScreen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.tab.GridScreenTab; import net.minecraft.client.gui.tab.Tab; import net.minecraft.client.gui.tab.TabManager; import net.minecraft.client.gui.tab.GridScreenTab; import net.minecraft.client.gui.tab.Tab; import net.minecraft.client.gui.tab.TabManager;
import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.widget.*; import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.widget.*;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.screen.ScreenTexts; import net.minecraft.screen.ScreenTexts;
@@ -21,7 +23,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.Color; import java.awt.Color;
import java.io.IOException;
import java.lang.annotation.*; import java.lang.annotation.*;
import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType;
import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Files; import java.nio.file.Path;
@@ -31,6 +32,26 @@ import java.util.regex.Pattern;
import static net.minecraft.client.MinecraftClient.IS_SYSTEM_MAC; import static net.minecraft.client.MinecraftClient.IS_SYSTEM_MAC;
/* FIXME:
* hi martin :wave:
* before anythinge else:
* DON'T ANNOY YOURSELF WITH THIS
* BACKPORT UNLESS YOU REALLY DON'T HAVE
* ANYTHING BETTER TO DO!!!!!
* i don't wish to waste your time in any capacity,
* and this backport is going to be a *huge* mess,
* as you surely know
* so please!! take it easy!
* much love <3
* .
* this being your codebase, i'm guessing
* (moreso hoping) you'll know what's in need
* of fixing given the rendering changes between
* 1.20 & 1.21
* gave it my best shot but... got completely lost.
*/
/** MidnightConfig by Martin "Motschen" Prokoph /** MidnightConfig by Martin "Motschen" Prokoph
* Single class config library - feel free to copy! * Single class config library - feel free to copy!
* Based on <a href="https://github.com/Minenash/TinyConfig">...</a> * Based on <a href="https://github.com/Minenash/TinyConfig">...</a>
@@ -97,8 +118,10 @@ public abstract class MidnightConfig {
if (!condition.requiredModId().isEmpty() && !PlatformFunctions.isModLoaded(condition.requiredModId())) if (!condition.requiredModId().isEmpty() && !PlatformFunctions.isModLoaded(condition.requiredModId()))
this.conditionsMet = false; this.conditionsMet = false;
String requiredOption = condition.requiredOption().contains(":") ? condition.requiredOption() : (this.modid + ":" + condition.requiredOption()); String requiredOption = condition.requiredOption().contains(":") ? condition.requiredOption() : (this.modid + ":" + condition.requiredOption());
if (entries.get(requiredOption) instanceof EntryInfo info) if (entries.get(requiredOption) != null) {
EntryInfo info = entries.get(requiredOption);
this.conditionsMet &= List.of(condition.requiredValue()).contains(info.tempValue); this.conditionsMet &= List.of(condition.requiredValue()).contains(info.tempValue);
}
if (!this.conditionsMet) break; if (!this.conditionsMet) break;
} }
if (prevConditionState != this.conditionsMet) reloadScreen = true; if (prevConditionState != this.conditionsMet) reloadScreen = true;
@@ -120,10 +143,7 @@ public abstract class MidnightConfig {
private static final Gson gson = new GsonBuilder() private static final Gson gson = new GsonBuilder()
.excludeFieldsWithModifiers(Modifier.TRANSIENT).excludeFieldsWithModifiers(Modifier.PRIVATE) .excludeFieldsWithModifiers(Modifier.TRANSIENT).excludeFieldsWithModifiers(Modifier.PRIVATE)
.addSerializationExclusionStrategy(new NonEntryExclusionStrategy()) .addSerializationExclusionStrategy(new NonEntryExclusionStrategy())
.registerTypeAdapter(Identifier.class, new TypeAdapter<Identifier>() { .registerTypeAdapter(Identifier.class, new Identifier.Serializer()).setPrettyPrinting().create();
public void write(JsonWriter out, Identifier id) throws IOException { out.value(id.toString()); }
public Identifier read(JsonReader in) throws IOException { return Identifier.of(in.nextString()); }
}).setPrettyPrinting().create();
public static void loadValuesFromJson(String modid) { public static void loadValuesFromJson(String modid) {
try { gson.fromJson(Files.newBufferedReader(path), configClass.get(modid)); } try { gson.fromJson(Files.newBufferedReader(path), configClass.get(modid)); }
@@ -198,8 +218,7 @@ public abstract class MidnightConfig {
info.function = (BiFunction<TextFieldWidget, ButtonWidget, Predicate<String>>) (t, b) -> s -> { info.function = (BiFunction<TextFieldWidget, ButtonWidget, Predicate<String>>) (t, b) -> s -> {
s = s.trim(); s = s.trim();
if (!(s.isEmpty() || !isNumber || pattern.matcher(s).matches()) || if (!(s.isEmpty() || !isNumber || pattern.matcher(s).matches()) ||
(info.dataType == Identifier.class && Identifier.validate(s).isError())) return false; (info.dataType == Identifier.class && Identifier.validate(s).equals(DataResult.success(new Identifier(s))))) return false; // inline substitution for "isError"
Number value = 0; boolean inLimits = false; info.error = null; Number value = 0; boolean inLimits = false; info.error = null;
if (!(isNumber && s.isEmpty()) && !s.equals("-") && !s.equals(".")) { if (!(isNumber && s.isEmpty()) && !s.equals("-") && !s.equals(".")) {
try { value = f.apply(s); } catch(NumberFormatException e){ return false; } try { value = f.apply(s); } catch(NumberFormatException e){ return false; }
@@ -292,9 +311,9 @@ public abstract class MidnightConfig {
super.tick(); super.tick();
if (prevTab != null && prevTab != tabManager.getCurrentTab()) { if (prevTab != null && prevTab != tabManager.getCurrentTab()) {
prevTab = tabManager.getCurrentTab(); prevTab = tabManager.getCurrentTab();
updateList(); list.setScrollY(0); updateList(); list.setScrollAmount(0);
} }
scrollProgress = list.getScrollY(); scrollProgress = list.getScrollAmount();
for (EntryInfo info : entries.values()) info.updateFieldValue(); for (EntryInfo info : entries.values()) info.updateFieldValue();
updateButtons(); updateButtons();
if (reloadScreen) { updateList(); reloadScreen = false; } if (reloadScreen) { updateList(); reloadScreen = false; }
@@ -303,8 +322,10 @@ public abstract class MidnightConfig {
if (this.list != null) { if (this.list != null) {
for (ButtonEntry entry : this.list.children()) { for (ButtonEntry entry : this.list.children()) {
if (entry.buttons != null && entry.buttons.size() > 1 && entry.info.field != null) { if (entry.buttons != null && entry.buttons.size() > 1 && entry.info.field != null) {
if (entry.buttons.get(0) instanceof ClickableWidget widget) if (entry.buttons.get(0) != null) {
ClickableWidget widget = entry.buttons.get(0);
if (widget.isFocused() || widget.isHovered()) widget.setTooltip(entry.info.getTooltip(true)); if (widget.isFocused() || widget.isHovered()) widget.setTooltip(entry.info.getTooltip(true));
}
if (entry.buttons.get(1) instanceof ButtonWidget button) if (entry.buttons.get(1) instanceof ButtonWidget button)
button.active = !Objects.equals(String.valueOf(entry.info.value), String.valueOf(entry.info.defaultValue)) && entry.info.conditionsMet; button.active = !Objects.equals(String.valueOf(entry.info.value), String.valueOf(entry.info.defaultValue)) && entry.info.conditionsMet;
}}}} }}}}
@@ -336,7 +357,7 @@ public abstract class MidnightConfig {
Objects.requireNonNull(client).setScreen(parent); Objects.requireNonNull(client).setScreen(parent);
}).dimensions(this.width / 2 + 4, this.height - 26, 150, 20).build()); }).dimensions(this.width / 2 + 4, this.height - 26, 150, 20).build());
this.list = new MidnightConfigListWidget(this.client, this.width, this.height - 57, 24, 25); this.list = new MidnightConfigListWidget(this.client, this.width, this.height, this.height - 57, 24, 25);
this.addSelectableChild(this.list); fillList(); this.addSelectableChild(this.list); fillList();
if (tabs.size() > 1) list.renderHeaderSeparator = false; if (tabs.size() > 1) list.renderHeaderSeparator = false;
} }
@@ -356,11 +377,11 @@ public abstract class MidnightConfig {
} }
if (info.modid.equals(modid) && (info.tab == null || info.tab == tabManager.getCurrentTab())) { if (info.modid.equals(modid) && (info.tab == null || info.tab == tabManager.getCurrentTab())) {
Text name = Objects.requireNonNullElseGet(info.name, () -> Text.translatable(translationPrefix + info.fieldName)); Text name = Objects.requireNonNullElseGet(info.name, () -> Text.translatable(translationPrefix + info.fieldName));
TextIconButtonWidget resetButton = TextIconButtonWidget.builder(Text.translatable("controls.reset"), (button -> { IconButtonWidget resetButton = IconButtonWidget.builder(Text.translatable("controls.reset"), Identifier.of("midnightlib","icon/reset"), (button -> {
info.value = info.defaultValue; info.listIndex = 0; info.value = info.defaultValue; info.listIndex = 0;
info.tempValue = info.toTemporaryValue(); info.tempValue = info.toTemporaryValue();
updateList(); updateList();
}), true).texture(Identifier.of("midnightlib","icon/reset"), 12, 12).dimension(20, 20).build(); }) ).build();
resetButton.setPosition(width - 205 + 150 + 25, 0); resetButton.setPosition(width - 205 + 150 + 25, 0);
if (info.function != null) { if (info.function != null) {
@@ -408,7 +429,7 @@ public abstract class MidnightConfig {
} catch (Exception ignored) {} } catch (Exception ignored) {}
info.actionButton = colorButton; info.actionButton = colorButton;
} else if (e.selectionMode() > -1) { } else if (e.selectionMode() > -1) {
ButtonWidget explorerButton = TextIconButtonWidget.builder(Text.empty(), ButtonWidget explorerButton = IconButtonWidget.builder(Text.empty(), Identifier.of("midnightlib", "icon/explorer"),
button -> new Thread(() -> { button -> new Thread(() -> {
JFileChooser fileChooser = new JFileChooser(info.tempValue); JFileChooser fileChooser = new JFileChooser(info.tempValue);
fileChooser.setFileSelectionMode(e.selectionMode()); fileChooser.setDialogType(e.fileChooserType()); fileChooser.setFileSelectionMode(e.selectionMode()); fileChooser.setDialogType(e.fileChooserType());
@@ -420,8 +441,8 @@ public abstract class MidnightConfig {
info.setValue(fileChooser.getSelectedFile().getAbsolutePath()); info.setValue(fileChooser.getSelectedFile().getAbsolutePath());
updateList(); updateList();
} }
}).start(), true }).start()
).texture(Identifier.of("midnightlib", "icon/explorer"), 12, 12).dimension(20, 20).build(); ).build();
explorerButton.setPosition(width - 185, 0); explorerButton.setPosition(width - 185, 0);
info.actionButton = explorerButton; info.actionButton = explorerButton;
} }
@@ -438,7 +459,7 @@ public abstract class MidnightConfig {
if (!info.conditionsMet) widgets.forEach(w -> w.active = false); if (!info.conditionsMet) widgets.forEach(w -> w.active = false);
this.list.addButton(widgets, name, info); this.list.addButton(widgets, name, info);
} else this.list.addButton(List.of(), name, info); } else this.list.addButton(List.of(), name, info);
} list.setScrollY(scrollProgress); } list.setScrollAmount(scrollProgress);
updateButtons(); updateButtons();
} }
} }
@@ -446,20 +467,24 @@ public abstract class MidnightConfig {
public void render(DrawContext context, int mouseX, int mouseY, float delta) { public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta); super.render(context, mouseX, mouseY, delta);
this.list.render(context, mouseX, mouseY, delta); this.list.render(context, mouseX, mouseY, delta);
if (tabs.size() < 2) context.drawCenteredTextWithShadow(textRenderer, title, width / 2, 10, 0xFFFFFF); if (tabs.size() < 2) context.drawCenteredTextWithShadow(textRenderer, title, width / 2, 10, 0xFFFFFFFF);
} }
} }
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public static class MidnightConfigListWidget extends ElementListWidget<ButtonEntry> { public static class MidnightConfigListWidget extends ElementListWidget<ButtonEntry> {
public boolean renderHeaderSeparator = true; public boolean renderHeaderSeparator = true;
public MidnightConfigListWidget(MinecraftClient client, int width, int height, int y, int itemHeight) { super(client, width, height, y, itemHeight); } public MidnightConfigListWidget(MinecraftClient client, int width, int height, int yStart, int y, int itemHeight) { super(client, width, height, yStart, y, itemHeight); }
@Override public int getScrollbarX() { return this.width -7; } @Override public int getScrollbarPositionX() { return this.width -7; }
/*
@Override @Override
protected void drawHeaderAndFooterSeparators(DrawContext context) { protected void drawHeaderAndFooterSeparators(DrawContext context) {
if (renderHeaderSeparator) super.drawHeaderAndFooterSeparators(context); if (renderHeaderSeparator) super.drawHeaderAndFooterSeparators(context);
else context.drawTexture(RenderLayer::getGuiTextured, this.client.world == null ? Screen.FOOTER_SEPARATOR_TEXTURE : Screen.INWORLD_FOOTER_SEPARATOR_TEXTURE, this.getX(), this.getBottom(), 0, 0, this.getWidth(), 2, 32, 2); else { RenderSystem.enableBlend();
context.drawTexture(this.client.world == null ? Screen.FOOTER_SEPARATOR_TEXTURE : Screen.INWORLD_FOOTER_SEPARATOR_TEXTURE, this.getX(), this.getBottom(), 0.0F, 0.0F, this.getWidth(), 2, 32, 2);
RenderSystem.disableBlend(); }
} }
*/
public void addButton(List<ClickableWidget> buttons, Text text, EntryInfo info) { this.addEntry(new ButtonEntry(buttons, text, info)); } public void addButton(List<ClickableWidget> buttons, Text text, EntryInfo info) { this.addEntry(new ButtonEntry(buttons, text, info)); }
public void clear() { this.clearEntries(); } public void clear() { this.clearEntries(); }
@Override public int getRowWidth() { return 10000; } @Override public int getRowWidth() { return 10000; }
@@ -478,21 +503,22 @@ public abstract class MidnightConfig {
int scaledWidth = MinecraftClient.getInstance().getWindow().getScaledWidth(); int scaledWidth = MinecraftClient.getInstance().getWindow().getScaledWidth();
if (text != null && (!text.getString().contains("spacer") || !buttons.isEmpty())) { if (text != null && (!text.getString().contains("spacer") || !buttons.isEmpty())) {
title = new MultilineTextWidget((centered) ? (scaledWidth / 2 - (textRenderer.getWidth(text) / 2)) : 12, 0, Text.of(text), textRenderer); title = new MultilineTextWidget((centered) ? (scaledWidth / 2 - (textRenderer.getWidth(text) / 2)) : 12, 0, text, textRenderer);
title.setCentered(centered);
if (info != null) title.setTooltip(info.getTooltip(false)); if (info != null) title.setTooltip(info.getTooltip(false));
title.setMaxWidth(buttons.size() > 1 ? buttons.get(1).getX() - 24 : scaledWidth - 24); title.setMaxWidth(!buttons.isEmpty() ? buttons.get(buttons.size() > 2 ? buttons.size()-1 : 0).getX() - 16 : scaledWidth - 24);
} }
} }
public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
buttons.forEach(b -> { b.setY(y); b.render(context, mouseX, mouseY, tickDelta);}); buttons.forEach(b -> { b.setY(y); b.render(context, mouseX, mouseY, tickDelta);});
if (title != null) { if (title != null) {
title.setY(y+5); title.setY(y+5);
title.renderWidget(context, mouseX, mouseY, tickDelta); title.render(context, mouseX, mouseY, tickDelta);
boolean tooltipVisible = mouseX >= title.getX() && mouseX < title.getWidth() + title.getX() && mouseY >= title.getY() && mouseY < title.getHeight() + title.getY(); boolean tooltipVisible = mouseX >= title.getX() && mouseX < title.getWidth() + title.getX() && mouseY >= title.getY() && mouseY < title.getHeight() + title.getY();
if (tooltipVisible && title.getTooltip() != null) context.drawOrderedTooltip(textRenderer, title.getTooltip().getLines(MinecraftClient.getInstance()), mouseX, mouseY); if (tooltipVisible && title.getTooltip() != null) context.drawOrderedTooltip(textRenderer, title.getTooltip().getLines(MinecraftClient.getInstance()), mouseX, mouseY);
if (info.entry != null && !this.buttons.isEmpty() && this.buttons.getFirst() instanceof ClickableWidget widget) { if (info.entry != null && !this.buttons.isEmpty() && this.buttons.get(0) != null) {
ClickableWidget widget = this.buttons.get(0);
int idMode = this.info.entry.idMode(); int idMode = this.info.entry.idMode();
if (idMode != -1) context.drawItem(idMode == 0 ? Registries.ITEM.get(Identifier.tryParse(this.info.tempValue)).getDefaultStack() : Registries.BLOCK.get(Identifier.tryParse(this.info.tempValue)).asItem().getDefaultStack(), widget.getX() + widget.getWidth() - 18, y + 2); if (idMode != -1) context.drawItem(idMode == 0 ? Registries.ITEM.get(Identifier.tryParse(this.info.tempValue)).getDefaultStack() : Registries.BLOCK.get(Identifier.tryParse(this.info.tempValue)).asItem().getDefaultStack(), widget.getX() + widget.getWidth() - 18, y + 2);
} }
@@ -502,7 +528,7 @@ public abstract class MidnightConfig {
@Override @Override
public boolean mouseClicked(double mouseX, double mouseY, int button) { public boolean mouseClicked(double mouseX, double mouseY, int button) {
if (this.info != null && this.info.comment != null && !this.info.comment.url().isBlank()) if (this.info != null && this.info.comment != null && !this.info.comment.url().isBlank())
ConfirmLinkScreen.open(MinecraftClient.getInstance().currentScreen, this.info.comment.url(), true); ConfirmLinkScreen.open(this.info.comment.url(), MinecraftClient.getInstance().currentScreen, true);
return super.mouseClicked(mouseX, mouseY, button); return super.mouseClicked(mouseX, mouseY, button);
} }

View File

@@ -0,0 +1,40 @@
package eu.midnightdust.lib.util.screen;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.widget.TexturedButtonWidget;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
public class TexturedOverlayButtonWidget extends TexturedButtonWidget {
public TexturedOverlayButtonWidget(int x, int y, int width, int height, int u, int v, Identifier texture, PressAction pressAction) {
super(x, y, width, height, u, v, texture, pressAction);
}
public TexturedOverlayButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, Identifier texture, PressAction pressAction) {
super(x, y, width, height, u, v, hoveredVOffset, texture, pressAction);
}
public TexturedOverlayButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, Identifier texture, int textureWidth, int textureHeight, PressAction pressAction) {
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction);
}
public TexturedOverlayButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, Identifier texture, int textureWidth, int textureHeight, PressAction pressAction, Text text) {
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, text);
}
@Override
public void renderButton(DrawContext context, int mouseX, int mouseY, float delta) {
int i = 66;
if (!this.isNarratable()) {
i += hoveredVOffset * 2;
} else if (this.isSelected()) {
i += hoveredVOffset;
}
context.drawNineSlicedTexture(WIDGETS_TEXTURE, this.getX(), this.getY(), this.width, this.height, 4, 200, 20, 0, i);
super.renderButton(context, mouseX, mouseY, delta);
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 136 B

View File

@@ -1 +1,12 @@
{"required": true,"minVersion": "0.8","package": "eu.midnightdust.core.mixin","compatibilityLevel": "JAVA_17","client": ["MixinOptionsScreen"],"injectors": {"defaultRequire": 1}} {
"required": true,
"minVersion": "0.8",
"package": "eu.midnightdust.core.mixin",
"compatibilityLevel": "JAVA_17",
"client": [
"MixinOptionsScreen"
],
"injectors": {
"defaultRequire": 1
}
}

View File

@@ -65,7 +65,7 @@ components.java {
} }
} }
unifiedPublishing { /*unifiedPublishing {
project { project {
displayName = "MidnightLib $rootProject.version - Fabric $project.minecraft_version" displayName = "MidnightLib $rootProject.version - Fabric $project.minecraft_version"
releaseType = "$project.release_type" releaseType = "$project.release_type"
@@ -85,7 +85,7 @@ unifiedPublishing {
curseforge { curseforge {
token = CURSEFORGE_TOKEN token = CURSEFORGE_TOKEN
id = rootProject.curseforge_id id = rootProject.curseforge_id
gameVersions.addAll "Java 21", project.minecraft_version gameVersions.addAll "Java 17", project.minecraft_version
if (project.supported_versions != "") gameVersions.addAll project.supported_versions if (project.supported_versions != "") gameVersions.addAll project.supported_versions
} }
} }
@@ -101,4 +101,4 @@ unifiedPublishing {
} }
} }
} }
} }*/

View File

@@ -36,7 +36,7 @@
}, },
"depends": { "depends": {
"fabric-resource-loader-v0": "*", "fabric-resource-loader-v0": "*",
"minecraft": ">=1.21" "minecraft": ">=1.20"
}, },
"mixins": [ "mixins": [

View File

@@ -1,21 +1,18 @@
org.gradle.jvmargs=-Xmx4096M org.gradle.jvmargs=-Xmx4096M
minecraft_version=1.21.4 minecraft_version=1.20.1
supported_versions=1.21.5 supported_versions=1.20
yarn_mappings=1.21.4+build.1 yarn_mappings=1.20.1+build.10
enabled_platforms=fabric,neoforge enabled_platforms=fabric
archives_base_name=midnightlib archives_base_name=midnightlib
mod_version=1.7.3 mod_version=1.7.5
maven_group=eu.midnightdust maven_group=eu.midnightdust
release_type=release # release_type=release
curseforge_id=488090 # curseforge_id=488090
modrinth_id=codAaoxh # modrinth_id=codAaoxh
fabric_loader_version=0.16.9 fabric_loader_version=0.16.14
fabric_api_version=0.110.5+1.21.4 fabric_api_version=0.92.6+1.20.1
neoforge_version=21.4.3-beta mod_menu_version = 7.2.2
yarn_mappings_patch_neoforge_version = 1.21+build.4
mod_menu_version = 9.0.0

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@@ -1,108 +0,0 @@
plugins {
id 'com.github.johnrengelman.shadow'
id "me.shedaniel.unified-publishing"
}
repositories {
maven {
name = 'NeoForged'
url = 'https://maven.neoforged.net/releases'
}
}
architectury {
platformSetupLoomIde()
neoForge()
}
loom {
accessWidenerPath = project(":common").loom.accessWidenerPath
}
configurations {
common {
canBeResolved = true
canBeConsumed = false
}
compileClasspath.extendsFrom common
runtimeClasspath.extendsFrom common
developmentNeoForge.extendsFrom common
// Files in this configuration will be bundled into your mod using the Shadow plugin.
// Don't use the `shadow` configuration from the plugin itself as it's meant for excluding files.
shadowBundle {
canBeResolved = true
canBeConsumed = false
}
archivesBaseName = rootProject.archives_base_name
version = rootProject.mod_version + "-" + project.name + "+" + rootProject.minecraft_version
}
dependencies {
neoForge "net.neoforged:neoforge:$rootProject.neoforge_version"
common(project(path: ':common', configuration: 'namedElements')) { transitive false }
shadowBundle project(path: ':common', configuration: 'transformProductionNeoForge')
}
processResources {
inputs.property 'version', rootProject.version
filesMatching('META-INF/neoforge.mods.toml') {
expand version: rootProject.version
}
}
shadowJar {
configurations = [project.configurations.shadowBundle]
archiveClassifier = 'dev-shadow'
}
remapJar {
input.set shadowJar.archiveFile
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
from commonSources.archiveFile.map { zipTree(it) }
}
components.java {
withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
skip()
}
}
unifiedPublishing {
project {
displayName = "MidnightLib $rootProject.version - NeoForge $project.minecraft_version"
releaseType = "$project.release_type"
changelog = releaseChangelog()
gameVersions = []
gameLoaders = ["neoforge"]
mainPublication remapJar
var CURSEFORGE_TOKEN = project.findProperty("CURSEFORGE_TOKEN") ?: System.getenv("CURSEFORGE_TOKEN")
if (CURSEFORGE_TOKEN != null) {
curseforge {
token = CURSEFORGE_TOKEN
id = rootProject.curseforge_id
gameVersions.addAll "Java 21", project.minecraft_version
if (project.supported_versions != "") gameVersions.addAll project.supported_versions
}
}
var MODRINTH_TOKEN = project.findProperty("MODRINTH_TOKEN") ?: System.getenv("MODRINTH_TOKEN")
if (MODRINTH_TOKEN != null) {
modrinth {
token = MODRINTH_TOKEN
id = rootProject.modrinth_id
version = rootProject.mod_version + "+" + rootProject.minecraft_version + "-" + project.name
gameVersions.addAll project.minecraft_version
if (project.supported_versions != "") gameVersions.addAll project.supported_versions
}
}
}
}

View File

@@ -1 +0,0 @@
loom.platform=neoforge

View File

@@ -1,33 +0,0 @@
package eu.midnightdust.lib.util.neoforge;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.minecraft.server.command.ServerCommandSource;
import net.neoforged.fml.ModList;
import net.neoforged.fml.loading.FMLEnvironment;
import net.neoforged.fml.loading.FMLPaths;
import java.nio.file.Path;
import static eu.midnightdust.neoforge.MidnightLibNeoForge.commands;
public class PlatformFunctionsImpl {
public static String getPlatformName() {
return "neoforge";
}
/**
* This is our actual method to {@link PlatformFunctions#getConfigDirectory()}.
*/
public static Path getConfigDirectory() {
return FMLPaths.CONFIGDIR.get();
}
public static boolean isClientEnv() {
return FMLEnvironment.dist.isClient();
}
public static boolean isModLoaded(String modid) {
return ModList.get().isLoaded(modid);
}
public static void registerCommand(LiteralArgumentBuilder<ServerCommandSource> command) {
commands.add(command);
}
}

View File

@@ -1,52 +0,0 @@
package eu.midnightdust.neoforge;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import eu.midnightdust.core.MidnightLib;
import eu.midnightdust.lib.config.MidnightConfig;
import net.minecraft.server.command.ServerCommandSource;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.ModList;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
import net.neoforged.fml.loading.FMLEnvironment;
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
import net.neoforged.neoforge.event.RegisterCommandsEvent;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.List;
@Mod("midnightlib")
public class MidnightLibNeoForge {
public static List<LiteralArgumentBuilder<ServerCommandSource>> commands = new ArrayList<>();
public MidnightLibNeoForge() {
if (FMLEnvironment.dist == Dist.CLIENT) MidnightLib.onInitializeClient();
}
@EventBusSubscriber(modid = "midnightlib", bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
public static class MidnightLibBusEvents {
@SubscribeEvent
public static void onPostInit(FMLClientSetupEvent event) {
ModList.get().forEachModContainer((modid, modContainer) -> {
if (MidnightConfig.configClass.containsKey(modid) && !MidnightLib.hiddenMods.contains(modid)) {
modContainer.registerExtensionPoint(IConfigScreenFactory.class, (minecraftClient, screen) -> MidnightConfig.getScreen(screen, modid));
}
});
MidnightLib.registerAutoCommand();
}
}
@EventBusSubscriber(modid = "midnightlib")
public static class MidnightLibEvents {
@SubscribeEvent
public static void registerCommands(RegisterCommandsEvent event) {
try {
commands.forEach(command -> event.getDispatcher().register(command));
}
catch (ConcurrentModificationException ignored) {}
}
}
}

View File

@@ -1,31 +0,0 @@
modLoader = "javafml"
loaderVersion = "[2,)"
#issueTrackerURL = ""
license = "MIT License"
[[mods]]
modId = "midnightlib"
version = "${version}"
displayName = "MidnightLib"
logoFile = "midnightlib.png"
authors = "TeamMidnightDust, Motschen"
description = '''
Common Library for Team MidnightDust's mods.
'''
[[mixins]]
config = "midnightlib.mixins.json"
[[dependencies.midnightlib]]
modId = "neoforge"
mandatory = true
versionRange = "[20.5,)"
ordering = "NONE"
side = "BOTH"
[[dependencies.midnightlib]]
modId = "minecraft"
mandatory = true
versionRange = "[1.20.5,)"
ordering = "NONE"
side = "BOTH"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -1,3 +1,4 @@
/*
plugins { plugins {
id "com.github.johnrengelman.shadow" version "7.1.2" id "com.github.johnrengelman.shadow" version "7.1.2"
} }
@@ -86,3 +87,4 @@ publishing {
// Add repositories to publish to here. // Add repositories to publish to here.
} }
} }
*/

View File

@@ -10,8 +10,8 @@ pluginManagement {
include("common") include("common")
include("fabric") include("fabric")
include("test-fabric") include("test-fabric")
include("neoforge") // include("neoforge")
include("test-neoforge") // include("test-neoforge")
//include("quilt") //include("quilt")
rootProject.name = "midnightlib" rootProject.name = "midnightlib"