Compare commits

..

3 Commits

Author SHA1 Message Date
Motschen
c805d03630 MidnightLib 0.4.4 - Some more fixes 2022-06-07 21:11:13 +02:00
Motschen
23ab3ea9f8 MidnightLib 0.4.3 - Fix AutoModMenu opt-out
Also opt-out Puzzle by default
2022-06-06 18:38:10 +02:00
Motschen
5ef681693e MidnightLib 0.4.2 - Add opt-out from AutoModMenu 2022-06-06 17:57:05 +02:00
59 changed files with 382 additions and 1073 deletions

38
.gitignore vendored Normal file → Executable file
View File

@@ -1,19 +1,25 @@
build/ # gradle
*.ipr
run/
*.iws
out/
*.iml
.gradle/
output/
bin/
libs/
.gradle/
out/
classes/
build/
# idea
.idea/
*.iml
*.ipr
*.iws
# vscode
.settings/
.vscode/
bin/
.classpath .classpath
.project .project
.idea/
classes/ # fabric
.metadata
.vscode run/
.settings
*.launch

114
build.gradle Normal file → Executable file
View File

@@ -1,47 +1,85 @@
plugins { plugins {
id "architectury-plugin" version "3.4-SNAPSHOT" id 'fabric-loom' version '0.8-SNAPSHOT'
id "dev.architectury.loom" version "1.0-SNAPSHOT" apply false id 'maven-publish'
} }
architectury { sourceCompatibility = JavaVersion.VERSION_16
minecraft = rootProject.minecraft_version targetCompatibility = JavaVersion.VERSION_16
archivesBaseName = project.archives_base_name
version = project.mod_version
group = project.maven_group
minecraft {
} }
subprojects { repositories {
apply plugin: "dev.architectury.loom" maven { url "https://maven.terraformersmc.com/releases" }
maven { url "https://jitpack.io" }
dependencies {
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
// The following line declares the mojmap mappings, you may use other mappings as well
//mappings loom.officialMojangMappings()
// 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"
}
} }
allprojects { dependencies {
apply plugin: "java" //to change the versions see the gradle.properties file
apply plugin: "architectury-plugin" minecraft "com.mojang:minecraft:${project.minecraft_version}"
apply plugin: "maven-publish" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
archivesBaseName = rootProject.archives_base_name modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
version = rootProject.mod_version
group = rootProject.maven_group modImplementation ("com.terraformersmc:modmenu:${project.mod_menu_version}")
}
repositories {
// Add repositories to retrieve artifacts from in here. processResources {
// You should only use this when depending on other mods because inputs.property "version", project.version
// Loom adds the essential maven repositories to download Minecraft and libraries from automatically.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html filesMatching("fabric.mod.json") {
// for more information about repositories. expand "version": project.version
} }
}
tasks.withType(JavaCompile) {
options.encoding = "UTF-8" tasks.withType(JavaCompile).configureEach {
options.release = 17 // ensure that the encoding is set to UTF-8, no matter what the system default is
} // this fixes some edge cases with special characters not displaying correctly
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
java { // If Javadoc is generated, this must be specified in that task too.
withSourcesJar() it.options.encoding = "UTF-8"
}
// Minecraft 1.17 (21w19a) upwards uses Java 16.
it.options.release = 16
}
java {
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
// if it is present.
// If you remove this line, sources will not be generated.
withSourcesJar()
}
jar {
from("LICENSE") {
rename { "${it}_${project.archivesBaseName}"}
}
}
// configure the maven publication
publishing {
publications {
mavenJava(MavenPublication) {
// add all the jars that should be included when publishing to maven
artifact(remapJar) {
builtBy remapJar
}
artifact(sourcesJar) {
builtBy remapSourcesJar
}
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
// Notice: This block does NOT have the same function as the block in the top level.
// The repositories here will be used for publishing your artifact, not for
// retrieving dependencies.
}
} }

View File

@@ -1,26 +0,0 @@
architectury {
common(rootProject.enabled_platforms.split(","))
}
loom {
}
dependencies {
// We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies
// Do NOT use other classes from fabric loader
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
}
publishing {
publications {
mavenCommon(MavenPublication) {
artifactId = rootProject.archives_base_name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}

View File

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

View File

@@ -1,30 +0,0 @@
package eu.midnightdust.lib.util;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import dev.architectury.injectables.annotations.ExpectPlatform;
import net.minecraft.server.command.ServerCommandSource;
import java.nio.file.Path;
public class PlatformFunctions {
@ExpectPlatform
public static Path getConfigDirectory() {
// Just throw an error, the content should get replaced at runtime.
throw new AssertionError();
}
@ExpectPlatform
public static boolean isClientEnv() {
// Just throw an error, the content should get replaced at runtime.
throw new AssertionError();
}
@ExpectPlatform
public static boolean isModLoaded(String modid) {
// Just throw an error, the content should get replaced at runtime.
throw new AssertionError();
}
@ExpectPlatform
public static void registerCommand(LiteralArgumentBuilder<ServerCommandSource> command) {
// Just throw an error, the content should get replaced at runtime.
throw new AssertionError();
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -1,17 +0,0 @@
{
"midnightlib.overview.title":"Visão geral do MidnightConfig",
"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.enum.ConfigButton.TRUE":"§aVerdadeiro",
"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.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.summaryTranslation.midnightlib": "Biblioteca comum para mods do Team MidnightDust."
}

View File

@@ -1,17 +0,0 @@
{
"midnightlib.overview.title":"Огляд MidnightConfig",
"midnightlib.midnightconfig.title":"Конфігурація MidnightLib",
"midnightlib.midnightconfig.midnightlib_description":"§nMidnightLib",
"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.midnighthats_description":"§nMidnightHats",
"midnightlib.midnightconfig.special_hats":"Увімкнути капелюхи спонсорів",
"midnightlib.modrinth":"Modrinth",
"midnightlib.curseforge":"CurseForge",
"midnightlib.wiki":"Вікі",
"modmenu.descriptionTranslation.midnightlib": "Загальна бібліотека для модів команди MidnightDust.\nНадає конфігураційний API, автоматичну інтеграцію з іншими модами, загальні утиліти та косметику.",
"modmenu.summaryTranslation.midnightlib": "Загальна бібліотека для модів команди MidnightDust."
}

View File

@@ -1,19 +0,0 @@
architectury {
common(rootProject.enabled_platforms.split(","))
}
repositories {
maven { url "https://maven.terraformersmc.com/releases" }
}
loom {
}
dependencies {
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_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}")
compileClasspath(project(path: ":common", configuration: "namedElements")) { transitive false }
}

View File

@@ -1,81 +0,0 @@
plugins {
id "com.github.johnrengelman.shadow" version "7.1.2"
}
architectury {
platformSetupLoomIde()
fabric()
}
loom {
}
configurations {
common
shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this.
compileClasspath.extendsFrom common
runtimeClasspath.extendsFrom common
developmentFabric.extendsFrom common
archivesBaseName = rootProject.archives_base_name + "-fabric"
}
dependencies {
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false }
common(project(path: ":fabric-like", configuration: "namedElements")) { transitive false }
shadowCommon(project(path: ":fabric-like", configuration: "transformProductionFabric")) { transitive false }
}
processResources {
inputs.property "version", project.version
filesMatching("fabric.mod.json") {
expand "version": project.version
}
}
shadowJar {
exclude "architectury.common.json"
configurations = [project.configurations.shadowCommon]
classifier "dev-shadow"
}
remapJar {
input.set shadowJar.archiveFile
dependsOn shadowJar
classifier null
}
jar {
classifier "dev"
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
from commonSources.archiveFile.map { zipTree(it) }
}
components.java {
withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
skip()
}
}
publishing {
publications {
mavenFabric(MavenPublication) {
artifactId = rootProject.archives_base_name + "-" + project.name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}

View File

@@ -1,11 +0,0 @@
package eu.midnightdust.fabric.core;
import eu.midnightdust.core.MidnightLibServer;
import net.fabricmc.api.DedicatedServerModInitializer;
public class MidnightLibServerFabric implements DedicatedServerModInitializer {
@Override
public void onInitializeServer() {
MidnightLibServer.onInitializeServer();
}
}

View File

@@ -1,28 +0,0 @@
package eu.midnightdust.lib.util.fabric;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.fabricmc.api.EnvType;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.server.command.ServerCommandSource;
import java.nio.file.Path;
public class PlatformFunctionsImpl {
/**
* This is our actual method to {@link PlatformFunctions#getConfigDirectory()}.
*/
public static Path getConfigDirectory() {
return FabricLoader.getInstance().getConfigDir();
}
public static boolean isClientEnv() {
return FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT;
}
public static boolean isModLoaded(String modid) {
return FabricLoader.getInstance().isModLoaded(modid);
}
public static void registerCommand(LiteralArgumentBuilder<ServerCommandSource> command) {
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated, registrationEnvironment) -> dispatcher.register(command));
}
}

View File

@@ -1,82 +0,0 @@
plugins {
id "com.github.johnrengelman.shadow" version "7.1.2"
}
architectury {
platformSetupLoomIde()
forge()
}
loom {
forge {
mixinConfig "midnightlib.mixins.json"
}
}
configurations {
common
shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this.
compileClasspath.extendsFrom common
runtimeClasspath.extendsFrom common
developmentForge.extendsFrom common
archivesBaseName = rootProject.archives_base_name + "-forge"
}
dependencies {
forge "net.minecraftforge:forge:${rootProject.forge_version}"
common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false }
}
processResources {
inputs.property "version", project.version
filesMatching("META-INF/mods.toml") {
expand "version": project.version
}
}
shadowJar {
exclude "fabric.mod.json"
exclude "architectury.common.json"
configurations = [project.configurations.shadowCommon]
classifier "dev-shadow"
}
remapJar {
input.set shadowJar.archiveFile
dependsOn shadowJar
classifier null
}
jar {
classifier "dev"
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
from commonSources.archiveFile.map { zipTree(it) }
}
components.java {
withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
skip()
}
}
publishing {
publications {
mavenForge(MavenPublication) {
artifactId = rootProject.archives_base_name + "-" + project.name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}

View File

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

View File

@@ -1,37 +0,0 @@
package eu.midnightdust.forge;
import eu.midnightdust.hats.witch.WitchHatFeatureRenderer;
import eu.midnightdust.lib.config.MidnightConfig;
import eu.midnightdust.lib.util.MidnightColorUtil;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.ConfigScreenHandler;
import net.minecraftforge.client.event.EntityRenderersEvent;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent;
@Mod.EventBusSubscriber(modid = "midnightlib", bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
public class MidnightLibClientEvents {
@SubscribeEvent
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();
}
@SubscribeEvent
public void onPostInit(FMLLoadCompleteEvent event) {
ModList.get().applyForEachModContainer(modContainer -> {
System.out.println(modContainer.getModId() + " yes");
if (MidnightConfig.configClass.containsKey(modContainer.getModId())) {
modContainer.registerExtensionPoint(ConfigScreenHandler.ConfigScreenFactory.class, () ->
new ConfigScreenHandler.ConfigScreenFactory((client, parent) -> MidnightConfig.getScreen(parent, modContainer.getModId())));
}
return true;
});
}
}

View File

@@ -1,24 +0,0 @@
package eu.midnightdust.forge;
import eu.midnightdust.core.MidnightLibClient;
import eu.midnightdust.core.MidnightLibServer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.IExtensionPoint;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.network.NetworkConstants;
@Mod("midnightlib")
public class MidnightLibForge {
public MidnightLibForge() {
ModLoadingContext.get().registerExtensionPoint(IExtensionPoint.DisplayTest.class, () -> new IExtensionPoint.DisplayTest(() -> NetworkConstants.IGNORESERVERONLY, (remote, server) -> true));
DistExecutor.safeRunWhenOn(Dist.CLIENT, () -> MidnightLibClient::onInitializeClient);
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

@@ -1,19 +0,0 @@
package eu.midnightdust.forge;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import eu.midnightdust.lib.config.AutoCommand;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.event.RegisterCommandsEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber(modid = "midnightlib", bus = Mod.EventBusSubscriber.Bus.MOD, value = Dist.DEDICATED_SERVER)
public class MidnightLibServerEvents {
@SubscribeEvent
public void registerCommands(RegisterCommandsEvent event) {
for (LiteralArgumentBuilder<ServerCommandSource> command : AutoCommand.commands){
event.getDispatcher().register(command);
}
}
}

View File

@@ -1,28 +0,0 @@
package eu.midnightdust.lib.util.forge;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.fml.loading.FMLPaths;
import java.nio.file.Path;
public class PlatformFunctionsImpl {
/**
* 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) {
// Ignored here, see MidnightLibEvents#registerCommands
}
}

View File

@@ -1,29 +0,0 @@
modLoader = "javafml"
loaderVersion = "[43,)"
#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.
'''
#logoFile = ""
[[dependencies.midnightlib]]
modId = "forge"
mandatory = true
versionRange = "[43,)"
ordering = "NONE"
side = "BOTH"
[[dependencies.midnightlib]]
modId = "minecraft"
mandatory = true
versionRange = "[1.19.2,)"
ordering = "NONE"
side = "BOTH"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -1,6 +0,0 @@
{
"pack": {
"description": "MidnightLib",
"pack_format": 9
}
}

31
gradle.properties Normal file → Executable file
View File

@@ -1,19 +1,18 @@
org.gradle.jvmargs=-Xmx4096M # Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx1G
minecraft_version=1.19.3-rc1 # Fabric Properties
enabled_platforms=fabric # check these on https://fabricmc.net/use
minecraft_version=1.17.1
yarn_mappings=1.17.1+build.63
loader_version=0.11.7
archives_base_name=midnightlib # Mod Properties
mod_version=1.1.0 mod_version = 0.4.4
maven_group=eu.midnightdust maven_group = eu.midnightdust
archives_base_name = midnightlib
architectury_version=6.2.43 # Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_loader_version=0.14.11 fabric_version=0.41.0+1.17
fabric_api_version=0.68.1+1.19.3 mod_menu_version = 2.0.2
forge_version=1.19.2-43.0.8
quilt_loader_version=0.18.1-beta.9
quilt_fabric_api_version=4.0.0-beta.7+0.59.0-1.19.2
mod_menu_version = 5.0.0-alpha.4

Binary file not shown.

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-7.5.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

6
gradlew vendored
View File

@@ -205,12 +205,6 @@ set -- \
org.gradle.wrapper.GradleWrapperMain \ org.gradle.wrapper.GradleWrapperMain \
"$@" "$@"
# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
die "xargs is not available"
fi
# Use "xargs" to parse quoted args. # Use "xargs" to parse quoted args.
# #
# With -n1 it outputs one arg per line, with the quotes and backslashes removed. # With -n1 it outputs one arg per line, with the quotes and backslashes removed.

180
gradlew.bat vendored
View File

@@ -1,91 +1,89 @@
@rem @rem
@rem Copyright 2015 the original author or authors. @rem Copyright 2015 the original author or authors.
@rem @rem
@rem Licensed under the Apache License, Version 2.0 (the "License"); @rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License. @rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at @rem You may obtain a copy of the License at
@rem @rem
@rem https://www.apache.org/licenses/LICENSE-2.0 @rem https://www.apache.org/licenses/LICENSE-2.0
@rem @rem
@rem Unless required by applicable law or agreed to in writing, software @rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS, @rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and @rem See the License for the specific language governing permissions and
@rem limitations under the License. @rem limitations under the License.
@rem @rem
@if "%DEBUG%"=="" @echo off @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@rem Gradle startup script for Windows @rem Gradle startup script for Windows
@rem @rem
@rem ########################################################################## @rem ##########################################################################
@rem Set local scope for the variables with windows NT shell @rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0 set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=. if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter. @rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute if "%ERRORLEVEL%" == "0" goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo. echo.
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. echo location of your Java installation.
goto fail goto fail
:findJavaFromJavaHome :findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo. echo.
echo Please set the JAVA_HOME variable in your environment to match the echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation. echo location of your Java installation.
goto fail goto fail
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd if "%ERRORLEVEL%"=="0" goto mainEnd
:fail :fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code! rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL% if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
if %EXIT_CODE% equ 0 set EXIT_CODE=1 exit /b 1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE% :mainEnd
if "%OS%"=="Windows_NT" endlocal
:mainEnd
if "%OS%"=="Windows_NT" endlocal :omega
:omega

0
logs/latest.log Executable file
View File

View File

@@ -1,88 +0,0 @@
plugins {
id "com.github.johnrengelman.shadow" version "7.1.2"
}
repositories {
maven { url "https://maven.quiltmc.org/repository/release/" }
}
architectury {
platformSetupLoomIde()
loader("quilt")
}
loom {
}
configurations {
common
shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this.
compileClasspath.extendsFrom common
runtimeClasspath.extendsFrom common
developmentQuilt.extendsFrom common
archivesBaseName = rootProject.archives_base_name + "-quilt"
}
dependencies {
modImplementation "org.quiltmc:quilt-loader:${rootProject.quilt_loader_version}"
modApi "org.quiltmc.quilted-fabric-api:quilted-fabric-api:${rootProject.quilt_fabric_api_version}"
// Remove the next few lines if you don't want to depend on the API
common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowCommon(project(path: ":common", configuration: "transformProductionQuilt")) { transitive false }
common(project(path: ":fabric-like", configuration: "namedElements")) { transitive false }
shadowCommon(project(path: ":fabric-like", configuration: "transformProductionQuilt")) { transitive false }
}
processResources {
inputs.property "group", rootProject.maven_group
inputs.property "version", project.version
filesMatching("quilt.mod.json") {
expand "group": rootProject.maven_group,
"version": project.version
}
}
shadowJar {
exclude "architectury.common.json"
configurations = [project.configurations.shadowCommon]
classifier "dev-shadow"
}
remapJar {
input.set shadowJar.archiveFile
dependsOn shadowJar
classifier null
}
jar {
classifier "dev"
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
from commonSources.archiveFile.map { zipTree(it) }
}
components.java {
withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
skip()
}
}
publishing {
publications {
mavenQuilt(MavenPublication) {
artifactId = rootProject.archives_base_name + "-" + project.name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}

View File

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

View File

@@ -1,29 +0,0 @@
package eu.midnightdust.lib.util.fabric;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.fabricmc.api.EnvType;
import net.minecraft.server.command.ServerCommandSource;
import org.quiltmc.loader.api.QuiltLoader;
import org.quiltmc.loader.impl.QuiltLoaderImpl;
import org.quiltmc.qsl.command.api.CommandRegistrationCallback;
import java.nio.file.Path;
public class PlatformFunctionsImpl {
/**
* This is our actual method to {@link PlatformFunctions#getConfigDirectory()}.
*/
public static Path getConfigDirectory() {
return QuiltLoader.getConfigDir();
}
public static boolean isClientEnv() {
return QuiltLoaderImpl.INSTANCE.getEnvironmentType() == EnvType.CLIENT;
}
public static boolean isModLoaded(String modid) {
return QuiltLoader.isModLoaded(modid);
}
public static void registerCommand(LiteralArgumentBuilder<ServerCommandSource> command) {
CommandRegistrationCallback.EVENT.register((dispatcher, dedicated, registrationEnvironment) -> dispatcher.register(command));
}
}

View File

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

View File

@@ -1,12 +0,0 @@
package eu.midnightdust.quilt.core;
import eu.midnightdust.core.MidnightLibServer;
import org.quiltmc.loader.api.ModContainer;
import org.quiltmc.qsl.base.api.entrypoint.server.DedicatedServerModInitializer;
public class MidnightLibServerQuilt implements DedicatedServerModInitializer {
@Override
public void onInitializeServer(ModContainer mod) {
MidnightLibServer.onInitializeServer();
}
}

View File

@@ -1,72 +0,0 @@
{
"schema_version": 1,
"quilt_loader": {
"group": "${group}",
"id": "midnightlib",
"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",
"environment": "*",
"entrypoints": {
"client_init": [
"eu.midnightdust.quilt.core.MidnightLibClientQuilt"
],
"server_init": [
"eu.midnightdust.quilt.core.MidnightLibServerQuilt"
],
"modmenu": [
"eu.midnightdust.lib.config.AutoModMenu"
]
},
"depends": [
{
"id": "quilt_loader",
"version": "*"
},
{
"id": "quilt_base",
"version": "*"
}
],
"metadata": {
"name": "MidnightLib (Quilt)",
"description": "Common Library for Team MidnightDust's mods.\nProvides a config api, automatic integration with other mods, common utils, and cosmetics.",
"contributors": {
"Motschen": "Author",
"TeamMidnightDust": "Mascot"
},
"contact": {
"email": "mail@midnightdust.eu",
"homepage": "https://modrinth.com/mod/midnightlib",
"issues": "https://github.com/TeamMidnightDust/MidnightLib/issues",
"sources": "https://github.com/TeamMidnightDust/MidnightLib"
},
"icon": "assets/midnightlib/icon.png"
}
},
"mixin": [
"midnightlib.mixins.json"
],
"modmenu": {
"links": {
"modmenu.discord": "https://discord.midnightdust.eu/",
"modmenu.website": "https://www.midnightdust.eu/",
"midnightlib.curseforge": "https://www.curseforge.com/minecraft/mc-mods/midnightlib",
"midnightlib.modrinth": "https://modrinth.com/mod/midnightlib",
"midnightlib.wiki": "https://github.com/TeamMidnightDust/MidnightLib/wiki"
},
"badges": [ "library" ]
}
}

16
settings.gradle Normal file → Executable file
View File

@@ -1,16 +1,10 @@
pluginManagement { pluginManagement {
repositories { repositories {
maven { url "https://maven.fabricmc.net/" } jcenter()
maven { url "https://maven.architectury.dev/" } maven {
maven { url "https://maven.minecraftforge.net/" } name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
gradlePluginPortal() gradlePluginPortal()
} }
} }
include("common")
include("fabric-like")
include("fabric")
//include("quilt")
//include("forge")
rootProject.name = "midnightlib"

View File

@@ -1,17 +1,29 @@
package eu.midnightdust.fabric.core; package eu.midnightdust.core;
import eu.midnightdust.core.MidnightLibClient; import eu.midnightdust.core.config.MidnightLibConfig;
import eu.midnightdust.hats.web.HatLoader;
import eu.midnightdust.hats.witch.WitchHatFeatureRenderer; import eu.midnightdust.hats.witch.WitchHatFeatureRenderer;
import eu.midnightdust.lib.config.MidnightConfig;
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; import net.fabricmc.fabric.api.client.rendering.v1.EntityModelLayerRegistry;
public class MidnightLibClientFabric implements ClientModInitializer { import java.util.ArrayList;
import java.util.List;
public class MidnightLibClient implements ClientModInitializer {
public static List<String> hiddenMods = new ArrayList<>();
public static final String MOD_ID = "midnightlib";
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
MidnightConfig.init("midnightlib", MidnightLibConfig.class);
if (hiddenMods.contains("puzzle")) hiddenMods.add("puzzle");
EntityModelLayerRegistry.registerModelLayer(WitchHatFeatureRenderer.WITCH_HAT_MODEL_LAYER, WitchHatFeatureRenderer::getTexturedModelData); EntityModelLayerRegistry.registerModelLayer(WitchHatFeatureRenderer.WITCH_HAT_MODEL_LAYER, WitchHatFeatureRenderer::getTexturedModelData);
MidnightLibClient.onInitializeClient(); if (MidnightLibConfig.special_hats) HatLoader.init();
ClientTickEvents.END_CLIENT_TICK.register( ClientTickEvents.END_CLIENT_TICK.register(
client -> MidnightColorUtil.tick() client -> MidnightColorUtil.tick()
); );

View File

@@ -2,15 +2,17 @@ package eu.midnightdust.core;
import eu.midnightdust.lib.config.AutoCommand; import eu.midnightdust.lib.config.AutoCommand;
import eu.midnightdust.lib.config.MidnightConfig; import eu.midnightdust.lib.config.MidnightConfig;
import net.fabricmc.api.DedicatedServerModInitializer;
import java.lang.reflect.Field; import java.lang.reflect.Field;
public class MidnightLibServer { public class MidnightLibServer implements DedicatedServerModInitializer {
public static void onInitializeServer() { @Override
public void onInitializeServer() {
MidnightConfig.configClass.forEach((modid, config) -> { MidnightConfig.configClass.forEach((modid, config) -> {
for (Field field : config.getFields()) { for (Field field : config.getFields()) {
if (field.isAnnotationPresent(MidnightConfig.Entry.class) && !field.isAnnotationPresent(MidnightConfig.Client.class) && !field.isAnnotationPresent(MidnightConfig.Hidden.class)) if (field.isAnnotationPresent(MidnightConfig.Entry.class) && !field.isAnnotationPresent(MidnightConfig.Client.class))
new AutoCommand(field, modid).register(); new AutoCommand(field, modid).register();
} }
}); });

View File

@@ -1,13 +1,13 @@
package eu.midnightdust.core.config; package eu.midnightdust.core.config;
import eu.midnightdust.lib.config.MidnightConfig; import eu.midnightdust.lib.config.MidnightConfig;
import eu.midnightdust.lib.util.PlatformFunctions; import net.fabricmc.loader.api.FabricLoader;
public class MidnightLibConfig extends MidnightConfig { public class MidnightLibConfig extends MidnightConfig {
@Comment(centered = true) public static Comment midnightlib_description; @Comment 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 = FabricLoader.getInstance().isModLoaded("modmenu") ? ConfigButton.MODMENU : ConfigButton.TRUE;
@Comment(centered = true) public static Comment midnighthats_description; @Comment public static Comment midnighthats_description;
@Entry // Enable or disable hats for contributors, friends and donors. @Entry // Enable or disable hats for contributors, friends and donors.
public static boolean special_hats = true; public static boolean special_hats = true;

View File

@@ -2,11 +2,12 @@ package eu.midnightdust.core.mixin;
import eu.midnightdust.core.config.MidnightLibConfig; 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 eu.midnightdust.lib.util.screen.TexturedOverlayButtonWidget;
import net.fabricmc.loader.api.FabricLoader;
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.text.Text; import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
@@ -24,7 +25,7 @@ public class MixinOptionsScreen extends Screen {
@Inject(at = @At("HEAD"),method = "init") @Inject(at = @At("HEAD"),method = "init")
private void midnightlib$init(CallbackInfo ci) { private void midnightlib$init(CallbackInfo ci) {
if (MidnightLibConfig.config_screen_list.equals(MidnightLibConfig.ConfigButton.TRUE) || (MidnightLibConfig.config_screen_list.equals(MidnightLibConfig.ConfigButton.MODMENU) && !PlatformFunctions.isModLoaded("modmenu"))) if (MidnightLibConfig.config_screen_list.equals(MidnightLibConfig.ConfigButton.TRUE) || (MidnightLibConfig.config_screen_list.equals(MidnightLibConfig.ConfigButton.MODMENU) && !FabricLoader.getInstance().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"))); 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)), new TranslatableText("midnightlib.overview.title")));
} }
} }

View File

@@ -9,9 +9,9 @@ import net.minecraft.client.font.TextRenderer;
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.screen.ScreenTexts;
import net.minecraft.client.gui.widget.*; import net.minecraft.client.gui.widget.*;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.*; import net.minecraft.text.*;
import java.util.*; import java.util.*;
@@ -19,7 +19,7 @@ import java.util.*;
public class MidnightConfigOverviewScreen extends Screen { public class MidnightConfigOverviewScreen extends Screen {
public MidnightConfigOverviewScreen(Screen parent) { public MidnightConfigOverviewScreen(Screen parent) {
super(Text.translatable( "midnightlib.overview.title")); super(new TranslatableText( "midnightlib.overview.title"));
this.parent = parent; this.parent = parent;
} }
private final Screen parent; private final Screen parent;
@@ -27,17 +27,15 @@ public class MidnightConfigOverviewScreen extends Screen {
@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 - 28, 200, 20).build()); this.addDrawableChild(new ButtonWidget(this.width / 2 - 100, this.height - 28, 200, 20, ScreenTexts.DONE, (button) -> Objects.requireNonNull(client).setScreen(parent)));
this.list = new MidnightOverviewListWidget(this.client, this.width, this.height, 32, this.height - 32, 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); if (this.client != null && this.client.world != null) this.list.setRenderBackground(false);
this.addSelectableChild(this.list); this.addSelectableChild(this.list);
List<String> sortedMods = new ArrayList<>(MidnightConfig.configClass.keySet()); MidnightConfig.configClass.forEach((modid, configClass) -> {
Collections.sort(sortedMods);
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(new ButtonWidget(this.width / 2 - 100, this.height - 28, 200, 20, new TranslatableText(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))));
} }
}); });
super.init(); super.init();
@@ -77,7 +75,7 @@ public class MidnightConfigOverviewScreen extends Screen {
} }
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(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
button.setY(y); button.y = y;
button.render(matrices, mouseX, mouseY, tickDelta); button.render(matrices, mouseX, mouseY, tickDelta);
} }
public List<? extends Element> children() {return buttonList;} public List<? extends Element> children() {return buttonList;}

View File

@@ -11,9 +11,7 @@ import java.io.Reader;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.*;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
@SuppressWarnings("UnstableApiUsage") @SuppressWarnings("UnstableApiUsage")

View File

@@ -7,7 +7,7 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
public class WitchHatModel<T extends LivingEntity> extends SinglePartEntityModel<T> { public class WitchHatModel<T extends LivingEntity> extends SinglePartEntityModel<T> {
private final ModelPart headwear; private final ModelPart headwear;
public WitchHatModel(ModelPart root) { public WitchHatModel(ModelPart root) {
headwear = root; headwear = root;
@@ -37,13 +37,13 @@ public class WitchHatModel<T extends LivingEntity> extends SinglePartEntityModel
return modelData; return modelData;
} }
@Override @Override
public void setAngles(T entity, float limbAngle, float limbDistance, float animationProgress, float headYaw, float headPitch) { public void setAngles(T entity, float limbAngle, float limbDistance, float animationProgress, float headYaw, float headPitch) {
} }
@Override @Override
public void render(MatrixStack matrixStack, VertexConsumer buffer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha){ 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); headwear.render(matrixStack, buffer, packedLight, packedOverlay, red, green, blue, alpha);
} }
@Override @Override
@@ -51,9 +51,9 @@ public class WitchHatModel<T extends LivingEntity> extends SinglePartEntityModel
return headwear; return headwear;
} }
public void setRotationAngle(ModelPart bone, float x, float y, float z) { public void setRotationAngle(ModelPart bone, float x, float y, float z) {
bone.pitch = x; bone.pitch = x;
bone.yaw = y; bone.yaw = y;
bone.roll = z; bone.roll = z;
} }
} }

View File

@@ -4,18 +4,15 @@ import com.mojang.brigadier.arguments.DoubleArgumentType;
import com.mojang.brigadier.arguments.IntegerArgumentType; import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import eu.midnightdust.lib.util.PlatformFunctions; import net.fabricmc.fabric.api.command.v1.CommandRegistrationCallback;
import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text; import net.minecraft.text.LiteralText;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
public class AutoCommand { public class AutoCommand {
public static List<LiteralArgumentBuilder<ServerCommandSource>> commands = new ArrayList<>();
private LiteralArgumentBuilder<ServerCommandSource> command; private LiteralArgumentBuilder<ServerCommandSource> command;
final Field entry; final Field entry;
final String modid; final String modid;
@@ -30,7 +27,7 @@ public class AutoCommand {
command(); command();
LiteralArgumentBuilder<ServerCommandSource> finalized = CommandManager.literal("midnightconfig").requires(source -> source.hasPermissionLevel(2)).then(command); LiteralArgumentBuilder<ServerCommandSource> finalized = CommandManager.literal("midnightconfig").requires(source -> source.hasPermissionLevel(2)).then(command);
PlatformFunctions.registerCommand(finalized); commands.add(finalized); CommandRegistrationCallback.EVENT.register((dispatcher, dedicated) -> dispatcher.register(finalized));
} }
private void command() { private void command() {
@@ -64,10 +61,10 @@ public class AutoCommand {
} }
} }
else else
command = command.then(CommandManager.literal(this.entry.getName()).executes(ctx -> getValue(ctx.getSource())).then( command = command.then(CommandManager.literal(this.entry.getName()).executes(ctx -> getValue(ctx.getSource())).then(
CommandManager.argument("value", StringArgumentType.string()) CommandManager.argument("value", StringArgumentType.string())
.executes(ctx -> this.setValue(ctx.getSource(), StringArgumentType.getString(ctx, "value"))) .executes(ctx -> this.setValue(ctx.getSource(), StringArgumentType.getString(ctx, "value")))
)); ));
} }
private int setValue(ServerCommandSource source, Object value) { private int setValue(ServerCommandSource source, Object value) {
@@ -76,16 +73,16 @@ public class AutoCommand {
MidnightConfig.write(modid); MidnightConfig.write(modid);
} }
catch (Exception e) { catch (Exception e) {
source.sendError(Text.literal("Could not set "+entry.getName()+" to value "+value+": " + e)); source.sendError(new LiteralText("Could not set "+entry.getName()+" to value "+value+": " + e));
return 0; return 0;
} }
source.sendFeedback(Text.literal("Successfully set " + entry.getName()+" to "+value), true); source.sendFeedback(new LiteralText("Successfully set " + entry.getName()+" to "+value), true);
return 1; return 1;
} }
private int getValue(ServerCommandSource source) { private int getValue(ServerCommandSource source) {
try { try {
source.sendFeedback(Text.literal("The value of "+entry.getName()+" is "+entry.get(null)), false); source.sendFeedback(new LiteralText("The value of "+entry.getName()+" is "+entry.get(null)), false);
return 1; return 1;
} }
catch (IllegalAccessException ignored) {} catch (IllegalAccessException ignored) {}

View File

@@ -25,4 +25,4 @@ public class AutoModMenu implements ModMenuApi {
); );
return map; return map;
} }
} }

View File

@@ -4,22 +4,26 @@ import com.google.gson.ExclusionStrategy;
import com.google.gson.FieldAttributes; import com.google.gson.FieldAttributes;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.fabricmc.loader.api.FabricLoader;
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.DrawableHelper;
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.tooltip.Tooltip; import net.minecraft.client.gui.screen.ScreenTexts;
import net.minecraft.client.gui.widget.*; import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.gui.widget.ElementListWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.resource.language.I18n; import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.screen.ScreenTexts; import net.minecraft.text.LiteralText;
import net.minecraft.text.Style; import net.minecraft.text.Style;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.Formatting; import net.minecraft.util.Formatting;
import java.awt.Color; import java.awt.Color;
@@ -38,9 +42,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.1.0 by TeamMidnightDust & Motschen
* Single class config library - feel free to copy! * Single class config library - feel free to copy!
*
* Based on https://github.com/Minenash/TinyConfig * Based on https://github.com/Minenash/TinyConfig
* Credits to Minenash */ * Credits to Minenash */
@@ -57,14 +61,13 @@ public abstract class MidnightConfig {
Object widget; Object widget;
int width; int width;
int max; int max;
boolean centered;
Map.Entry<TextFieldWidget,Text> error; Map.Entry<TextFieldWidget,Text> error;
Object defaultValue; Object defaultValue;
Object value; Object value;
String tempValue; String tempValue;
boolean inLimits = true; boolean inLimits = true;
String id; String id;
Text name; TranslatableText name;
int index; int index;
ClickableWidget colorButton; ClickableWidget colorButton;
} }
@@ -75,14 +78,13 @@ public abstract class MidnightConfig {
private static final Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).excludeFieldsWithModifiers(Modifier.PRIVATE).addSerializationExclusionStrategy(new HiddenAnnotationExclusionStrategy()).setPrettyPrinting().create(); private static final Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.TRANSIENT).excludeFieldsWithModifiers(Modifier.PRIVATE).addSerializationExclusionStrategy(new HiddenAnnotationExclusionStrategy()).setPrettyPrinting().create();
public static void init(String modid, Class<?> config) { public static void init(String modid, Class<?> config) {
path = PlatformFunctions.getConfigDirectory().resolve(modid + ".json"); path = FabricLoader.getInstance().getConfigDir().resolve(modid + ".json");
configClass.put(modid, config); configClass.put(modid, config);
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))
if (PlatformFunctions.isClientEnv()) initClient(modid, field, info); if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) initClient(modid, field, info);
if (field.isAnnotationPresent(Comment.class)) info.centered = field.getAnnotation(Comment.class).centered();
if (field.isAnnotationPresent(Entry.class)) if (field.isAnnotationPresent(Entry.class))
try { try {
info.defaultValue = field.get(null); info.defaultValue = field.get(null);
@@ -96,7 +98,8 @@ public abstract class MidnightConfig {
try { try {
info.value = info.field.get(null); info.value = info.field.get(null);
info.tempValue = info.value.toString(); info.tempValue = info.value.toString();
} catch (IllegalAccessException ignored) {} } catch (IllegalAccessException ignored) {
}
} }
} }
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
@@ -108,7 +111,7 @@ public abstract class MidnightConfig {
info.id = modid; info.id = modid;
if (e != null) { if (e != null) {
if (!e.name().equals("")) info.name = Text.translatable(e.name()); if (!e.name().equals("")) info.name = new TranslatableText(e.name());
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);
@@ -116,14 +119,14 @@ public abstract class MidnightConfig {
info.max = e.max() == Double.MAX_VALUE ? Integer.MAX_VALUE : (int) e.max(); info.max = e.max() == Double.MAX_VALUE ? Integer.MAX_VALUE : (int) e.max();
textField(info, String::length, null, Math.min(e.min(), 0), Math.max(e.max(), 1), true); textField(info, String::length, null, Math.min(e.min(), 0), Math.max(e.max(), 1), true);
} else if (type == boolean.class) { } 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 -> new LiteralText((Boolean) value ? "True" : "False").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;
button.setMessage(func.apply(info.value)); button.setMessage(func.apply(info.value));
}, func); }, func);
} else if (type.isEnum()) { } else if (type.isEnum()) {
List<?> values = Arrays.asList(field.getType().getEnumConstants()); List<?> values = Arrays.asList(field.getType().getEnumConstants());
Function<Object, Text> func = value -> Text.translatable(modid + ".midnightconfig." + "enum." + type.getSimpleName() + "." + info.value.toString()); Function<Object, Text> func = value -> new TranslatableText(modid + ".midnightconfig." + "enum." + type.getSimpleName() + "." + info.value.toString());
info.widget = new AbstractMap.SimpleEntry<ButtonWidget.PressAction, Function<Object, Text>>(button -> { info.widget = new AbstractMap.SimpleEntry<ButtonWidget.PressAction, Function<Object, Text>>(button -> {
int index = values.indexOf(info.value) + 1; int index = values.indexOf(info.value) + 1;
info.value = values.get(index >= values.size() ? 0 : index); info.value = values.get(index >= values.size() ? 0 : index);
@@ -144,9 +147,9 @@ public abstract class MidnightConfig {
boolean inLimits = false; boolean inLimits = false;
info.error = null; 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; } value = f.apply(s);
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 : new AbstractMap.SimpleEntry<>(t, new LiteralText(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)));
} }
@@ -167,7 +170,7 @@ public abstract class MidnightConfig {
if (!s.contains("#")) s = '#' + s; if (!s.contains("#")) s = '#' + s;
if (!HEXADECIMAL_ONLY.matcher(s).matches()) return false; if (!HEXADECIMAL_ONLY.matcher(s).matches()) return false;
try { try {
info.colorButton.setMessage(Text.literal("").setStyle(Style.EMPTY.withColor(Color.decode(info.tempValue).getRGB()))); info.colorButton.setMessage(new LiteralText("").setStyle(Style.EMPTY.withColor(Color.decode(info.tempValue).getRGB())));
} catch (Exception ignored) {} } catch (Exception ignored) {}
} }
return true; return true;
@@ -175,7 +178,7 @@ public abstract class MidnightConfig {
} }
public static void write(String modid) { public static void write(String modid) {
path = PlatformFunctions.getConfigDirectory().resolve(modid + ".json"); path = FabricLoader.getInstance().getConfigDir().resolve(modid + ".json");
try { try {
if (!Files.exists(path)) Files.createFile(path); if (!Files.exists(path)) Files.createFile(path);
Files.write(path, gson.toJson(configClass.get(modid).getDeclaredConstructor().newInstance()).getBytes()); Files.write(path, gson.toJson(configClass.get(modid).getDeclaredConstructor().newInstance()).getBytes());
@@ -188,18 +191,18 @@ public abstract class MidnightConfig {
return new MidnightConfigScreen(parent, modid); return new MidnightConfigScreen(parent, modid);
} }
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public static class MidnightConfigScreen extends Screen { private static class MidnightConfigScreen extends Screen {
protected MidnightConfigScreen(Screen parent, String modid) { protected MidnightConfigScreen(Screen parent, String modid) {
super(Text.translatable(modid + ".midnightconfig." + "title")); super(new TranslatableText(modid + ".midnightconfig." + "title"));
this.parent = parent; this.parent = parent;
this.modid = modid; this.modid = modid;
this.translationPrefix = modid + ".midnightconfig."; this.translationPrefix = modid + ".midnightconfig.";
} }
public final String translationPrefix; private final String translationPrefix;
public final Screen parent; private final Screen parent;
public final String modid; private final String modid;
public MidnightConfigListWidget list; private MidnightConfigListWidget list;
public boolean reload = false; private boolean reload = false;
// Real Time config update // // Real Time config update //
@Override @Override
@@ -208,18 +211,8 @@ public abstract class MidnightConfig {
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) {}
} }
updateResetButtons();
} }
public void updateResetButtons() { private void loadValues() {
if (this.list != null) {
for (ButtonEntry entry : this.list.children()) {
if (entry.buttons != null && entry.buttons.size() > 1 && entry.buttons.get(1) instanceof ButtonWidget button) {
button.active = !Objects.equals(entry.info.value.toString(), entry.info.defaultValue.toString());
}
}
}
}
public void loadValues() {
try { gson.fromJson(Files.newBufferedReader(path), configClass.get(modid)); } try { gson.fromJson(Files.newBufferedReader(path), configClass.get(modid)); }
catch (Exception e) { write(modid); } catch (Exception e) { write(modid); }
@@ -231,20 +224,17 @@ public abstract class MidnightConfig {
} catch (IllegalAccessException ignored) {} } catch (IllegalAccessException ignored) {}
} }
} }
public Tooltip getTooltip(EntryInfo info) {
return Tooltip.of(I18n.hasTranslation(translationPrefix+info.field.getName()+".tooltip") ? Text.translatable(translationPrefix+info.field.getName()+".tooltip") : Text.empty());
}
@Override @Override
public void init() { protected void init() {
super.init(); super.init();
if (!reload) loadValues(); if (!reload) loadValues();
this.addDrawableChild(ButtonWidget.builder(ScreenTexts.CANCEL, button -> { this.addDrawableChild(new ButtonWidget(this.width / 2 - 154, this.height - 28, 150, 20, 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()); }));
ButtonWidget done = this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, (button) -> { ButtonWidget done = this.addDrawableChild(new ButtonWidget(this.width / 2 + 4, this.height - 28, 150, 20, ScreenTexts.DONE, (button) -> {
for (EntryInfo info : entries) for (EntryInfo info : entries)
if (info.id.equals(modid)) { if (info.id.equals(modid)) {
try { try {
@@ -253,15 +243,15 @@ public abstract class MidnightConfig {
} }
write(modid); write(modid);
Objects.requireNonNull(client).setScreen(parent); Objects.requireNonNull(client).setScreen(parent);
}).dimensions(this.width / 2 + 4, this.height - 28, 150, 20).build()); }));
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);
for (EntryInfo info : entries) { for (EntryInfo info : entries) {
if (info.id.equals(modid)) { if (info.id.equals(modid)) {
Text name = Objects.requireNonNullElseGet(info.name, () -> Text.translatable(translationPrefix + info.field.getName())); TranslatableText name = Objects.requireNonNullElseGet(info.name, () -> new TranslatableText(translationPrefix + info.field.getName()));
ButtonWidget resetButton = ButtonWidget.builder(Text.literal("Reset").formatted(Formatting.RED), (button -> { ButtonWidget resetButton = new ButtonWidget(width - 205, 0, 40, 20, new LiteralText("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;
@@ -269,22 +259,23 @@ public abstract class MidnightConfig {
this.reload = true; this.reload = true;
Objects.requireNonNull(client).setScreen(this); Objects.requireNonNull(client).setScreen(this);
list.setScrollAmount(scrollAmount); list.setScrollAmount(scrollAmount);
})).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 -> new TranslatableText(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(new ButtonWidget(width - 160, 0,150, 20, widget.getValue().apply(info.value), widget.getKey()),resetButton), name);
} 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, null);
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))));
else widget.setText("");
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(new LiteralText("R").formatted(Formatting.RED));
ButtonWidget cycleButton = ButtonWidget.builder(Text.literal(String.valueOf(info.index)).formatted(Formatting.GOLD), (button -> { ButtonWidget cycleButton = new ButtonWidget(width - 185, 0, 20, 20, new LiteralText(String.valueOf(info.index)).formatted(Formatting.GOLD), (button -> {
((List<String>)info.value).remove(""); ((List<String>)info.value).remove("");
double scrollAmount = list.getScrollAmount(); double scrollAmount = list.getScrollAmount();
this.reload = true; this.reload = true;
@@ -292,36 +283,27 @@ public abstract class MidnightConfig {
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); Objects.requireNonNull(client).setScreen(this);
list.setScrollAmount(scrollAmount); list.setScrollAmount(scrollAmount);
})).dimensions(width - 185, 0, 20, 20).build(); }));
widget.setTooltip(getTooltip(info)); this.list.addButton(List.of(widget, resetButton, cycleButton), name);
this.list.addButton(List.of(widget, resetButton, cycleButton), name, info);
} else if (info.widget != null) { } else if (info.widget != null) {
ClickableWidget widget; TextFieldWidget widget = new TextFieldWidget(textRenderer, width - 160, 0, 150, 20, null);
Entry e = info.field.getAnnotation(Entry.class); widget.setMaxLength(info.width);
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); widget.setText(info.tempValue);
else widget = new TextFieldWidget(textRenderer, width - 160, 0, 150, 20, null, Text.of(info.tempValue)); Predicate<String> processor = ((BiFunction<TextFieldWidget, ButtonWidget, Predicate<String>>) info.widget).apply(widget, done);
if (widget instanceof TextFieldWidget textField) { widget.setTextPredicate(processor);
textField.setMaxLength(info.width); if (info.field.getAnnotation(Entry.class).isColor()) {
textField.setText(info.tempValue);
Predicate<String> processor = ((BiFunction<TextFieldWidget, ButtonWidget, Predicate<String>>) info.widget).apply(textField, done);
textField.setTextPredicate(processor);
}
widget.setTooltip(getTooltip(info));
if (e.isColor()) {
resetButton.setWidth(20); resetButton.setWidth(20);
resetButton.setMessage(Text.literal("R").formatted(Formatting.RED)); resetButton.setMessage(new LiteralText("R").formatted(Formatting.RED));
ButtonWidget colorButton = ButtonWidget.builder(Text.literal(""), (button -> {})).dimensions(width - 185, 0, 20, 20).build(); ButtonWidget colorButton = new ButtonWidget(width - 185, 0, 20, 20, new LiteralText(""), (button -> {}));
try {colorButton.setMessage(Text.literal("").setStyle(Style.EMPTY.withColor(Color.decode(info.tempValue).getRGB())));} catch (Exception ignored) {} try {colorButton.setMessage(new LiteralText("").setStyle(Style.EMPTY.withColor(Color.decode(info.tempValue).getRGB())));} catch (Exception ignored) {}
info.colorButton = colorButton; info.colorButton = colorButton;
colorButton.active = false; this.list.addButton(List.of(widget, colorButton, resetButton), name);
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);
} else { } else {
this.list.addButton(List.of(),name, info); this.list.addButton(List.of(),name);
} }
} }
updateResetButtons();
} }
} }
@@ -330,6 +312,25 @@ public abstract class MidnightConfig {
this.renderBackground(matrices); this.renderBackground(matrices);
this.list.render(matrices, mouseX, mouseY, delta); this.list.render(matrices, mouseX, mouseY, delta);
drawCenteredText(matrices, textRenderer, title, width / 2, 15, 0xFFFFFF); drawCenteredText(matrices, textRenderer, title, width / 2, 15, 0xFFFFFF);
for (EntryInfo info : entries) {
if (info.id.equals(modid)) {
if (list.getHoveredButton(mouseX,mouseY).isPresent()) {
ClickableWidget buttonWidget = list.getHoveredButton(mouseX,mouseY).get();
Text text = ButtonEntry.buttonsWithText.get(buttonWidget);
TranslatableText name = new TranslatableText(this.translationPrefix + info.field.getName());
String key = translationPrefix + info.field.getName() + ".tooltip";
if (info.error != null && text.equals(name)) renderTooltip(matrices, info.error.getValue(), mouseX, mouseY);
else if (I18n.hasTranslation(key) && text.equals(name)) {
List<Text> list = new ArrayList<>();
for (String str : I18n.translate(key).split("\n"))
list.add(new LiteralText(str));
renderTooltip(matrices, list, mouseX, mouseY);
}
}
}
}
super.render(matrices,mouseX,mouseY,delta); super.render(matrices,mouseX,mouseY,delta);
} }
} }
@@ -345,8 +346,8 @@ public abstract class MidnightConfig {
@Override @Override
public int getScrollbarPositionX() { return this.width -7; } public int getScrollbarPositionX() { return this.width -7; }
public void addButton(List<ClickableWidget> buttons, Text text, EntryInfo info) { public void addButton(List<ClickableWidget> buttons, Text text) {
this.addEntry(new ButtonEntry(buttons, text, info)); this.addEntry(ButtonEntry.create(buttons, text));
} }
@Override @Override
public int getRowWidth() { return 10000; } public int getRowWidth() { return 10000; }
@@ -363,63 +364,36 @@ public abstract class MidnightConfig {
private static final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; private static final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
public final List<ClickableWidget> buttons; public final List<ClickableWidget> buttons;
private final Text text; private final Text text;
public final EntryInfo info;
private final List<ClickableWidget> children = new ArrayList<>(); private final List<ClickableWidget> children = new ArrayList<>();
public static final Map<ClickableWidget, Text> buttonsWithText = new HashMap<>(); public static final Map<ClickableWidget, Text> buttonsWithText = new HashMap<>();
private ButtonEntry(List<ClickableWidget> buttons, Text text, EntryInfo info) { private ButtonEntry(List<ClickableWidget> buttons, Text text) {
if (!buttons.isEmpty()) buttonsWithText.put(buttons.get(0),text); if (!buttons.isEmpty()) buttonsWithText.put(buttons.get(0),text);
this.buttons = buttons; this.buttons = buttons;
this.text = text; this.text = text;
this.info = info;
children.addAll(buttons); children.addAll(buttons);
} }
public static ButtonEntry create(List<ClickableWidget> buttons, Text text) {
return new ButtonEntry(buttons, text);
}
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(MatrixStack matrices, 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.y = y; b.render(matrices, 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); DrawableHelper.drawTextWithShadow(matrices,textRenderer, text,12,y+5,0xFFFFFF);
else DrawableHelper.drawTextWithShadow(matrices, textRenderer, text, 12, y + 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 {
private final EntryInfo info; private final Entry e;
public MidnightSliderWidget(int x, int y, int width, int height, Text text, double value, EntryInfo info) {
super(x, y, width, height, text, value);
this.e = info.field.getAnnotation(Entry.class);
this.info = info;
}
@Override
protected void updateMessage() {
this.setMessage(Text.of(info.tempValue));
}
@Override
protected void applyValue() {
if (info.field.getType() == int.class) info.value = ((Number) (e.min() + value * (e.max() - e.min()))).intValue();
else if (info.field.getType() == double.class) info.value = Math.round((e.min() + value * (e.max() - e.min())) * (double) e.precision()) / (double) e.precision();
else if (info.field.getType() == float.class) info.value = Math.round((e.min() + value * (e.max() - e.min())) * (float) e.precision()) / (float) e.precision();
info.tempValue = String.valueOf(info.value);
}
}
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Entry { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Entry {
int width() default 100; int width() default 100;
double min() default Double.MIN_NORMAL; double min() default Double.MIN_NORMAL;
double max() default Double.MAX_VALUE; double max() default Double.MAX_VALUE;
String name() default ""; String name() default "";
boolean isColor() default false; boolean isColor() default false;
boolean isSlider() default false;
int precision() default 100;
} }
@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 Comment {}
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Comment {
boolean centered() default false;
}
public static class HiddenAnnotationExclusionStrategy implements ExclusionStrategy { public static class HiddenAnnotationExclusionStrategy implements ExclusionStrategy {
public boolean shouldSkipClass(Class<?> clazz) { return false; } public boolean shouldSkipClass(Class<?> clazz) { return false; }

View File

@@ -1,6 +1,4 @@
package eu.midnightdust.core.config; package eu.midnightdust.lib.config;
import eu.midnightdust.lib.config.MidnightConfig;
import java.util.List; import java.util.List;
@@ -13,20 +11,17 @@ 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 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! @Entry public static int fabric = 16777215; // Example for a int option
@Entry public static int fabric = 16777215; // Example for an int option
@Entry public static double world = 1.4D; // Example for a double option @Entry public static double world = 1.4D; // Example for a double option
@Entry public static boolean showInfo = true; // Example for a boolean option @Entry public static boolean showInfo = true; // Example for a boolean option
@Entry public static String name = "Hello World!"; // Example for a string option @Entry public static String name = "Hello World!"; // Example for a string option
@Entry public static TestEnum testEnum = TestEnum.FABRIC; // Example for an enum option @Entry public static TestEnum testEnum = TestEnum.FABRIC; // Example for a 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
} }
@Entry(min=69,max=420) public static int hello = 420; // - The entered number has to be larger than 69 and smaller than 420 @Entry(min=69,max=420) public static int hello = 420; // - The entered number has to be larger than 69 and smaller than 420
@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(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 an array list!") public static List<String> arrayList = List.of("String1", "String2"); // Array String Lists are also supported @Entry(name = "I am an array list!") public static List<String> arrayList = List.of("String1", "String2"); // Array String Lists are also supported
@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(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
@@ -36,28 +31,29 @@ public class MidnightConfigExample extends MidnightConfig {
{ {
"modid.midnightconfig.title":"I am a title", // "*.midnightconfig.title" defines the title of the screen "modid.midnightconfig.title":"I am a title", // "*.midnightconfig.title" defines the title of the screen
"modid.midnightconfig.text1":"I am a comment *u*", // Translation for the comment "text1" defined in the example config "modid.midnightconfig.text1":"I am a comment *u*", // Translation for the comment "text1" defined in the example config
"modid.midnightconfig.text2":"I am a centered comment (╯°□°)╯︵ ┻━┻",
"modid.midnightconfig.name":"I am a string!", // Translation for the field "name" defined in the example config "modid.midnightconfig.name":"I am a string!", // Translation for the field "name" defined in the example config
"modid.midnightconfig.name.tooltip":"I am a tooltip uwu \nI am a new line",
"modid.midnightconfig.name.tooltip":"uwu \n I am a new line",
// When hovering over the option "showInfo", // When hovering over the option "showInfo",
// this text will appear as a tooltip. // this text will appear as a tooltip.
// "\n" inserts a line break. // "\n" inserts a line break.
"modid.midnightconfig.fabric":"I am an int", "modid.midnightconfig.fabric":"I am an int",
"modid.midnightconfig.world":"I am a double", "modid.midnightconfig.world":"I am a double",
"modid.midnightconfig.showInfo":"I am a boolean", "modid.midnightconfig.showInfo":"I am a boolean",
"modid.midnightconfig.hello":"I am a limited int!", "modid.midnightconfig.hello":"I am a limited int!",
"modid.midnightconfig.testEnum":"I am an enum!", "modid.midnightconfig.testEnum":"I am an enum!",
"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"
} }
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: The code in your ModMenu integration class would look something like this:
@Override @Override
public ConfigScreenFactory<?> getModConfigScreenFactory() { public ConfigScreenFactory<?> getModConfigScreenFactory() {
return parent -> MidnightConfig.getScreen(parent, "modid"); return parent -> MidnightConfig.getScreen(parent, "modid");
} }
*/ */
} }

View File

@@ -8,15 +8,9 @@ import net.minecraft.text.Text;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class TexturedOverlayButtonWidget extends TexturedButtonWidget { public class TexturedOverlayButtonWidget extends TexturedButtonWidget {
public TexturedOverlayButtonWidget(int x, int y, int width, int height, int u, int v, Identifier texture, PressAction pressAction) { 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); 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) { 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); super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction);
} }
@@ -25,17 +19,21 @@ public class TexturedOverlayButtonWidget extends TexturedButtonWidget {
super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, text); super(x, y, width, height, u, v, hoveredVOffset, texture, textureWidth, textureHeight, pressAction, text);
} }
public TexturedOverlayButtonWidget(int x, int y, int width, int height, int u, int v, int hoveredVOffset, Identifier texture, int textureWidth, int textureHeight, PressAction pressAction, TooltipSupplier tooltipSupplier, Text text) {
super(x,y,width,height, u,v,hoveredVOffset,texture,textureWidth,textureHeight,pressAction,tooltipSupplier,text);
}
@Override @Override
public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) { public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) {
RenderSystem.setShader(GameRenderer::getPositionTexProgram); RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, WIDGETS_TEXTURE); RenderSystem.setShaderTexture(0, WIDGETS_TEXTURE);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha);
int i = this.getYImage(this.isHovered()); int i = this.getYImage(this.isHovered());
RenderSystem.enableBlend(); RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc(); RenderSystem.defaultBlendFunc();
RenderSystem.enableDepthTest(); RenderSystem.enableDepthTest();
this.drawTexture(matrices, this.getX(), this.getY(), 0, 46 + i * 20, this.width / 2, this.height); this.drawTexture(matrices, this.x, this.y, 0, 46 + i * 20, this.width / 2, this.height);
this.drawTexture(matrices, this.getX() + this.width / 2, this.getY(), 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height); this.drawTexture(matrices, this.x + this.width / 2, this.y, 200 - this.width / 2, 46 + i * 20, this.width / 2, this.height);
super.renderButton(matrices, mouseX, mouseY, delta); super.renderButton(matrices, mouseX, mouseY, delta);
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@@ -3,8 +3,8 @@
"midnightlib.midnightconfig.title":"MidnightLib Config", "midnightlib.midnightconfig.title":"MidnightLib Config",
"midnightlib.midnightconfig.midnightlib_description":"§nMidnightLib", "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":"§aTrue",
"midnightlib.midnightconfig.enum.ConfigButton.FALSE":"§cNo", "midnightlib.midnightconfig.enum.ConfigButton.FALSE":"§cFalse",
"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.midnighthats_description":"§nMidnightHats",

View File

Before

Width:  |  Height:  |  Size: 217 B

After

Width:  |  Height:  |  Size: 217 B

View File

@@ -21,10 +21,10 @@
"environment": "*", "environment": "*",
"entrypoints": { "entrypoints": {
"client": [ "client": [
"eu.midnightdust.fabric.core.MidnightLibClientFabric" "eu.midnightdust.core.MidnightLibClient"
], ],
"server": [ "server": [
"eu.midnightdust.fabric.core.MidnightLibServerFabric" "eu.midnightdust.core.MidnightLibServer"
], ],
"modmenu": [ "modmenu": [
"eu.midnightdust.lib.config.AutoModMenu" "eu.midnightdust.lib.config.AutoModMenu"
@@ -35,6 +35,10 @@
"midnightlib.mixins.json" "midnightlib.mixins.json"
], ],
"depends": {
"fabric-renderer-registries-v1": "*"
},
"custom": { "custom": {
"modmenu": { "modmenu": {
"links": { "links": {

View File

@@ -1,8 +1,7 @@
{ {
"required": true, "required": true,
"minVersion": "0.8",
"package": "eu.midnightdust.core.mixin", "package": "eu.midnightdust.core.mixin",
"compatibilityLevel": "JAVA_17", "compatibilityLevel": "JAVA_16",
"client": [ "client": [
"MixinOptionsScreen", "MixinOptionsScreen",
"MixinPlayerEntityRenderer" "MixinPlayerEntityRenderer"