Compare commits

...

23 Commits

Author SHA1 Message Date
Martin Prokoph
59989308f6 Merge pull request #37 from Suel-ki/architectury
Fix forge initialization
2023-09-09 11:33:15 +02:00
Suel_ki
29706d3e39 Add static keyword to registerCommands method 2023-07-18 10:27:18 +08:00
Suel_ki
afdd6549d3 Fix registerCommands registration 2023-07-17 16:47:52 +08:00
Suel_ki
8466b3f21a Fix ConfigScreen registration 2023-07-17 16:44:14 +08:00
Martin Prokoph
f71e8dbdc3 Update README.md 2023-06-11 12:52:21 +02:00
Motschen
dbbf546551 MidnightLib 1.4.1 - Fix tabs & Re-enable Quilt and Forge
- Fix tabs not being visible
- Re-enable Forge and Quilt support
- Fix #28
2023-06-09 18:46:53 +02:00
Motschen
9074abc331 Previous commit had a typo, it's 1.20 ;)
This commit fixes unsaved options resetting when resizing the game window
2023-05-22 12:20:35 +02:00
Motschen
8109eeb74e Update to 1.19.4 & Fix invalid value tooltips 2023-05-18 21:33:17 +02:00
Martin Prokoph
e9e1bec91f Merge pull request #26 from notlin4/patch-1
Create zh_tw.json
2023-05-18 18:41:08 +02:00
notlin4
b723253686 Create zh_tw.json 2023-04-04 23:16:14 +08:00
Motschen
e8ea0da749 Fix quilt.mod.json 2023-04-02 16:57:51 +02:00
Motschen
8ab3b9fa7d MidnightLib 1.3.0 - No more hats
- Re-enable Quilt and Forge support
- Completely remove unnecessary bloat (Hat cosmetics)
- File size is now just around 55KB for the Fabric & Quilt version, 60KB for Forge
2023-04-02 14:58:04 +02:00
Motschen
2db6b33d30 Bump version 2023-03-09 21:11:02 +01:00
Motschen
c881db8be4 Fix <Ctrl>+<Number> keybinds not working for tabs 2023-03-09 21:10:01 +01:00
Motschen
79eb8936ff Update the example config 2023-03-09 20:37:44 +01:00
Motschen
920fb797e1 Minor improvements 2023-03-09 19:50:28 +01:00
Motschen
cacd3516c1 Port to 1.19.4, Add tab support & Large code cleanup 2023-03-08 21:27:41 +01:00
Martin Prokoph
b5052ff324 Merge pull request #24 from Amirhan-Taipovjan-Greatest-I/patch-1
Tatar Translation for MidnightLib
2023-03-08 16:43:38 +01:00
Martin Prokoph
8acc9baa5a Merge pull request #22 from Calvineries/patch-1
Create fr_fr.json
2023-03-08 16:43:27 +01:00
Amirhan-Taipovjan-Greatest-I
ecda37dd13 Tatar Translation for MidnightLib 2023-02-26 09:44:44 +03:00
Motschen
1009dd9e84 Fix #23 2023-02-15 12:12:18 +01:00
Calvineries
9bfa593d4d Create fr_fr.json 2023-01-22 13:11:42 +01:00
Motschen
1ef835a015 Re-enable Quilt and Forge support 2022-12-14 18:22:32 +01:00
38 changed files with 277 additions and 476 deletions

1
.gitignore vendored
View File

@@ -17,3 +17,4 @@ classes/
.vscode .vscode
.settings .settings
*.launch *.launch
.architectury-transformer/debug.log

View File

@@ -1,5 +1,6 @@
package eu.midnightdust.core.config; package eu.midnightdust.core.config;
import com.google.common.collect.Lists;
import eu.midnightdust.lib.config.MidnightConfig; import eu.midnightdust.lib.config.MidnightConfig;
import java.util.List; import java.util.List;
@@ -12,21 +13,22 @@ import java.util.List;
public class MidnightConfigExample extends MidnightConfig { public class MidnightConfigExample extends MidnightConfig {
@Comment public static Comment text1; // Comments are rendered like an option without a button and are excluded from the config file @Comment(category = "text") public static Comment text1; // Comments are rendered like an option without a button and are excluded from the config file
@Comment(centered = true) public static Comment text2; // Centered comments are the same as normal ones - just centered! @Comment(category = "text", centered = true) public static Comment text2; // Centered comments are the same as normal ones - just centered!
@Entry public static int fabric = 16777215; // Example for an int option @Comment(category = "text") public static Comment spacer1; // Comments containing the word "spacer" will just appear as a blank line
@Entry public static double world = 1.4D; // Example for a double option @Entry(category = "text") public static boolean showInfo = true; // Example for a boolean option
@Entry public static boolean showInfo = true; // Example for a boolean option @Entry(category = "text") public static String name = "Hello World!"; // Example for a string option, which is in a category!
@Entry public static String name = "Hello World!"; // Example for a string option @Entry(category = "text") public static TestEnum testEnum = TestEnum.FABRIC; // Example for an enum option
@Entry public static TestEnum testEnum = TestEnum.FABRIC; // Example for an enum option
public enum TestEnum { // Enums allow the user to cycle through predefined options public enum TestEnum { // Enums allow the user to cycle through predefined options
QUILT, FABRIC, FORGE QUILT, FABRIC, FORGE
} }
@Entry(min=69,max=420) public static int hello = 420; // - The entered number has to be larger than 69 and smaller than 420 @Entry(category = "numbers") public static int fabric = 16777215; // Example for an int option
@Entry(width = 7, min = 7, isColor = true, name = "I am a color!") public static String titleColor = "#ffffff"; // The isColor property adds a preview box for a hexadecimal color @Entry(category = "numbers") public static double world = 1.4D; // Example for a double option
@Entry(name = "I am an array list!") public static List<String> arrayList = List.of("String1", "String2"); // Array String Lists are also supported @Entry(category = "numbers", min=69,max=420) public static int hello = 420; // - The entered number has to be larger than 69 and smaller than 420
@Entry(name = "I am an int slider.",isSlider = true, min = 0, max = 100) public static int intSlider = 35; // Int fields can also be displayed as a Slider @Entry(category = "text", width = 7, min = 7, isColor = true, name = "I am a color!") public static String titleColor = "#ffffff"; // The isColor property adds a preview box for a hexadecimal color
@Entry(name = "I am a float slider!", isSlider = true, min = 0f, max = 1f, precision = 1000) public static float floatSlider = 0.24f; // And so can floats! Precision defines the amount of decimal places @Entry(category = "text", name = "I am an array list!") public static List<String> arrayList = Lists.newArrayList("String1", "String2"); // Array String Lists are also supported
@Entry(category = "sliders", name = "I am an int slider.",isSlider = true, min = 0, max = 100) public static int intSlider = 35; // Int fields can also be displayed as a Slider
@Entry(category = "sliders", name = "I am a float slider!", isSlider = true, min = 0f, max = 1f, precision = 1000) public static float floatSlider = 0.24f; // And so can floats! Precision defines the amount of decimal places
// The name field can be used to specify a custom translation string or plain text // The name field can be used to specify a custom translation string or plain text
public static int imposter = 16777215; // - Entries without an @Entry or @Comment annotation are ignored public static int imposter = 16777215; // - Entries without an @Entry or @Comment annotation are ignored
@@ -49,11 +51,13 @@ public class MidnightConfigExample extends MidnightConfig {
"modid.midnightconfig.testEnum":"I am an enum!", "modid.midnightconfig.testEnum":"I am an enum!",
"modid.midnightconfig.enum.TestEnum.FORGE":"Slow", "modid.midnightconfig.enum.TestEnum.FORGE":"Slow",
"modid.midnightconfig.enum.TestEnum.FABRIC":"Fancy", "modid.midnightconfig.enum.TestEnum.FABRIC":"Fancy",
"modid.midnightconfig.enum.TestEnum.QUILT":"Fabulous" "modid.midnightconfig.enum.TestEnum.QUILT":"Fabulous",
"modid.midnightconfig.category.numbers": "Numbers",
"modid.midnightconfig.category.text": "Text",
"modid.midnightconfig.category.sliders": "Sliders"
} }
To initialize the config you have to call "MidnightConfig.init("modid", MidnightConfigExample.class)" in your ModInitializer To initialize the config you have to call "MidnightConfig.init("modid", MidnightConfigExample.class)" in your ModInitializer
To get an instance of the config screen you have to call "MidnightConfig.getScreen(parent, "modid");" To get an instance of the config screen you have to call "MidnightConfig.getScreen(parent, "modid");"
If you don't use the whole library and therefore not the automatic ModMenu integration, the code in your ModMenu integration class would look something like this: If you don't use the whole library and therefore not the automatic ModMenu integration, the code in your ModMenu integration class would look something like this:
@Override @Override
public ConfigScreenFactory<?> getModConfigScreenFactory() { public ConfigScreenFactory<?> getModConfigScreenFactory() {

View File

@@ -1,3 +1,3 @@
# MidnightLib # MidnightLib
Common Library for Team MidnightDust's mods. Lightweight Common Library for Minecraft mods.
Provides a config api, common utils, and cosmetics. Provides a config api with a nice GUI and common utilities, all in a very small file.

View File

@@ -1,6 +1,6 @@
plugins { plugins {
id "architectury-plugin" version "3.4-SNAPSHOT" id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "1.0-SNAPSHOT" apply false id "dev.architectury.loom" version "1.1-SNAPSHOT" apply false
} }
architectury { architectury {
@@ -15,7 +15,7 @@ subprojects {
// The following line declares the mojmap mappings, you may use other mappings as well // The following line declares the mojmap mappings, you may use other mappings as well
//mappings loom.officialMojangMappings() //mappings loom.officialMojangMappings()
// 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 "net.fabricmc:yarn:1.19.3-rc1+build.2:v2" mappings "net.fabricmc:yarn:${rootProject.yarn_mappings}:v2"
} }
} }

View File

@@ -1,7 +1,6 @@
package eu.midnightdust.core; package eu.midnightdust.core;
import eu.midnightdust.core.config.MidnightLibConfig; import eu.midnightdust.core.config.MidnightLibConfig;
import eu.midnightdust.hats.web.HatLoader;
import eu.midnightdust.lib.config.MidnightConfig; import eu.midnightdust.lib.config.MidnightConfig;
import java.util.ArrayList; import java.util.ArrayList;
@@ -10,12 +9,7 @@ import java.util.List;
public class MidnightLibClient { public class MidnightLibClient {
public static List<String> hiddenMods = new ArrayList<>(); public static List<String> hiddenMods = new ArrayList<>();
public static final String MOD_ID = "midnightlib";
public static void onInitializeClient() { public static void onInitializeClient() {
MidnightConfig.init("midnightlib", MidnightLibConfig.class); MidnightConfig.init("midnightlib", MidnightLibConfig.class);
hiddenMods.add("puzzle");
if (MidnightLibConfig.special_hats) HatLoader.init();
} }
} }

View File

@@ -4,12 +4,8 @@ import eu.midnightdust.lib.config.MidnightConfig;
import eu.midnightdust.lib.util.PlatformFunctions; import eu.midnightdust.lib.util.PlatformFunctions;
public class MidnightLibConfig extends MidnightConfig { public class MidnightLibConfig extends MidnightConfig {
@Comment(centered = true) public static Comment midnightlib_description;
@Entry // Enable or disable the MidnightConfig overview screen button @Entry // Enable or disable the MidnightConfig overview screen button
public static ConfigButton config_screen_list = PlatformFunctions.isModLoaded("modmenu") ? ConfigButton.MODMENU : ConfigButton.TRUE; public static ConfigButton config_screen_list = PlatformFunctions.isModLoaded("modmenu") ? ConfigButton.MODMENU : ConfigButton.TRUE;
@Comment(centered = true) public static Comment midnighthats_description;
@Entry // Enable or disable hats for contributors, friends and donors.
public static boolean special_hats = true;
public enum ConfigButton { public enum ConfigButton {
TRUE,FALSE,MODMENU TRUE,FALSE,MODMENU

View File

@@ -1,24 +0,0 @@
package eu.midnightdust.core.mixin;
import eu.midnightdust.hats.witch.WitchHatFeatureRenderer;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.client.render.entity.PlayerEntityRenderer;
import net.minecraft.client.render.entity.model.PlayerEntityModel;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(PlayerEntityRenderer.class)
public abstract class MixinPlayerEntityRenderer extends LivingEntityRenderer<AbstractClientPlayerEntity, PlayerEntityModel<AbstractClientPlayerEntity>> {
public MixinPlayerEntityRenderer(EntityRendererFactory.Context ctx, PlayerEntityModel<AbstractClientPlayerEntity> model, float shadowSize) {
super(ctx, model, shadowSize);
}
@Inject(at = @At("TAIL"), method = "<init>")
public void addFeatures(EntityRendererFactory.Context ctx, boolean slim, CallbackInfo ci) {
this.addFeature(new WitchHatFeatureRenderer<>(this, ctx.getModelLoader()));
}
}

View File

@@ -6,6 +6,7 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.Element; import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.Selectable; import net.minecraft.client.gui.Selectable;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
@@ -37,17 +38,17 @@ public class MidnightConfigOverviewScreen extends Screen {
sortedMods.forEach((modid) -> { sortedMods.forEach((modid) -> {
if (!MidnightLibClient.hiddenMods.contains(modid)) { if (!MidnightLibClient.hiddenMods.contains(modid)) {
list.addButton(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 - 100, this.height - 28, 200, 20).build()); 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(MatrixStack matrices, int mouseX, int mouseY, float delta) { public void render(DrawContext context, int mouseX, int mouseY, float delta) {
this.renderBackground(matrices); this.renderBackground(context);
this.list.render(matrices, mouseX, mouseY, delta); this.list.render(context, mouseX, mouseY, delta);
drawCenteredText(matrices, textRenderer, title, width / 2, 15, 0xFFFFFF); context.drawCenteredTextWithShadow(textRenderer, title, width / 2, 15, 0xFFFFFF);
super.render(matrices, mouseX, mouseY, delta); super.render(context, mouseX, mouseY, delta);
} }
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public static class MidnightOverviewListWidget extends ElementListWidget<OverviewButtonEntry> { public static class MidnightOverviewListWidget extends ElementListWidget<OverviewButtonEntry> {
@@ -76,9 +77,9 @@ public class MidnightConfigOverviewScreen extends Screen {
this.buttonList.add(button); this.buttonList.add(button);
} }
public static OverviewButtonEntry create(ClickableWidget button) {return new OverviewButtonEntry(button);} public static OverviewButtonEntry create(ClickableWidget button) {return new OverviewButtonEntry(button);}
public void render(MatrixStack matrices, 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) {
button.setY(y); button.setY(y);
button.render(matrices, mouseX, mouseY, tickDelta); button.render(context, mouseX, mouseY, tickDelta);
} }
public List<? extends Element> children() {return buttonList;} public List<? extends Element> children() {return buttonList;}
public List<? extends Selectable> selectableChildren() {return buttonList;} public List<? extends Selectable> selectableChildren() {return buttonList;}

View File

@@ -1,49 +0,0 @@
package eu.midnightdust.hats.web;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.minecraft.client.MinecraftClient;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
@SuppressWarnings("UnstableApiUsage")
public class HatLoader {
public static final System.Logger logger = System.getLogger("MidnightLib");
private final static String HATS_URL = "https://raw.githubusercontent.com/TeamMidnightDust/MidnightHats/master/hats.json";
public static final Type HAT_TYPE = new TypeToken<Map<UUID, PlayerHatData>>(){}.getType();
public static Map<UUID, PlayerHatData> PLAYER_HATS;
private static final Gson GSON = new GsonBuilder().create();
public static void init() {
CompletableFuture.supplyAsync(() -> {
try (Reader reader = new InputStreamReader(new URL(HATS_URL).openStream())) {
return GSON.<Map<UUID, PlayerHatData>>fromJson(reader, HAT_TYPE);
} catch (MalformedURLException error) {
logger.log(System.Logger.Level.ERROR, "Unable to load player hats because of connection problems: " + error.getMessage());
} catch (IOException error) {
logger.log(System.Logger.Level.ERROR, "Unable to load player hats because of an I/O Exception: " + error.getMessage());
}
return null;
}).thenAcceptAsync(playerData -> {
if (playerData != null) {
PLAYER_HATS = playerData;
System.out.println("(MidnightLib) Player hats successfully loaded!");
} else {
PLAYER_HATS = Collections.emptyMap();
logger.log(System.Logger.Level.WARNING, "A problem with the database occurred, the hats could not be initialized.");
}
}, MinecraftClient.getInstance());
}
}

View File

@@ -1,13 +0,0 @@
package eu.midnightdust.hats.web;
public class PlayerHatData {
private final String hat;
public PlayerHatData(String hat) {
this.hat = hat;
}
public String getHatType() {
return hat;
}
}

View File

@@ -1,82 +0,0 @@
package eu.midnightdust.hats.witch;
import eu.midnightdust.hats.web.HatLoader;
import eu.midnightdust.lib.util.MidnightColorUtil;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.model.TexturedModelData;
import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.entity.model.EntityModelLayer;
import net.minecraft.client.render.entity.model.EntityModelLoader;
import net.minecraft.client.render.entity.model.ModelWithHead;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier;
import java.awt.*;
import java.util.UUID;
import static eu.midnightdust.core.MidnightLibClient.MOD_ID;
@Environment(EnvType.CLIENT)
public class WitchHatFeatureRenderer<T extends LivingEntity, M extends EntityModel<T>> extends FeatureRenderer<T, M> {
public static final EntityModelLayer WITCH_HAT_MODEL_LAYER = new EntityModelLayer(new Identifier("midnight-hats","witch_hat"), "main");
private static final UUID MOTSCHEN = UUID.fromString("a44c2660-630f-478f-946a-e518669fcf0c");
private static final Identifier WITCH = new Identifier("textures/entity/witch.png");
private static final Identifier OVERLAY = new Identifier(MOD_ID,"textures/hats/overlay.png");
private static final Color MOTSCHEN_COLOR = MidnightColorUtil.radialRainbow(1,1);
private static final Color ADOPTER_COLOR = MidnightColorUtil.hex2Rgb("ffffff");
private static final Color MODDER_COLOR = MidnightColorUtil.hex2Rgb("7825b4");
private static final Color FRIEND_COLOR = MidnightColorUtil.hex2Rgb("ff0234");
private static final Color DONOR_COLOR = MidnightColorUtil.hex2Rgb("ff6c00");
private static final Color SOCIAL_COLOR = MidnightColorUtil.hex2Rgb("238a9d");
private final WitchHatModel<T> witchHat;
private final MinecraftClient client = MinecraftClient.getInstance();
public WitchHatFeatureRenderer(FeatureRendererContext<T, M> featureRendererContext, EntityModelLoader entityModelLoader) {
super(featureRendererContext);
this.witchHat = new WitchHatModel<>(entityModelLoader.getModelPart(WITCH_HAT_MODEL_LAYER));
}
public static TexturedModelData getTexturedModelData() {
return TexturedModelData.of(WitchHatModel.getModelData(), 64, 128);
}
public void render(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, T livingEntity, float f, float g, float h, float j, float k, float l) {
Color hat_type = getHat(livingEntity.getUuid());
if (hat_type != null && !livingEntity.isInvisibleTo(client.player)) {
if (hat_type == MOTSCHEN_COLOR) hat_type = MidnightColorUtil.radialRainbow(1,1);
matrixStack.push();
((ModelWithHead) this.getContextModel()).getHead().rotate(matrixStack);
VertexConsumer vertexConsumer = vertexConsumerProvider.getBuffer(RenderLayer.getEntityCutoutNoCull(WITCH));
this.witchHat.render(matrixStack, vertexConsumer, i, OverlayTexture.DEFAULT_UV,1f,1f,1f,1);
VertexConsumer glow = vertexConsumerProvider.getBuffer(RenderLayer.getBeaconBeam(OVERLAY,true));
matrixStack.translate(0,0,-0.001f);
this.witchHat.render(matrixStack, glow, 230, OverlayTexture.DEFAULT_UV, hat_type.getRed() / 255f, hat_type.getGreen() / 255f, hat_type.getBlue() / 255f, 1.0F);
matrixStack.pop();
}
}
private Color getHat(UUID uuid) {
if (uuid.equals(MOTSCHEN)) {
return MOTSCHEN_COLOR;
} else if (HatLoader.PLAYER_HATS != null && HatLoader.PLAYER_HATS.containsKey(uuid)) {
return switch (HatLoader.PLAYER_HATS.get(uuid).getHatType()) {
case "adopter" -> ADOPTER_COLOR;
case "contributer", "modder" -> MODDER_COLOR;
case "friend" -> FRIEND_COLOR;
case "donator", "donor" -> DONOR_COLOR;
case "social" -> SOCIAL_COLOR;
default -> MidnightColorUtil.hex2Rgb(HatLoader.PLAYER_HATS.get(uuid).getHatType());
};
}
return null;
}
}

View File

@@ -1,59 +0,0 @@
package eu.midnightdust.hats.witch;
import net.minecraft.client.model.*;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.entity.model.SinglePartEntityModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
public class WitchHatModel<T extends LivingEntity> extends SinglePartEntityModel<T> {
private final ModelPart headwear;
public WitchHatModel(ModelPart root) {
headwear = root;
root.setPivot(5.0F, -9.0F, -5.0F);
ModelPart bone = headwear.getChild("bone");
bone.setPivot(-8.5F, -0.1F, 1.5F);
setRotationAngle(bone, -0.0524F, 0.0F, 0.0349F);
ModelPart bone2 = bone.getChild("bone2");
bone2.setPivot(1.5F, -4.0F, 1.5F);
setRotationAngle(bone2, -0.1222F, 0.0F, 0.0698F);
ModelPart bone3 = bone2.getChild("bone3");
bone3.setPivot(1.5F, -4.0F, 1.5F);
setRotationAngle(bone3, -0.2618F, 0.0F, 0.1047F);
}
public static ModelData getModelData(){
ModelData modelData = new ModelData();
ModelPartData modelPartData = modelData.getRoot();
modelPartData.addChild("headwear", ModelPartBuilder.create().uv(0, 64).cuboid(-10.0F, -0.1F, 0.0F, 10.0F, 2.0F, 10.0F), ModelTransform.NONE);
ModelPartData modelPartData2 = modelPartData.addChild("bone", ModelPartBuilder.create().uv(0, 76).cuboid(0.0F, -4.0F, 0.0F, 7.0F, 4.0F, 7.0F), ModelTransform.rotation(-0.0524F, 0.0F, 0.0349F));
ModelPartData modelPartData3 = modelPartData2.addChild("bone2", ModelPartBuilder.create().uv(0, 87).cuboid(0.0F, -4.0F, 0.0F, 4.0F, 4.0F, 4.0F), ModelTransform.rotation(-0.1222F, 0.0F, 0.0698F));
modelPartData3.addChild("bone3", ModelPartBuilder.create().uv(0, 95).cuboid(0.0F, -2.0F, 0.0F, 1.0F, 2.0F, 1.0F), ModelTransform.rotation(-0.2618F, 0.0F, 0.1047F));
return modelData;
}
@Override
public void setAngles(T entity, float limbAngle, float limbDistance, float animationProgress, float headYaw, float headPitch) {
}
@Override
public void render(MatrixStack matrixStack, VertexConsumer buffer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha){
headwear.render(matrixStack, buffer, packedLight, packedOverlay, red, green, blue, alpha);
}
@Override
public ModelPart getPart() {
return headwear;
}
public void setRotationAngle(ModelPart bone, float x, float y, float z) {
bone.pitch = x;
bone.yaw = y;
bone.roll = z;
}
}

View File

@@ -80,15 +80,17 @@ public class AutoCommand {
return 0; return 0;
} }
source.sendFeedback(Text.literal("Successfully set " + entry.getName()+" to "+value), true); source.sendFeedback(() -> Text.literal("Successfully set " + entry.getName()+" to "+value), true);
return 1; return 1;
} }
private int getValue(ServerCommandSource source) { private int getValue(ServerCommandSource source) {
source.sendFeedback(() -> {
try { try {
source.sendFeedback(Text.literal("The value of "+entry.getName()+" is "+entry.get(null)), false); return Text.literal("The value of "+entry.getName()+" is "+entry.get(null));
return 1; } catch (IllegalAccessException e) {
throw new RuntimeException(e);
} }
catch (IllegalAccessException ignored) {} }, false);
return 0; return 0;
} }
} }

View File

@@ -9,15 +9,18 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer; import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawableHelper; import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.Element; import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.Selectable; 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.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.tooltip.Tooltip;
import net.minecraft.client.gui.widget.*; import net.minecraft.client.gui.widget.*;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.screen.ScreenTexts; import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.OrderedText;
import net.minecraft.text.Style; import net.minecraft.text.Style;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
@@ -38,10 +41,9 @@ import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** MidnightConfig v2.4.0 by TeamMidnightDust & Motschen /** MidnightConfig v2.4.1 by TeamMidnightDust & Motschen
* 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 https://github.com/Minenash/TinyConfig
* Credits to Minenash */ * Credits to Minenash */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -56,9 +58,8 @@ public abstract class MidnightConfig {
Field field; Field field;
Object widget; Object widget;
int width; int width;
int max;
boolean centered; boolean centered;
Map.Entry<TextFieldWidget,Text> error; Text error;
Object defaultValue; Object defaultValue;
Object value; Object value;
String tempValue; String tempValue;
@@ -67,6 +68,7 @@ public abstract class MidnightConfig {
Text name; Text name;
int index; int index;
ClickableWidget colorButton; ClickableWidget colorButton;
Tab tab;
} }
public static final Map<String,Class<?>> configClass = new HashMap<>(); public static final Map<String,Class<?>> configClass = new HashMap<>();
@@ -80,8 +82,8 @@ public abstract class MidnightConfig {
for (Field field : config.getFields()) { for (Field field : config.getFields()) {
EntryInfo info = new EntryInfo(); EntryInfo info = new EntryInfo();
if ((field.isAnnotationPresent(Entry.class) || field.isAnnotationPresent(Comment.class)) && !field.isAnnotationPresent(Server.class) && !field.isAnnotationPresent(Hidden.class)) if ((field.isAnnotationPresent(Entry.class) || field.isAnnotationPresent(Comment.class)) && !field.isAnnotationPresent(Server.class) && !field.isAnnotationPresent(Hidden.class) && PlatformFunctions.isClientEnv())
if (PlatformFunctions.isClientEnv()) initClient(modid, field, info); initClient(modid, field, info);
if (field.isAnnotationPresent(Comment.class)) info.centered = field.getAnnotation(Comment.class).centered(); if (field.isAnnotationPresent(Comment.class)) info.centered = field.getAnnotation(Comment.class).centered();
if (field.isAnnotationPresent(Entry.class)) if (field.isAnnotationPresent(Entry.class))
try { try {
@@ -112,10 +114,8 @@ public abstract class MidnightConfig {
if (type == int.class) textField(info, Integer::parseInt, INTEGER_ONLY, (int) e.min(), (int) e.max(), true); if (type == int.class) textField(info, Integer::parseInt, INTEGER_ONLY, (int) e.min(), (int) e.max(), true);
else if (type == float.class) textField(info, Float::parseFloat, DECIMAL_ONLY, (float) e.min(), (float) e.max(), false); else if (type == float.class) textField(info, Float::parseFloat, DECIMAL_ONLY, (float) e.min(), (float) e.max(), false);
else if (type == double.class) textField(info, Double::parseDouble, DECIMAL_ONLY, e.min(), e.max(), false); else if (type == double.class) textField(info, Double::parseDouble, DECIMAL_ONLY, e.min(), e.max(), false);
else if (type == String.class || type == List.class) { else if (type == String.class || type == List.class) textField(info, String::length, null, Math.min(e.min(), 0), Math.max(e.max(), 1), true);
info.max = e.max() == Double.MAX_VALUE ? Integer.MAX_VALUE : (int) e.max(); else if (type == boolean.class) {
textField(info, String::length, null, Math.min(e.min(), 0), Math.max(e.max(), 1), true);
} else if (type == boolean.class) {
Function<Object, Text> func = value -> Text.translatable((Boolean) value ? "gui.yes" : "gui.no").formatted((Boolean) value ? Formatting.GREEN : Formatting.RED); Function<Object, Text> func = value -> Text.translatable((Boolean) value ? "gui.yes" : "gui.no").formatted((Boolean) value ? Formatting.GREEN : Formatting.RED);
info.widget = new AbstractMap.SimpleEntry<ButtonWidget.PressAction, Function<Object, Text>>(button -> { info.widget = new AbstractMap.SimpleEntry<ButtonWidget.PressAction, Function<Object, Text>>(button -> {
info.value = !(Boolean) info.value; info.value = !(Boolean) info.value;
@@ -133,6 +133,9 @@ public abstract class MidnightConfig {
} }
entries.add(info); entries.add(info);
} }
public static Tooltip getTooltip(EntryInfo info) {
return Tooltip.of(info.error != null ? info.error : I18n.hasTranslation(info.id + ".midnightconfig."+info.field.getName()+".tooltip") ? Text.translatable(info.id + ".midnightconfig."+info.field.getName()+".tooltip") : Text.empty());
}
private static void textField(EntryInfo info, Function<String,Number> f, Pattern pattern, double min, double max, boolean cast) { private static void textField(EntryInfo info, Function<String,Number> f, Pattern pattern, double min, double max, boolean cast) {
boolean isNumber = pattern != null; boolean isNumber = pattern != null;
@@ -146,9 +149,10 @@ public abstract class MidnightConfig {
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; }
inLimits = value.doubleValue() >= min && value.doubleValue() <= max; inLimits = value.doubleValue() >= min && value.doubleValue() <= max;
info.error = inLimits? null : new AbstractMap.SimpleEntry<>(t, Text.literal(value.doubleValue() < min ? info.error = inLimits? null : Text.literal(value.doubleValue() < min ?
"§cMinimum " + (isNumber? "value" : "length") + (cast? " is " + (int)min : " is " + min) : "§cMinimum " + (isNumber? "value" : "length") + (cast? " is " + (int)min : " is " + min) :
"§cMaximum " + (isNumber? "value" : "length") + (cast? " is " + (int)max : " is " + max))); "§cMaximum " + (isNumber? "value" : "length") + (cast? " is " + (int)max : " is " + max)).formatted(Formatting.RED);
t.setTooltip(getTooltip(info));
} }
info.tempValue = s; info.tempValue = s;
@@ -194,17 +198,49 @@ public abstract class MidnightConfig {
this.parent = parent; this.parent = parent;
this.modid = modid; this.modid = modid;
this.translationPrefix = modid + ".midnightconfig."; this.translationPrefix = modid + ".midnightconfig.";
loadValues();
for (EntryInfo e : entries) {
if (e.id.equals(modid)) {
String tabId = e.field.isAnnotationPresent(Entry.class) ? e.field.getAnnotation(Entry.class).category() : e.field.getAnnotation(Comment.class).category();
String name = translationPrefix + "category." + tabId;
if (!I18n.hasTranslation(name) && tabId.equals("default"))
name = translationPrefix + "title";
if (!tabs.containsKey(name)) {
Tab tab = new GridScreenTab(Text.translatable(name));
e.tab = tab;
tabs.put(name, tab);
} else e.tab = tabs.get(name);
}
}
tabNavigation = TabNavigationWidget.builder(tabManager, this.width).tabs(tabs.values().toArray(new Tab[0])).build();
tabNavigation.selectTab(0, false);
tabNavigation.init();
prevTab = tabManager.getCurrentTab();
} }
public final String translationPrefix; public final String translationPrefix;
public final Screen parent; public final Screen parent;
public final String modid; public final String modid;
public MidnightConfigListWidget list; public MidnightConfigListWidget list;
public boolean reload = false; public boolean reload = false;
public TabManager tabManager = new TabManager(a -> {}, a -> {});
public Map<String, Tab> tabs = new HashMap<>();
public Tab prevTab;
public TabNavigationWidget tabNavigation;
public ButtonWidget done;
public double scrollProgress = 0d;
// Real Time config update // // Real Time config update //
@Override @Override
public void tick() { public void tick() {
super.tick(); super.tick();
if (prevTab != null && prevTab != tabManager.getCurrentTab()) {
prevTab = tabManager.getCurrentTab();
this.list.clear();
fillList();
list.setScrollAmount(0);
}
scrollProgress = list.getScrollAmount();
for (EntryInfo info : entries) { for (EntryInfo info : entries) {
try {info.field.set(null, info.value);} catch (IllegalAccessException ignored) {} try {info.field.set(null, info.value);} catch (IllegalAccessException ignored) {}
} }
@@ -231,20 +267,23 @@ public abstract class MidnightConfig {
} catch (IllegalAccessException ignored) {} } catch (IllegalAccessException ignored) {}
} }
} }
public Tooltip getTooltip(EntryInfo info) { @Override
return Tooltip.of(I18n.hasTranslation(translationPrefix+info.field.getName()+".tooltip") ? Text.translatable(translationPrefix+info.field.getName()+".tooltip") : Text.empty()); public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (this.tabNavigation.trySwitchTabsWithKey(keyCode)) return true;
return super.keyPressed(keyCode, scanCode, modifiers);
} }
@Override @Override
public void init() { public void init() {
super.init(); super.init();
if (!reload) loadValues(); tabNavigation.setWidth(this.width);
tabNavigation.init();
if (tabs.size() > 1) this.addDrawableChild(tabNavigation);
this.addDrawableChild(ButtonWidget.builder(ScreenTexts.CANCEL, button -> { this.addDrawableChild(ButtonWidget.builder(ScreenTexts.CANCEL, button -> {
loadValues(); loadValues();
Objects.requireNonNull(client).setScreen(parent); Objects.requireNonNull(client).setScreen(parent);
}).dimensions(this.width / 2 - 154, this.height - 28, 150, 20).build()); }).dimensions(this.width / 2 - 154, this.height - 28, 150, 20).build());
done = this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, (button) -> {
ButtonWidget done = this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, (button) -> {
for (EntryInfo info : entries) for (EntryInfo info : entries)
if (info.id.equals(modid)) { if (info.id.equals(modid)) {
try { try {
@@ -258,48 +297,53 @@ public abstract class MidnightConfig {
this.list = new MidnightConfigListWidget(this.client, this.width, this.height, 32, this.height - 32, 25); this.list = new MidnightConfigListWidget(this.client, this.width, this.height, 32, this.height - 32, 25);
if (this.client != null && this.client.world != null) this.list.setRenderBackground(false); if (this.client != null && this.client.world != null) this.list.setRenderBackground(false);
this.addSelectableChild(this.list); this.addSelectableChild(this.list);
fillList();
reload = true;
}
public void fillList() {
for (EntryInfo info : entries) { for (EntryInfo info : entries) {
if (info.id.equals(modid)) { if (info.id.equals(modid) && (info.tab == null || info.tab == tabManager.getCurrentTab())) {
Text name = Objects.requireNonNullElseGet(info.name, () -> Text.translatable(translationPrefix + info.field.getName())); Text name = Objects.requireNonNullElseGet(info.name, () -> Text.translatable(translationPrefix + info.field.getName()));
ButtonWidget resetButton = ButtonWidget.builder(Text.literal("Reset").formatted(Formatting.RED), (button -> { ButtonWidget resetButton = ButtonWidget.builder(Text.literal("Reset").formatted(Formatting.RED), (button -> {
info.value = info.defaultValue; info.value = info.defaultValue;
info.tempValue = info.defaultValue.toString(); info.tempValue = info.defaultValue.toString();
info.index = 0; info.index = 0;
double scrollAmount = list.getScrollAmount(); list.clear();
this.reload = true; fillList();
Objects.requireNonNull(client).setScreen(this);
list.setScrollAmount(scrollAmount);
})).dimensions(width - 205, 0, 40, 20).build(); })).dimensions(width - 205, 0, 40, 20).build();
if (info.widget instanceof Map.Entry) { if (info.widget instanceof Map.Entry) {
Map.Entry<ButtonWidget.PressAction, Function<Object, Text>> widget = (Map.Entry<ButtonWidget.PressAction, Function<Object, Text>>) info.widget; Map.Entry<ButtonWidget.PressAction, Function<Object, Text>> widget = (Map.Entry<ButtonWidget.PressAction, Function<Object, Text>>) info.widget;
if (info.field.getType().isEnum()) widget.setValue(value -> Text.translatable(translationPrefix + "enum." + info.field.getType().getSimpleName() + "." + info.value.toString())); if (info.field.getType().isEnum())
widget.setValue(value -> Text.translatable(translationPrefix + "enum." + info.field.getType().getSimpleName() + "." + info.value.toString()));
this.list.addButton(List.of(ButtonWidget.builder(widget.getValue().apply(info.value), widget.getKey()).dimensions(width - 160, 0, 150, 20).tooltip(getTooltip(info)).build(), resetButton), name, info); this.list.addButton(List.of(ButtonWidget.builder(widget.getValue().apply(info.value), widget.getKey()).dimensions(width - 160, 0, 150, 20).tooltip(getTooltip(info)).build(), resetButton), name, info);
} else if (info.field.getType() == List.class) { } else if (info.field.getType() == List.class) {
if (!reload) info.index = 0; if (!reload) info.index = 0;
TextFieldWidget widget = new TextFieldWidget(textRenderer, width - 160, 0, 150, 20, Text.empty()); TextFieldWidget widget = new TextFieldWidget(textRenderer, width - 160, 0, 150, 20, Text.empty());
widget.setMaxLength(info.width); widget.setMaxLength(info.width);
if (info.index < ((List<String>)info.value).size()) widget.setText((String.valueOf(((List<String>)info.value).get(info.index)))); if (info.index < ((List<String>) info.value).size())
widget.setText((String.valueOf(((List<String>) info.value).get(info.index))));
Predicate<String> processor = ((BiFunction<TextFieldWidget, ButtonWidget, Predicate<String>>) info.widget).apply(widget, done); Predicate<String> processor = ((BiFunction<TextFieldWidget, ButtonWidget, Predicate<String>>) info.widget).apply(widget, done);
widget.setTextPredicate(processor); widget.setTextPredicate(processor);
resetButton.setWidth(20); resetButton.setWidth(20);
resetButton.setMessage(Text.literal("R").formatted(Formatting.RED)); resetButton.setMessage(Text.literal("R").formatted(Formatting.RED));
ButtonWidget cycleButton = ButtonWidget.builder(Text.literal(String.valueOf(info.index)).formatted(Formatting.GOLD), (button -> { ButtonWidget cycleButton = ButtonWidget.builder(Text.literal(String.valueOf(info.index)).formatted(Formatting.GOLD), (button -> {
((List<String>)info.value).remove(""); if (((List<?>) info.value).contains("")) ((List<String>) info.value).remove("");
double scrollAmount = list.getScrollAmount();
this.reload = true;
info.index = info.index + 1; info.index = info.index + 1;
if (info.index > ((List<String>) info.value).size()) info.index = 0; if (info.index > ((List<String>) info.value).size()) info.index = 0;
Objects.requireNonNull(client).setScreen(this); list.clear();
list.setScrollAmount(scrollAmount); fillList();
})).dimensions(width - 185, 0, 20, 20).build(); })).dimensions(width - 185, 0, 20, 20).build();
widget.setTooltip(getTooltip(info)); widget.setTooltip(getTooltip(info));
this.list.addButton(List.of(widget, resetButton, cycleButton), name, info); this.list.addButton(List.of(widget, resetButton, cycleButton), name, info);
} else if (info.widget != null) { } else if (info.widget != null) {
ClickableWidget widget; ClickableWidget widget;
Entry e = info.field.getAnnotation(Entry.class); Entry e = info.field.getAnnotation(Entry.class);
if (e.isSlider()) widget = new MidnightSliderWidget(width - 160, 0, 150, 20, Text.of(info.tempValue), (Double.parseDouble(info.tempValue)-e.min()) / (e.max() - e.min()), info); if (e.isSlider())
else widget = new TextFieldWidget(textRenderer, width - 160, 0, 150, 20, null, Text.of(info.tempValue)); widget = new MidnightSliderWidget(width - 160, 0, 150, 20, Text.of(info.tempValue), (Double.parseDouble(info.tempValue) - e.min()) / (e.max() - e.min()), info);
else
widget = new TextFieldWidget(textRenderer, width - 160, 0, 150, 20, null, Text.of(info.tempValue));
if (widget instanceof TextFieldWidget textField) { if (widget instanceof TextFieldWidget textField) {
textField.setMaxLength(info.width); textField.setMaxLength(info.width);
textField.setText(info.tempValue); textField.setText(info.tempValue);
@@ -310,27 +354,31 @@ public abstract class MidnightConfig {
if (e.isColor()) { if (e.isColor()) {
resetButton.setWidth(20); resetButton.setWidth(20);
resetButton.setMessage(Text.literal("R").formatted(Formatting.RED)); resetButton.setMessage(Text.literal("R").formatted(Formatting.RED));
ButtonWidget colorButton = ButtonWidget.builder(Text.literal(""), (button -> {})).dimensions(width - 185, 0, 20, 20).build(); ButtonWidget colorButton = ButtonWidget.builder(Text.literal(""), (button -> {
try {colorButton.setMessage(Text.literal("").setStyle(Style.EMPTY.withColor(Color.decode(info.tempValue).getRGB())));} catch (Exception ignored) {} })).dimensions(width - 185, 0, 20, 20).build();
try {
colorButton.setMessage(Text.literal("").setStyle(Style.EMPTY.withColor(Color.decode(info.tempValue).getRGB())));
} catch (Exception ignored) {
}
info.colorButton = colorButton; info.colorButton = colorButton;
colorButton.active = false; colorButton.active = false;
this.list.addButton(List.of(widget, resetButton, colorButton), name, info); this.list.addButton(List.of(widget, resetButton, colorButton), name, info);
} } else this.list.addButton(List.of(widget, resetButton), name, info);
else this.list.addButton(List.of(widget, resetButton), name, info);
} else { } else {
this.list.addButton(List.of(), name, info); this.list.addButton(List.of(), name, info);
} }
} }
list.setScrollAmount(scrollProgress);
updateResetButtons(); updateResetButtons();
} }
} }
@Override @Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { public void render(DrawContext context, int mouseX, int mouseY, float delta) {
this.renderBackground(matrices); this.renderBackground(context);
this.list.render(matrices, mouseX, mouseY, delta); this.list.render(context, mouseX, mouseY, delta);
drawCenteredText(matrices, textRenderer, title, width / 2, 15, 0xFFFFFF);
super.render(matrices,mouseX,mouseY,delta); if (tabs.size() < 2) context.drawCenteredTextWithShadow(textRenderer, title, width / 2, 15, 0xFFFFFF);
super.render(context,mouseX,mouseY,delta);
} }
} }
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
@@ -348,16 +396,11 @@ public abstract class MidnightConfig {
public void addButton(List<ClickableWidget> buttons, Text text, EntryInfo info) { public void addButton(List<ClickableWidget> buttons, Text text, EntryInfo info) {
this.addEntry(new ButtonEntry(buttons, text, info)); this.addEntry(new ButtonEntry(buttons, text, info));
} }
public void clear() {
this.clearEntries();
}
@Override @Override
public int getRowWidth() { return 10000; } public int getRowWidth() { return 10000; }
public Optional<ClickableWidget> getHoveredButton(double mouseX, double mouseY) {
for (ButtonEntry buttonEntry : this.children()) {
if (!buttonEntry.buttons.isEmpty() && buttonEntry.buttons.get(0).isMouseOver(mouseX, mouseY)) {
return Optional.of(buttonEntry.buttons.get(0));
}
}
return Optional.empty();
}
} }
public static class ButtonEntry extends ElementListWidget.Entry<ButtonEntry> { public static class ButtonEntry extends ElementListWidget.Entry<ButtonEntry> {
private static final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; private static final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
@@ -374,17 +417,23 @@ public abstract class MidnightConfig {
this.info = info; this.info = info;
children.addAll(buttons); children.addAll(buttons);
} }
public void render(MatrixStack matrices, 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(matrices, mouseX, mouseY, tickDelta); }); buttons.forEach(b -> { b.setY(y); b.render(context, mouseX, mouseY, tickDelta); });
if (text != null && (!text.getString().contains("spacer") || !buttons.isEmpty())) { if (text != null && (!text.getString().contains("spacer") || !buttons.isEmpty())) {
if (info.centered) textRenderer.drawWithShadow(matrices, text, MinecraftClient.getInstance().getWindow().getScaledWidth() / 2f - (textRenderer.getWidth(text) / 2f), y + 5, 0xFFFFFF); if (info.centered) context.drawTextWithShadow(textRenderer, text, MinecraftClient.getInstance().getWindow().getScaledWidth() / 2 - (textRenderer.getWidth(text) / 2), y + 5, 0xFFFFFF);
else DrawableHelper.drawTextWithShadow(matrices, textRenderer, text, 12, y + 5, 0xFFFFFF); else {
int wrappedY = y;
for(Iterator<OrderedText> iterator = textRenderer.wrapLines(text, (buttons.size() > 1 ? buttons.get(1).getX()-24 : MinecraftClient.getInstance().getWindow().getScaledWidth() - 24)).iterator(); iterator.hasNext(); wrappedY += 9) {
OrderedText orderedText = iterator.next();
context.drawTextWithShadow(textRenderer, orderedText, 12, wrappedY + 5, 0xFFFFFF);
}
}
} }
} }
public List<? extends Element> children() {return children;} public List<? extends Element> children() {return children;}
public List<? extends Selectable> selectableChildren() {return children;} public List<? extends Selectable> selectableChildren() {return children;}
} }
private static class MidnightSliderWidget extends SliderWidget { public static class MidnightSliderWidget extends SliderWidget {
private final EntryInfo info; private final Entry e; private final EntryInfo info; private final Entry e;
public MidnightSliderWidget(int x, int y, int width, int height, Text text, double value, EntryInfo info) { public MidnightSliderWidget(int x, int y, int width, int height, Text text, double value, EntryInfo info) {
super(x, y, width, height, text, value); super(x, y, width, height, text, value);
@@ -413,12 +462,14 @@ public abstract class MidnightConfig {
boolean isColor() default false; boolean isColor() default false;
boolean isSlider() default false; boolean isSlider() default false;
int precision() default 100; int precision() default 100;
String category() default "default";
} }
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Client {} @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Client {}
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Server {} @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Server {}
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Hidden {} @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Hidden {}
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Comment { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Comment {
boolean centered() default false; boolean centered() default false;
String category() default "default";
} }
public static class HiddenAnnotationExclusionStrategy implements ExclusionStrategy { public static class HiddenAnnotationExclusionStrategy implements ExclusionStrategy {

View File

@@ -1,7 +0,0 @@
package eu.midnightdust.lib.util;
public class MidnightMathUtil {
public static boolean isEven(int i) {
return (i | 1) > i;
}
}

View File

@@ -1,6 +1,7 @@
package eu.midnightdust.lib.util.screen; package eu.midnightdust.lib.util.screen;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.widget.TexturedButtonWidget; import net.minecraft.client.gui.widget.TexturedButtonWidget;
import net.minecraft.client.render.GameRenderer; import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
@@ -26,17 +27,14 @@ public class TexturedOverlayButtonWidget extends TexturedButtonWidget {
} }
@Override @Override
public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) { public void renderButton(DrawContext context, int mouseX, int mouseY, float delta) {
RenderSystem.setShader(GameRenderer::getPositionTexProgram); int i = 66;
RenderSystem.setShaderTexture(0, WIDGETS_TEXTURE); if (!this.isNarratable()) {
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha); i += hoveredVOffset * 2;
int i = this.getYImage(this.isHovered()); } else if (this.isSelected()) {
RenderSystem.enableBlend(); i += hoveredVOffset;
RenderSystem.defaultBlendFunc(); }
RenderSystem.enableDepthTest(); context.drawNineSlicedTexture(WIDGETS_TEXTURE, this.getX(), this.getY(), this.width, this.height, 4, 200, 20, 0, i);
this.drawTexture(matrices, this.getX(), this.getY(), 0, 46 + i * 20, this.width / 2, this.height); super.renderButton(context, mouseX, mouseY, delta);
this.drawTexture(matrices, this.getX() + this.width / 2, this.getY(), 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height);
super.renderButton(matrices, mouseX, mouseY, delta);
} }
} }

View File

@@ -1,11 +1,8 @@
{ {
"midnightlib.overview.title":"MidnightConfig Übersicht", "midnightlib.overview.title":"MidnightConfig Übersicht",
"midnightlib.midnightconfig.title":"MidnightLib Konfiguration", "midnightlib.midnightconfig.title":"MidnightLib Konfiguration",
"midnightlib.midnightconfig.midnightlib_description":"§nMidnightLib",
"midnightlib.midnightconfig.config_screen_list":"Konfigurationsübersicht", "midnightlib.midnightconfig.config_screen_list":"Konfigurationsübersicht",
"midnightlib.midnightconfig.background_texture":"Textur der Konfigurationsbildschirme", "midnightlib.midnightconfig.background_texture":"Textur der Konfigurationsbildschirme",
"midnightlib.midnightconfig.midnighthats_description":"§nMidnightHats",
"midnightlib.midnightconfig.special_hats":"Unterstützer-Hüte",
"modmenu.descriptionTranslation.midnightlib": "Code-Bibliothek für Mods von MidnightDust.\nStellt eine Konfigurationsschnittstelle, automatische Kompatibilität, oft genutzten Code und Hüte für Unterstützer bereit.", "modmenu.descriptionTranslation.midnightlib": "Code-Bibliothek für Mods von MidnightDust.\nStellt eine Konfigurationsschnittstelle, automatische Kompatibilität, oft genutzten Code und Hüte für Unterstützer bereit.",
"modmenu.summaryTranslation.midnightlib": "Code-Bibliothek für Mods von MidnightDust." "modmenu.summaryTranslation.midnightlib": "Code-Bibliothek für Mods von MidnightDust."
} }

View File

@@ -1,14 +1,11 @@
{ {
"midnightlib.overview.title":"MidnightConfig Overview", "midnightlib.overview.title":"MidnightConfig Overview",
"midnightlib.midnightconfig.title":"MidnightLib Config", "midnightlib.midnightconfig.title":"MidnightLib Config",
"midnightlib.midnightconfig.midnightlib_description":"§nMidnightLib",
"midnightlib.midnightconfig.config_screen_list":"Enable Config Screen List", "midnightlib.midnightconfig.config_screen_list":"Enable Config Screen List",
"midnightlib.midnightconfig.enum.ConfigButton.TRUE":"§aYes", "midnightlib.midnightconfig.enum.ConfigButton.TRUE":"§aYes",
"midnightlib.midnightconfig.enum.ConfigButton.FALSE":"§cNo", "midnightlib.midnightconfig.enum.ConfigButton.FALSE":"§cNo",
"midnightlib.midnightconfig.enum.ConfigButton.MODMENU":"§bModMenu", "midnightlib.midnightconfig.enum.ConfigButton.MODMENU":"§bModMenu",
"midnightlib.midnightconfig.background_texture":"Texture of config screen backgrounds", "midnightlib.midnightconfig.background_texture":"Texture of config screen backgrounds",
"midnightlib.midnightconfig.midnighthats_description":"§nMidnightHats",
"midnightlib.midnightconfig.special_hats":"Enable Supporter Hats",
"midnightlib.modrinth":"Modrinth", "midnightlib.modrinth":"Modrinth",
"midnightlib.curseforge":"CurseForge", "midnightlib.curseforge":"CurseForge",
"midnightlib.wiki":"Wiki", "midnightlib.wiki":"Wiki",

View File

@@ -0,0 +1,10 @@
{
"midnightlib.overview.title":"Vue d'ensemble de MidnightConfig",
"midnightlib.midnightconfig.title":"Configuration de MidnightLib",
"midnightlib.midnightconfig.config_screen_list":"Activer la liste de l'écran de configuration",
"midnightlib.midnightconfig.enum.ConfigButton.TRUE":"§aOui",
"midnightlib.midnightconfig.enum.ConfigButton.FALSE":"§cNon",
"midnightlib.midnightconfig.background_texture":"Texture d'arrière-plan de l'écran de configuration",
"modmenu.descriptionTranslation.midnightlib": "Bibliothèque commune pour les mods de la Team MidnightDust.\nFournit une API de configuration, une intégration automatique avec d'autres mods, des utilitaires courants et des cosmétiques.",
"modmenu.summaryTranslation.midnightlib": "Bibliothèque commune pour les mods de la Team MidnightDust."
}

View File

@@ -1,17 +1,10 @@
{ {
"midnightlib.overview.title":"Visão geral do MidnightConfig", "midnightlib.overview.title":"Visão geral do MidnightConfig",
"midnightlib.midnightconfig.title":"Configuração MidnightLib", "midnightlib.midnightconfig.title":"Configuração MidnightLib",
"midnightlib.midnightconfig.midnightlib_description":"§nMidnightLib",
"midnightlib.midnightconfig.config_screen_list":"Ativar lista de telas de configuração", "midnightlib.midnightconfig.config_screen_list":"Ativar lista de telas de configuração",
"midnightlib.midnightconfig.enum.ConfigButton.TRUE":"§aVerdadeiro", "midnightlib.midnightconfig.enum.ConfigButton.TRUE":"§aVerdadeiro",
"midnightlib.midnightconfig.enum.ConfigButton.FALSE":"§cFalso", "midnightlib.midnightconfig.enum.ConfigButton.FALSE":"§cFalso",
"midnightlib.midnightconfig.enum.ConfigButton.MODMENU":"§bModMenu",
"midnightlib.midnightconfig.background_texture":"Textura dos fundos da tela de configuração", "midnightlib.midnightconfig.background_texture":"Textura dos fundos da tela de configuração",
"midnightlib.midnightconfig.midnighthats_description":"§nMidnightHats",
"midnightlib.midnightconfig.special_hats":"Ativar chapéus de torcedor",
"midnightlib.modrinth":"Modrinth",
"midnightlib.curseforge":"CurseForge",
"midnightlib.wiki":"Wiki",
"modmenu.descriptionTranslation.midnightlib": "Biblioteca comum para mods do Team MidnightDust.\nFornece uma API de configuração, integração automática com outros mods, utilitários comuns e cosméticos.", "modmenu.descriptionTranslation.midnightlib": "Biblioteca comum para mods do Team MidnightDust.\nFornece uma API de configuração, integração automática com outros mods, utilitários comuns e cosméticos.",
"modmenu.summaryTranslation.midnightlib": "Biblioteca comum para mods do Team MidnightDust." "modmenu.summaryTranslation.midnightlib": "Biblioteca comum para mods do Team MidnightDust."
} }

View File

@@ -0,0 +1,11 @@
{
"midnightlib.overview.title":"MidnightConfig күзәтү",
"midnightlib.midnightconfig.title":"MidnightLib көйләүләре",
"midnightlib.midnightconfig.config_screen_list":"Көйләүләр экранының исемлеген кушу",
"midnightlib.midnightconfig.enum.ConfigButton.TRUE":"§aӘйе",
"midnightlib.midnightconfig.enum.ConfigButton.FALSE":"§cЮк",
"midnightlib.midnightconfig.background_texture":"Көйләүләр экранының фонының текстурасы",
"midnightlib.wiki":"Вики",
"modmenu.descriptionTranslation.midnightlib": "MidnightDust төркеменең модлары өчен гомуми китапханә.\nКөйләүләр API-ын, башка модлар белән автоматик интеграцияне, гомуми хезмәти программаларны һәм бизәнүләрне тәэмин ителә.",
"modmenu.summaryTranslation.midnightlib": "MidnightDust төркеменең модлары өчен гомуми китапханә."
}

View File

@@ -1,16 +1,8 @@
{ {
"midnightlib.overview.title":"Огляд MidnightConfig", "midnightlib.overview.title":"Огляд MidnightConfig",
"midnightlib.midnightconfig.title":"Конфігурація MidnightLib", "midnightlib.midnightconfig.title":"Конфігурація MidnightLib",
"midnightlib.midnightconfig.midnightlib_description":"§nMidnightLib",
"midnightlib.midnightconfig.config_screen_list":"Увімкнути список екрана конфігурації", "midnightlib.midnightconfig.config_screen_list":"Увімкнути список екрана конфігурації",
"midnightlib.midnightconfig.enum.ConfigButton.TRUE":"§aTrue",
"midnightlib.midnightconfig.enum.ConfigButton.FALSE":"§cFalse",
"midnightlib.midnightconfig.enum.ConfigButton.MODMENU":"§bModMenu",
"midnightlib.midnightconfig.background_texture":"Текстура фону екрана конфігурації", "midnightlib.midnightconfig.background_texture":"Текстура фону екрана конфігурації",
"midnightlib.midnightconfig.midnighthats_description":"§nMidnightHats",
"midnightlib.midnightconfig.special_hats":"Увімкнути капелюхи спонсорів",
"midnightlib.modrinth":"Modrinth",
"midnightlib.curseforge":"CurseForge",
"midnightlib.wiki":"Вікі", "midnightlib.wiki":"Вікі",
"modmenu.descriptionTranslation.midnightlib": "Загальна бібліотека для модів команди MidnightDust.\nНадає конфігураційний API, автоматичну інтеграцію з іншими модами, загальні утиліти та косметику.", "modmenu.descriptionTranslation.midnightlib": "Загальна бібліотека для модів команди MidnightDust.\nНадає конфігураційний API, автоматичну інтеграцію з іншими модами, загальні утиліти та косметику.",
"modmenu.summaryTranslation.midnightlib": "Загальна бібліотека для модів команди MidnightDust." "modmenu.summaryTranslation.midnightlib": "Загальна бібліотека для модів команди MidnightDust."

View File

@@ -0,0 +1,14 @@
{
"midnightlib.overview.title":"MidnightConfig 概述",
"midnightlib.midnightconfig.title":"MidnightLib 設定",
"midnightlib.midnightconfig.config_screen_list":"啟用設定畫面列表",
"midnightlib.midnightconfig.enum.ConfigButton.TRUE":"§a是",
"midnightlib.midnightconfig.enum.ConfigButton.FALSE":"§c否",
"midnightlib.midnightconfig.enum.ConfigButton.MODMENU":"§b模組選單",
"midnightlib.midnightconfig.background_texture":"設定背景畫面的材質",
"midnightlib.modrinth":"Modrinth",
"midnightlib.curseforge":"CurseForge",
"midnightlib.wiki":"維基",
"modmenu.descriptionTranslation.midnightlib": "MidnightDust 團隊的常用程式庫模組。\n提供設定 API、與其他模組自動整合、常用工具和美觀。",
"modmenu.summaryTranslation.midnightlib": "MidnightDust 團隊的常用程式庫模組。"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

View File

@@ -4,8 +4,7 @@
"package": "eu.midnightdust.core.mixin", "package": "eu.midnightdust.core.mixin",
"compatibilityLevel": "JAVA_17", "compatibilityLevel": "JAVA_17",
"client": [ "client": [
"MixinOptionsScreen", "MixinOptionsScreen"
"MixinPlayerEntityRenderer"
], ],
"injectors": { "injectors": {
"defaultRequire": 1 "defaultRequire": 1

View File

@@ -11,8 +11,6 @@ loom {
dependencies { dependencies {
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
// Remove the next line if you don't want to depend on the API
modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}"
modImplementation ("com.terraformersmc:modmenu:${rootProject.mod_menu_version}") modImplementation ("com.terraformersmc:modmenu:${rootProject.mod_menu_version}")
compileClasspath(project(path: ":common", configuration: "namedElements")) { transitive false } compileClasspath(project(path: ":common", configuration: "namedElements")) { transitive false }

View File

@@ -1,16 +1,13 @@
package eu.midnightdust.fabric.core; package eu.midnightdust.fabric.core;
import eu.midnightdust.core.MidnightLibClient; import eu.midnightdust.core.MidnightLibClient;
import eu.midnightdust.hats.witch.WitchHatFeatureRenderer;
import eu.midnightdust.lib.util.MidnightColorUtil; import eu.midnightdust.lib.util.MidnightColorUtil;
import net.fabricmc.api.ClientModInitializer; import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry;
public class MidnightLibClientFabric implements ClientModInitializer { public class MidnightLibClientFabric implements ClientModInitializer {
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
EntityModelLayerRegistry.registerModelLayer(WitchHatFeatureRenderer.WITCH_HAT_MODEL_LAYER, WitchHatFeatureRenderer::getTexturedModelData);
MidnightLibClient.onInitializeClient(); MidnightLibClient.onInitializeClient();
ClientTickEvents.END_CLIENT_TICK.register( ClientTickEvents.END_CLIENT_TICK.register(
client -> MidnightColorUtil.tick() client -> MidnightColorUtil.tick()

View File

@@ -30,6 +30,10 @@
"eu.midnightdust.lib.config.AutoModMenu" "eu.midnightdust.lib.config.AutoModMenu"
] ]
}, },
"depends": {
"fabric-resource-loader-v0": "*",
"minecraft": ">=1.20-beta.2"
},
"mixins": [ "mixins": [
"midnightlib.mixins.json" "midnightlib.mixins.json"

View File

@@ -1,37 +1,30 @@
package eu.midnightdust.forge; package eu.midnightdust.forge;
import eu.midnightdust.hats.witch.WitchHatFeatureRenderer;
import eu.midnightdust.lib.config.MidnightConfig; import eu.midnightdust.lib.config.MidnightConfig;
import eu.midnightdust.lib.util.MidnightColorUtil; import eu.midnightdust.lib.util.MidnightColorUtil;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.ConfigScreenHandler; import net.minecraftforge.client.ConfigScreenHandler;
import net.minecraftforge.client.event.EntityRenderersEvent; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
@Mod.EventBusSubscriber(modid = "midnightlib", bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) @Mod.EventBusSubscriber(modid = "midnightlib", bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
public class MidnightLibClientEvents { public class MidnightLibClientEvents {
@SubscribeEvent public static void registerClientTick(TickEvent.ClientTickEvent event) {
public static void registerLayerDefinition(EntityRenderersEvent.RegisterLayerDefinitions event) {
event.registerLayerDefinition(WitchHatFeatureRenderer.WITCH_HAT_MODEL_LAYER, WitchHatFeatureRenderer::getTexturedModelData);
}
@SubscribeEvent
public void registerClientTick(TickEvent.ClientTickEvent event) {
MidnightColorUtil.tick(); MidnightColorUtil.tick();
} }
@SubscribeEvent
public void onPostInit(FMLLoadCompleteEvent event) {
ModList.get().applyForEachModContainer(modContainer -> {
System.out.println(modContainer.getModId() + " yes");
if (MidnightConfig.configClass.containsKey(modContainer.getModId())) {
@SubscribeEvent
public static void onPostInit(FMLClientSetupEvent event) {
MinecraftForge.EVENT_BUS.addListener(MidnightLibClientEvents::registerClientTick);
ModList.get().forEachModContainer((modid, modContainer) -> {
if (MidnightConfig.configClass.containsKey(modid)) {
modContainer.registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, () -> modContainer.registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, () ->
new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> MidnightConfig.getScreen(parent, modContainer.getModId()))); new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> MidnightConfig.getScreen(parent, modid)));
} }
return true;
}); });
} }
} }

View File

@@ -3,7 +3,6 @@ package eu.midnightdust.forge;
import eu.midnightdust.core.MidnightLibClient; import eu.midnightdust.core.MidnightLibClient;
import eu.midnightdust.core.MidnightLibServer; import eu.midnightdust.core.MidnightLibServer;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.IExtensionPoint; import net.minecraftforge.fml.IExtensionPoint;
import net.minecraftforge.fml.ModLoadingContext; import net.minecraftforge.fml.ModLoadingContext;
@@ -16,9 +15,5 @@ public class MidnightLibForge {
ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(() -> NetworkConstants.IGNORESERVERONLY, (remote, server) -> true)); ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(() -> NetworkConstants.IGNORESERVERONLY, (remote, server) -> true));
DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> MidnightLibClient::onInitializeClient); DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> MidnightLibClient::onInitializeClient);
DistExecutor.safeRunWhenOn(Dist.DEDICATED_SERVER, () -> MidnightLibServer::onInitializeServer); DistExecutor.safeRunWhenOn(Dist.DEDICATED_SERVER, () -> MidnightLibServer::onInitializeServer);
//ModLoadingContext.get().registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, () ->
// new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> MidnightConfig.getScreen(parent, "midnightlib")));
MinecraftForge.EVENT_BUS.register(new MidnightLibClientEvents());
MinecraftForge.EVENT_BUS.register(new MidnightLibServerEvents());
} }
} }

View File

@@ -8,10 +8,10 @@ import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber(modid = "midnightlib", bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.DEDICATED_SERVER) @Mod.EventBusSubscriber(modid = "midnightlib", value = Dist.DEDICATED_SERVER)
public class MidnightLibServerEvents { public class MidnightLibServerEvents {
@SubscribeEvent @SubscribeEvent
public void registerCommands(RegisterCommandsEvent event) { public static void registerCommands(RegisterCommandsEvent event) {
for (LiteralArgumentBuilder<ServerCommandSource> command : AutoCommand.commands){ for (LiteralArgumentBuilder<ServerCommandSource> command : AutoCommand.commands){
event.getDispatcher().register(command); event.getDispatcher().register(command);
} }

View File

@@ -23,6 +23,6 @@ public class PlatformFunctionsImpl {
return ModList.get().isLoaded(modid); return ModList.get().isLoaded(modid);
} }
public static void registerCommand(LiteralArgumentBuilder<ServerCommandSource> command) { public static void registerCommand(LiteralArgumentBuilder<ServerCommandSource> command) {
// Ignored here, see MidnightLibEvents#registerCommands // Ignored here, see MidnightLibServerEvents#registerCommands
} }
} }

View File

@@ -24,6 +24,6 @@ side = "BOTH"
[[dependencies.midnightlib]] [[dependencies.midnightlib]]
modId = "minecraft" modId = "minecraft"
mandatory = true mandatory = true
versionRange = "[1.19.2,)" versionRange = "[1.19.4,)"
ordering = "NONE" ordering = "NONE"
side = "BOTH" side = "BOTH"

View File

@@ -1,19 +1,18 @@
org.gradle.jvmargs=-Xmx4096M org.gradle.jvmargs=-Xmx4096M
minecraft_version=1.19.3-rc1 minecraft_version=1.20
enabled_platforms=fabric yarn_mappings=1.20+build.1
enabled_platforms=quilt,fabric,forge
archives_base_name=midnightlib archives_base_name=midnightlib
mod_version=1.1.0 mod_version=1.4.1
maven_group=eu.midnightdust maven_group=eu.midnightdust
architectury_version=6.2.43 fabric_loader_version=0.14.21
fabric_api_version=0.83.0+1.20
fabric_loader_version=0.14.11 forge_version=1.20-46.0.2
fabric_api_version=0.68.1+1.19.3
forge_version=1.19.2-43.0.8 quilt_loader_version=0.19.0-beta.18
quilt_fabric_api_version=7.0.1+0.83.0-1.20
quilt_loader_version=0.18.1-beta.9 mod_menu_version = 7.0.1
quilt_fabric_api_version=4.0.0-beta.7+0.59.0-1.19.2
mod_menu_version = 5.0.0-alpha.4

View File

@@ -5,7 +5,7 @@ import eu.midnightdust.lib.util.PlatformFunctions;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import org.quiltmc.loader.api.QuiltLoader; import org.quiltmc.loader.api.QuiltLoader;
import org.quiltmc.loader.impl.QuiltLoaderImpl; import org.quiltmc.loader.api.minecraft.MinecraftQuiltLoader;
import org.quiltmc.qsl.command.api.CommandRegistrationCallback; import org.quiltmc.qsl.command.api.CommandRegistrationCallback;
import java.nio.file.Path; import java.nio.file.Path;
@@ -18,7 +18,7 @@ public class PlatformFunctionsImpl {
return QuiltLoader.getConfigDir(); return QuiltLoader.getConfigDir();
} }
public static boolean isClientEnv() { public static boolean isClientEnv() {
return QuiltLoaderImpl.INSTANCE.getEnvironmentType() == EnvType.CLIENT; return MinecraftQuiltLoader.getEnvironmentType() == EnvType.CLIENT;
} }
public static boolean isModLoaded(String modid) { public static boolean isModLoaded(String modid) {
return QuiltLoader.isModLoaded(modid); return QuiltLoader.isModLoaded(modid);

View File

@@ -1,9 +1,7 @@
package eu.midnightdust.quilt.core; package eu.midnightdust.quilt.core;
import eu.midnightdust.core.MidnightLibClient; import eu.midnightdust.core.MidnightLibClient;
import eu.midnightdust.hats.witch.WitchHatFeatureRenderer;
import eu.midnightdust.lib.util.MidnightColorUtil; import eu.midnightdust.lib.util.MidnightColorUtil;
import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry;
import org.quiltmc.loader.api.ModContainer; import org.quiltmc.loader.api.ModContainer;
import org.quiltmc.qsl.base.api.entrypoint.client.ClientModInitializer; import org.quiltmc.qsl.base.api.entrypoint.client.ClientModInitializer;
import org.quiltmc.qsl.lifecycle.api.client.event.ClientTickEvents; import org.quiltmc.qsl.lifecycle.api.client.event.ClientTickEvents;
@@ -11,7 +9,6 @@ import org.quiltmc.qsl.lifecycle.api.client.event.ClientTickEvents;
public class MidnightLibClientQuilt implements ClientModInitializer { public class MidnightLibClientQuilt implements ClientModInitializer {
@Override @Override
public void onInitializeClient(ModContainer mod) { public void onInitializeClient(ModContainer mod) {
EntityModelLayerRegistry.registerModelLayer(WitchHatFeatureRenderer.WITCH_HAT_MODEL_LAYER, WitchHatFeatureRenderer::getTexturedModelData);
MidnightLibClient.onInitializeClient(); MidnightLibClient.onInitializeClient();
ClientTickEvents.END.register( ClientTickEvents.END.register(
client -> MidnightColorUtil.tick() client -> MidnightColorUtil.tick()

View File

@@ -4,21 +4,7 @@
"group": "${group}", "group": "${group}",
"id": "midnightlib", "id": "midnightlib",
"version": "${version}", "version": "${version}",
"name": "MidnightLib",
"description": "Common Library for Team MidnightDust's mods.",
"authors": [
"TeamMidnightDust",
"Motschen"
],
"contact": {
"homepage": "https://www.midnightdust.eu/",
"sources": "https://github.com/TeamMidnightDust/MidnightLib",
"issues": "https://github.com/TeamMidnightDust/MidnightLib/issues"
},
"license": "MIT",
"icon": "assets/midnightlib/icon.png",
"intermediate_mappings": "net.fabricmc:intermediary", "intermediate_mappings": "net.fabricmc:intermediary",
"environment": "*",
"entrypoints": { "entrypoints": {
"client_init": [ "client_init": [
"eu.midnightdust.quilt.core.MidnightLibClientQuilt" "eu.midnightdust.quilt.core.MidnightLibClientQuilt"
@@ -38,11 +24,17 @@
{ {
"id": "quilt_base", "id": "quilt_base",
"version": "*" "version": "*"
},
{
"id": "minecraft",
"version": ">=1.19.4"
} }
], ],
"metadata": { "metadata": {
"name": "MidnightLib (Quilt)", "name": "MidnightLib (Quilt)",
"description": "Common Library for Team MidnightDust's mods.\nProvides a config api, automatic integration with other mods, common utils, and cosmetics.", "description": "Common Library for Team MidnightDust's mods. Provides a config api, automatic integration with other mods, common utils, and cosmetics.",
"license": "MIT",
"environment": "*",
"contributors": { "contributors": {
"Motschen": "Author", "Motschen": "Author",
"TeamMidnightDust": "Mascot" "TeamMidnightDust": "Mascot"

View File

@@ -10,7 +10,7 @@ pluginManagement {
include("common") include("common")
include("fabric-like") include("fabric-like")
include("fabric") include("fabric")
//include("quilt") include("quilt")
//include("forge") include("forge")
rootProject.name = "midnightlib" rootProject.name = "midnightlib"