diff --git a/.gitignore b/.gitignore index 823aca8..87a3607 100755 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,7 @@ bin/ # fabric -run/ \ No newline at end of file +run/ + +# unfinished +puzzle-randomentities/ \ No newline at end of file diff --git a/build.gradle b/build.gradle index d6d8de6..1edd011 100755 --- a/build.gradle +++ b/build.gradle @@ -1,106 +1,137 @@ +// Based on https://github.com/OnyxStudios/Cardinal-Components-API/blob/1.17/build.gradle plugins { - id 'fabric-loom' version '0.7-SNAPSHOT' - id 'maven-publish' + id "fabric-loom" version "0.8-SNAPSHOT" apply false + id "com.matthewprenger.cursegradle" version "1.4.0" + id "maven-publish" + id "java-library" } -sourceCompatibility = JavaVersion.VERSION_1_8 -targetCompatibility = JavaVersion.VERSION_1_8 +group = "net.puzzlemc" +archivesBaseName = "puzzle" -archivesBaseName = project.archives_base_name -version = project.mod_version -group = project.maven_group +subprojects { + apply plugin: 'fabric-loom' + apply plugin: 'com.matthewprenger.cursegradle' + apply plugin: 'maven-publish' + apply plugin: 'java-library' -minecraft { + archivesBaseName = project.name + group = "${rootProject.group}.${rootProject.archivesBaseName}" + + //apply from: "https://raw.githubusercontent.com/OnyxStudios/Gradle-Scripts/master/scripts/fabric/basic_project.gradle" } +allprojects { + apply plugin: "fabric-loom" + sourceCompatibility = targetCompatibility = JavaVersion.VERSION_16 + version = System.getenv("TRAVIS_TAG") ?: rootProject.mod_version + + configurations { + dev + } + + repositories { + maven { url 'https://jitpack.io' } + + } + + dependencies { + minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" + mappings "net.fabricmc:yarn:${rootProject.yarn_mappings}:v2" + modApi "net.fabricmc:fabric-loader:${rootProject.loader_version}" + modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_version}" + } + + processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } + } + + // 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 + tasks.withType(JavaCompile).configureEach { + it.options.encoding = "UTF-8" + 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 { + } + + afterEvaluate { + artifacts { + dev file: file("${project.buildDir}/libs/$archivesBaseName-${version}-dev.jar"), type: "jar", builtBy: sourcesJar + } + } +} + +subprojects { + version = rootProject.version +} + +sourceSets { + testmod { + compileClasspath += main.compileClasspath + runtimeClasspath += main.runtimeClasspath + } + test { + compileClasspath += main.compileClasspath + runtimeClasspath += main.runtimeClasspath + } +} + +subprojects.each { remapJar.dependsOn("${it.path}:remapJar") } + repositories { - maven { url "https://maven.shedaniel.me/" } - maven { url "https://jitpack.io" } - maven { url "https://maven.terraformersmc.com/releases" } - maven { url "https://aperlambda.github.io/maven" } + maven { + name = "JitPack" + url = "https://jitpack.io" + } + maven { + name = "TerraformersMC" + url = "https://maven.terraformersmc.com/releases" + } + } dependencies { - //to change the versions see the gradle.properties file - minecraft "com.mojang:minecraft:${project.minecraft_version}" - mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" - modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" + modImplementation "net.fabricmc.fabric-api:fabric-api:0.34.8+1.17" + modImplementation ("com.terraformersmc:modmenu:${project.mod_menu_version}") { + exclude group: "net.fabricmc.fabric-api" + } - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - - modImplementation "com.terraformersmc:modmenu:${project.mod_menu_version}" - modImplementation ("com.github.TeamMidnightDust:CullLeaves:${project.cull_leaves_version}"){ - exclude module: "modmenu" - } - modImplementation ("com.github.LambdAurora:LambDynamicLights:${project.ldl_version}") { - exclude module: "modmenu" - exclude module: "sodium-fabric" - } - modImplementation ("com.github.LambdAurora:LambdaBetterGrass:${project.lbg_version}") { - exclude module: "modmenu" - } - modImplementation ("com.github.IrisShaders:Iris:${project.iris_version}") { - exclude module: "modmenu" - } - modImplementation ("com.github.PepperCode1:ConnectedTexturesMod-Fabric:${project.ctmf_version}") { - exclude module: "modmenu" - } - modImplementation ("com.github.LambdAurora:LambdaControls:${project.lc_version}") { - exclude module: "modmenu" - } + subprojects.each { + api project(path: ":${it.name}", configuration: "dev") + include project(":${it.name}") + } } -processResources { - inputs.property "version", project.version - - filesMatching("fabric.mod.json") { - expand "version": project.version - } -} - -tasks.withType(JavaCompile).configureEach { - // 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 - // If Javadoc is generated, this must be specified in that task too. - it.options.encoding = "UTF-8" - - // Minecraft 1.17 (21w19a) upwards uses Java 16. - //it.options.release = 8 -} - -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. - } + publications { + mavenJava(MavenPublication) { + artifact(file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar")) { + builtBy(remapJar) + } + pom.withXml { + def depsNode = asNode().appendNode("dependencies") + subprojects.each { + def depNode = depsNode.appendNode("dependency") + depNode.appendNode("groupId", it.group) + depNode.appendNode("artifactId", it.name) + depNode.appendNode("version", it.version) + depNode.appendNode("scope", "compile") + } + } + } + } } diff --git a/gradle.properties b/gradle.properties index 8541f5d..c6841db 100755 --- a/gradle.properties +++ b/gradle.properties @@ -3,23 +3,22 @@ org.gradle.jvmargs=-Xmx1G # Fabric Properties # check these on https://fabricmc.net/use - minecraft_version=1.16.5 - yarn_mappings=1.16.5+build.6 - loader_version=0.11.3 + minecraft_version=1.17-rc1 + yarn_mappings=1.17-rc1+build.1 + loader_version=0.11.3 # Mod Properties - mod_version = 0.2.0 + mod_version = 0.3.0 maven_group = eu.midnightdust archives_base_name = puzzle # Dependencies # currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api - fabric_version=0.32.5+1.16 - mod_menu_version = 1.16.9 + fabric_version=0.34.8+1.17 + mod_menu_version = 2.0.0-beta.7 - cull_leaves_version = 2.1.0 - ldl_version = 1.3.4-1.16 - lbg_version = 1.0.3-1.16 - lc_version = 1.6.0-1.16 + cull_leaves_version = 2.2.0 + ldl_version = 2.0.0+21w20a + lbg_version = 1.1.2+21w20a iris_version = v0.4.0 ctmf_version = v0.4.0 diff --git a/gradlew.bat b/gradlew.bat index 107acd3..ac1b06f 100755 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,89 +1,89 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@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 obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@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 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -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. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@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 obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@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 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +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. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/puzzle-base/build.gradle b/puzzle-base/build.gradle new file mode 100755 index 0000000..65a1e2d --- /dev/null +++ b/puzzle-base/build.gradle @@ -0,0 +1,3 @@ +archivesBaseName = "puzzle-base" +dependencies { +} diff --git a/puzzle-base/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java b/puzzle-base/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java new file mode 100755 index 0000000..e922563 --- /dev/null +++ b/puzzle-base/src/main/java/eu/midnightdust/lib/config/MidnightConfig.java @@ -0,0 +1,376 @@ +package eu.midnightdust.lib.config; + +import com.google.gson.ExclusionStrategy; +import com.google.gson.FieldAttributes; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.Element; +import net.minecraft.client.gui.Selectable; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ScreenTexts; +import net.minecraft.client.gui.widget.*; +import net.minecraft.client.resource.language.I18n; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.*; +import net.minecraft.util.Formatting; + +import java.lang.annotation.*; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.*; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.regex.Pattern; + +// MidnightConfig v1.0.2 +// Single class config library - feel free to copy! +// Changelog: +// - 1.0.2: +// - Update to 21w20a +// - 1.0.1: +// - Fixed buttons not working in fullscreen +// - 1.0.0: +// - The config screen no longer shows the entries of all instances of MidnightConfig +// - Compatible with servers! +// - Scrollable! +// - Comment support! +// - Fresh New Design + +/** Based on https://github.com/Minenash/TinyConfig + * Credits to Minenash */ + +@SuppressWarnings("unchecked") +public class MidnightConfig { + public static boolean useTooltipForTitle = true; // Render title as tooltip or as simple text + + private static final Pattern INTEGER_ONLY = Pattern.compile("(-?[0-9]*)"); + private static final Pattern DECIMAL_ONLY = Pattern.compile("-?([\\d]+\\.?[\\d]*|[\\d]*\\.?[\\d]+|\\.)"); + + private static final List entries = new ArrayList<>(); + + protected static class EntryInfo { + Field field; + Object widget; + int width; + Map.Entry error; + Object defaultValue; + Object value; + String tempValue; + boolean inLimits = true; + String id; + } + + public static final Map> configClass = new HashMap<>(); + private static Path path; + + 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) { + path = FabricLoader.getInstance().getConfigDir().resolve(modid + ".json"); + configClass.put(modid, config); + + for (Field field : config.getFields()) { + EntryInfo info = new EntryInfo(); + if (field.isAnnotationPresent(Entry.class) || field.isAnnotationPresent(Comment.class)) + try { + initClient(modid, field, info); + } catch (Exception e) {continue;} + if (field.isAnnotationPresent(Entry.class)) + try { + info.defaultValue = field.get(null); + } catch (IllegalAccessException ignored) {} + } + try { gson.fromJson(Files.newBufferedReader(path), config); } + catch (Exception e) { write(modid); } + + for (EntryInfo info : entries) { + if (info.field.isAnnotationPresent(Entry.class)) + try { + info.value = info.field.get(null); + info.tempValue = info.value.toString(); + } catch (IllegalAccessException ignored) { + } + } + } + @Environment(EnvType.CLIENT) + public static void initClient(String modid, Field field, EntryInfo info) { + Class type = field.getType(); + Entry e = field.getAnnotation(Entry.class); + info.width = e != null ? e.width() : 0; + info.field = field; + info.id = modid; + + if (e != null) + if (type == int.class) textField(info, Integer::parseInt, INTEGER_ONLY, e.min(), e.max(), true); + else if (type == double.class) textField(info, Double::parseDouble, DECIMAL_ONLY, e.min(), e.max(),false); + else if (type == String.class) textField(info, String::length, null, Math.min(e.min(),0), Math.max(e.max(),1),true); + else if (type == boolean.class) { + Function func = value -> new LiteralText((Boolean) value ? "True" : "False").formatted((Boolean) value ? Formatting.GREEN : Formatting.RED); + info.widget = new AbstractMap.SimpleEntry>(button -> { + info.value = !(Boolean) info.value; + button.setMessage(func.apply(info.value)); + }, func); + } else if (type.isEnum()) { + List values = Arrays.asList(field.getType().getEnumConstants()); + Function func = value -> new TranslatableText(modid + ".midnightconfig." + "enum." + type.getSimpleName() + "." + info.value.toString()); + info.widget = new AbstractMap.SimpleEntry>( button -> { + int index = values.indexOf(info.value) + 1; + info.value = values.get(index >= values.size()? 0 : index); + button.setMessage(func.apply(info.value)); + }, func); + } + entries.add(info); + } + + private static void textField(EntryInfo info, Function f, Pattern pattern, double min, double max, boolean cast) { + boolean isNumber = pattern != null; + info.widget = (BiFunction>) (t, b) -> s -> { + s = s.trim(); + if (!(s.isEmpty() || !isNumber || pattern.matcher(s).matches())) return false; + + Number value = 0; + boolean inLimits = false; + System.out.println(((isNumber ^ s.isEmpty()))); + System.out.println(!s.equals("-") && !s.equals(".")); + info.error = null; + if (!(isNumber && s.isEmpty()) && !s.equals("-") && !s.equals(".")) { + value = f.apply(s); + inLimits = value.doubleValue() >= min && value.doubleValue() <= max; + info.error = inLimits? null : new AbstractMap.SimpleEntry<>(t, new LiteralText(value.doubleValue() < min ? + "§cMinimum " + (isNumber? "value" : "length") + (cast? " is " + (int)min : " is " + min) : + "§cMaximum " + (isNumber? "value" : "length") + (cast? " is " + (int)max : " is " + max))); + } + + info.tempValue = s; + t.setEditableColor(inLimits? 0xFFFFFFFF : 0xFFFF7777); + info.inLimits = inLimits; + b.active = entries.stream().allMatch(e -> e.inLimits); + + if (inLimits) + info.value = isNumber? value : s; + + return true; + }; + } + + public static void write(String modid) { + path = FabricLoader.getInstance().getConfigDir().resolve(modid + ".json"); + try { + if (!Files.exists(path)) Files.createFile(path); + Files.write(path, gson.toJson(configClass.get(modid).getDeclaredConstructor().newInstance()).getBytes()); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Environment(EnvType.CLIENT) + public static Screen getScreen(Screen parent, String modid) { + return new TinyConfigScreen(parent, modid); + } + + @Environment(EnvType.CLIENT) + private static class TinyConfigScreen extends Screen { + + protected TinyConfigScreen(Screen parent, String modid) { + super(new TranslatableText(modid + ".midnightconfig." + "title")); + this.parent = parent; + this.modid = modid; + this.translationPrefix = modid + ".midnightconfig."; + } + private final String translationPrefix; + private final Screen parent; + private final String modid; + private MidnightConfigListWidget list; + + // Real Time config update // + @Override + public void tick() { + for (EntryInfo info : entries) + try { info.field.set(null, info.value); } + catch (IllegalAccessException ignored) {} + } + + @Override + protected void init() { + super.init(); + + this.addDrawableChild(new ButtonWidget(this.width / 2 - 154, this.height - 28, 150, 20, ScreenTexts.CANCEL, button -> { + try { gson.fromJson(Files.newBufferedReader(path), configClass.get(modid)); } + catch (Exception e) { write(modid); } + + for (EntryInfo info : entries) { + if (info.field.isAnnotationPresent(Entry.class)) { + try { + info.value = info.field.get(null); + info.tempValue = info.value.toString(); + } catch (IllegalAccessException ignored) { + } + } + } + Objects.requireNonNull(client).openScreen(parent); + })); + + ButtonWidget done = this.addDrawableChild(new ButtonWidget(this.width / 2 + 4, this.height - 28, 150, 20, ScreenTexts.DONE, (button) -> { + for (EntryInfo info : entries) + if (info.id.equals(modid)) { + try { + info.field.set(null, info.value); + } catch (IllegalAccessException ignored) {} + } + write(modid); + Objects.requireNonNull(client).openScreen(parent); + })); + + this.list = new MidnightConfigListWidget(this.client, this.width, this.height, 32, this.height - 32, 25); + this.addSelectableChild(this.list); + for (EntryInfo info : entries) { + if (info.id.equals(modid)) { + TranslatableText name = new TranslatableText(translationPrefix + info.field.getName()); + ButtonWidget resetButton = new ButtonWidget(width - 155, 0, 40, 20, new LiteralText("Reset").formatted(Formatting.RED), (button -> { + info.value = info.defaultValue; + info.tempValue = info.value.toString(); + double scrollAmount = list.getScrollAmount(); + Objects.requireNonNull(client).openScreen(this); + list.setScrollAmount(scrollAmount); + })); + + if (info.widget instanceof Map.Entry) { + Map.Entry> widget = (Map.Entry>) info.widget; + if (info.field.getType().isEnum()) widget.setValue(value -> new TranslatableText(translationPrefix + "enum." + info.field.getType().getSimpleName() + "." + info.value.toString())); + this.list.addButton(new ButtonWidget(width - 110, 0, info.width, 20, widget.getValue().apply(info.value), widget.getKey()),resetButton,name); + } else if (info.widget != null) { + TextFieldWidget widget = new TextFieldWidget(textRenderer, width - 110, 0, info.width, 20, null); + + widget.setText(info.tempValue); + Predicate processor = ((BiFunction>) info.widget).apply(widget, done); + widget.setTextPredicate(processor); + this.list.addButton(widget, resetButton, name); + } else { + ButtonWidget dummy = new ButtonWidget(-10, 0, 0, 0, Text.of(""), null); + this.list.addButton(dummy,dummy,name); + } + } + } + + } + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + this.renderBackground(matrices); + this.list.render(matrices, mouseX, mouseY, delta); + + int stringWidth = (int) (title.getString().length() * 2.75f); + if (useTooltipForTitle) renderTooltip(matrices, title, width/2 - stringWidth, 27); + else 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 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); + } + } + @Environment(EnvType.CLIENT) + public static class MidnightConfigListWidget extends ElementListWidget { + TextRenderer textRenderer; + + public MidnightConfigListWidget(MinecraftClient minecraftClient, int i, int j, int k, int l, int m) { + super(minecraftClient, i, j, k, l, m); + this.centerListVertically = false; + textRenderer = minecraftClient.textRenderer; + } + @Override + public int getScrollbarPositionX() { return this.width -7; } + + public void addButton(ClickableWidget button, ClickableWidget resetButton, Text text) { + this.addEntry(ButtonEntry.create(button, text, resetButton)); + } + @Override + public int getRowWidth() { return 10000; } + public Optional getHoveredButton(double mouseX, double mouseY) { + for (ButtonEntry buttonEntry : this.children()) { + for (ClickableWidget ClickableWidget : buttonEntry.buttons) { + if (ClickableWidget.isMouseOver(mouseX, mouseY)) { + return Optional.of(ClickableWidget); + } + } + } + return Optional.empty(); + } + } + public static class ButtonEntry extends ElementListWidget.Entry { + private static final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; + private final List buttons = new ArrayList<>(); + private final List resetButtons = new ArrayList<>(); + private final List texts = new ArrayList<>(); + private final List buttonsWithResetButtons = new ArrayList<>(); + public static final Map buttonsWithText = new HashMap<>(); + + private ButtonEntry(ClickableWidget button, Text text, ClickableWidget resetButton) { + buttonsWithText.put(button,text); + this.buttons.add(button); + this.resetButtons.add(resetButton); + this.texts.add(text); + this.buttonsWithResetButtons.add(button); + this.buttonsWithResetButtons.add(resetButton); + } + public static ButtonEntry create(ClickableWidget button, Text text, ClickableWidget resetButton) { + return new ButtonEntry(button, text, resetButton); + } + public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) { + this.buttons.forEach(button -> { + button.y = y; + button.render(matrices, mouseX, mouseY, tickDelta); + }); + this.texts.forEach(text -> DrawableHelper.drawTextWithShadow(matrices,textRenderer, text,12,y+5,0xFFFFFF)); + this.resetButtons.forEach((button) -> { + button.y = y; + button.render(matrices, mouseX, mouseY, tickDelta); + }); + } + public List children() { + return buttonsWithResetButtons; + } + + public List method_37025() { + return buttonsWithResetButtons; + } + } + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface Entry { + int width() default 100; + double min() default Double.MIN_NORMAL; + double max() default Double.MAX_VALUE; + } + @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Comment {} + + public static class HiddenAnnotationExclusionStrategy implements ExclusionStrategy { + public boolean shouldSkipClass(Class clazz) { return false; } + public boolean shouldSkipField(FieldAttributes fieldAttributes) { + return fieldAttributes.getAnnotation(Entry.class) == null; + } + } +} \ No newline at end of file diff --git a/puzzle-base/src/main/java/net/puzzlemc/core/PuzzleCore.java b/puzzle-base/src/main/java/net/puzzlemc/core/PuzzleCore.java new file mode 100755 index 0000000..feb10da --- /dev/null +++ b/puzzle-base/src/main/java/net/puzzlemc/core/PuzzleCore.java @@ -0,0 +1,22 @@ +package net.puzzlemc.core; + +import net.puzzlemc.core.config.PuzzleConfig; +import net.puzzlemc.core.util.UpdateChecker; +import net.fabricmc.api.ClientModInitializer; + +public class PuzzleCore implements ClientModInitializer { + + public final static String version = "Puzzle A1"; + public final static String name = "Puzzle"; + public final static String id = "puzzle"; + public final static String website = "https://github.com/TeamMidnightDust/Puzzle"; + public static String updateURL = website + "download"; + + public final static String UPDATE_URL = "https://raw.githubusercontent.com/TeamMidnightDust/Puzzle/main/puzzle_versions.json"; + + @Override + public void onInitializeClient() { + PuzzleConfig.init(id, PuzzleConfig.class); + if (PuzzleConfig.checkUpdates) UpdateChecker.init(); + } +} diff --git a/puzzle-base/src/main/java/net/puzzlemc/core/config/PuzzleConfig.java b/puzzle-base/src/main/java/net/puzzlemc/core/config/PuzzleConfig.java new file mode 100755 index 0000000..eb20cc1 --- /dev/null +++ b/puzzle-base/src/main/java/net/puzzlemc/core/config/PuzzleConfig.java @@ -0,0 +1,19 @@ +package net.puzzlemc.core.config; + +import eu.midnightdust.lib.config.MidnightConfig; + +public class PuzzleConfig extends MidnightConfig { + @Entry public static boolean debugMessages = false; + + @Entry public static boolean checkUpdates = true; + @Entry public static boolean showPuzzleInfo = true; + @Entry public static boolean resourcepackSplashScreen = true; + @Entry public static boolean randomEntityTextures = true; + @Entry public static boolean customRenderLayers = true; + @Entry public static boolean unlimitedRotations = true; + @Entry public static boolean biggerModels = true; + + @Entry public static int backgroundColor = 15675965; + @Entry public static int progressBarColor = 16777215; + @Entry public static int progressFrameColor = 16777215; +} diff --git a/puzzle-base/src/main/java/net/puzzlemc/core/mixin/MixinDebugHud.java b/puzzle-base/src/main/java/net/puzzlemc/core/mixin/MixinDebugHud.java new file mode 100755 index 0000000..1ea775d --- /dev/null +++ b/puzzle-base/src/main/java/net/puzzlemc/core/mixin/MixinDebugHud.java @@ -0,0 +1,38 @@ +package net.puzzlemc.core.mixin; + +import com.mojang.blaze3d.platform.GlDebugInfo; +import net.puzzlemc.core.PuzzleCore; +import net.puzzlemc.core.config.PuzzleConfig; +import net.puzzlemc.core.util.UpdateChecker; +import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.hud.DebugHud; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.List; + +@Mixin(DebugHud.class) +public class MixinDebugHud extends DrawableHelper { + @Inject(at = @At("RETURN"), method = "getRightText", cancellable = true) + private void puzzle$getRightText(CallbackInfoReturnable> cir) { + if (PuzzleConfig.showPuzzleInfo) { + List entries = cir.getReturnValue(); + String message; + if (UpdateChecker.isUpToDate) { + message = "Puzzle is up to date (" + PuzzleCore.version + ")"; + } else { + message = "Puzzle is outdated (" + PuzzleCore.version + " -> " + UpdateChecker.latestVersion + ")"; + } + for (int i = 0; i < entries.size(); i++) { + String str = entries.get(i); + + if (str.startsWith(GlDebugInfo.getVersion())) { + entries.add(i + 1, message); + break; + } + } + } + } +} diff --git a/puzzle-base/src/main/java/net/puzzlemc/core/mixin/MixinTitleScreen.java b/puzzle-base/src/main/java/net/puzzlemc/core/mixin/MixinTitleScreen.java new file mode 100755 index 0000000..1bd4d20 --- /dev/null +++ b/puzzle-base/src/main/java/net/puzzlemc/core/mixin/MixinTitleScreen.java @@ -0,0 +1,75 @@ +package net.puzzlemc.core.mixin; + +import net.puzzlemc.core.PuzzleCore; +import net.puzzlemc.core.config.PuzzleConfig; +import net.puzzlemc.core.util.UpdateChecker; +import net.minecraft.client.gui.screen.*; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Util; +import net.minecraft.util.math.MathHelper; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Objects; + +@Mixin(TitleScreen.class) +public class MixinTitleScreen extends Screen { + + @Shadow @Final private boolean doBackgroundFade; + @Shadow private long backgroundFadeStart; + private Text puzzleText; + private int puzzleTextWidth; + + protected MixinTitleScreen(Text title) { + super(title); + } + @Inject(at = @At("TAIL"), method = "init") + private void puzzle$init(CallbackInfo ci) { + if (UpdateChecker.isUpToDate) { + puzzleText = Text.of(PuzzleCore.version); + } + else { + puzzleText = new TranslatableText("").append(Text.of(PuzzleCore.version + " | ")).append(new TranslatableText("puzzle.text.update_available")); + this.puzzleTextWidth = this.textRenderer.getWidth(puzzleText); + } + } + + @Inject(at = @At("TAIL"), method = "render") + private void puzzle$render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) { + if (PuzzleConfig.showPuzzleInfo) { + float f = this.doBackgroundFade ? (float) (Util.getMeasuringTimeMs() - this.backgroundFadeStart) / 1000.0F : 1.0F; + float g = this.doBackgroundFade ? MathHelper.clamp(f - 1.0F, 0.0F, 1.0F) : 1.0F; + int l = MathHelper.ceil(g * 255.0F) << 24; + textRenderer.drawWithShadow(matrices, puzzleText,2,this.height - 20, 16777215 | l); + if (mouseX > 2 && mouseX < 2 + this.puzzleTextWidth && mouseY > this.height - 20 && mouseY < this.height - 10) { + fill(matrices, 2, this.height - 11, 2 + this.puzzleTextWidth, this.height-10, 16777215 | l); + } + } + } + + private void confirmLink(boolean open) { + if (open) { + Util.getOperatingSystem().open(PuzzleCore.updateURL); + } + Objects.requireNonNull(this.client).openScreen(this); + } + + @Inject(at = @At("HEAD"), method = "mouseClicked",cancellable = true) + private void puzzle$mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable cir) { + if (mouseX > 2 && mouseX < (double)(2 + this.puzzleTextWidth) && mouseY > (double)(this.height - 20) && mouseY < (double)this.height-10) { + if (Objects.requireNonNull(this.client).options.chatLinksPrompt) { + this.client.openScreen(new ConfirmChatLinkScreen(this::confirmLink, PuzzleCore.updateURL, true)); + } else { + Util.getOperatingSystem().open(PuzzleCore.updateURL); + } + cir.setReturnValue(false); + } + } +} diff --git a/puzzle-base/src/main/java/net/puzzlemc/core/util/ColorUtil.java b/puzzle-base/src/main/java/net/puzzlemc/core/util/ColorUtil.java new file mode 100755 index 0000000..d5a6266 --- /dev/null +++ b/puzzle-base/src/main/java/net/puzzlemc/core/util/ColorUtil.java @@ -0,0 +1,17 @@ +package net.puzzlemc.core.util; + +import java.awt.*; + +public class ColorUtil { + /** + * @credit https://stackoverflow.com/questions/4129666/how-to-convert-hex-to-rgb-using-java + * @param colorStr e.g. "FFFFFF" + * @return + */ + public static Color hex2Rgb(String colorStr) { + return new Color( + Integer.valueOf( colorStr.substring( 0, 2 ), 16 ), + Integer.valueOf( colorStr.substring( 2, 4 ), 16 ), + Integer.valueOf( colorStr.substring( 4, 6 ), 16 )); + } +} diff --git a/puzzle-base/src/main/java/net/puzzlemc/core/util/UpdateChecker.java b/puzzle-base/src/main/java/net/puzzlemc/core/util/UpdateChecker.java new file mode 100755 index 0000000..44677bf --- /dev/null +++ b/puzzle-base/src/main/java/net/puzzlemc/core/util/UpdateChecker.java @@ -0,0 +1,55 @@ +package net.puzzlemc.core.util; + +import com.google.common.reflect.TypeToken; +import com.google.gson.Gson; +import net.puzzlemc.core.PuzzleCore; +import net.minecraft.client.MinecraftClient; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.lang.reflect.Type; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.*; +import java.util.concurrent.CompletableFuture; + + +public class UpdateChecker { + private static final Gson GSON = new Gson(); + private static final String minecraftVersion = MinecraftClient.getInstance().getGame().getVersion().getId(); + public static final Logger logger = LogManager.getLogger(PuzzleCore.name); + + public static final Type UPDATE_TYPE_TOKEN = new TypeToken>(){}.getType(); + public static String latestVersion; + public static boolean isUpToDate = true; + + public static void init() { + CompletableFuture.supplyAsync(() -> { + try (Reader reader = new InputStreamReader(new URL(PuzzleCore.UPDATE_URL).openStream())) { + return GSON.>fromJson(reader, UPDATE_TYPE_TOKEN); + } catch (MalformedURLException error) { + logger.log(Level.ERROR, "Unable to check for updates because of connection problems: " + error.getMessage()); + } catch (IOException error) { + logger.log(Level.ERROR, "Unable to check for updates because of an I/O Exception: " + error.getMessage()); + } + + return null; + }).thenAcceptAsync(versionMap -> { + if (versionMap != null && versionMap.containsKey(minecraftVersion)) { + latestVersion = versionMap.get(minecraftVersion); + if (!latestVersion.equals(minecraftVersion)) { + isUpToDate = false; + PuzzleCore.updateURL = PuzzleCore.website + "download/" + latestVersion.replace(PuzzleCore.name + " ",""); + logger.log(Level.INFO, "There is a newer version of "+ PuzzleCore.name +" available: " + latestVersion); + logger.log(Level.INFO, "Please update immediately!"); + } + } else { + logger.log(Level.WARN, "A problem with the database occured, could not check for updates."); + } + }, MinecraftClient.getInstance()); + } +} \ No newline at end of file diff --git a/puzzle-base/src/main/resources/assets/puzzle/icon.png b/puzzle-base/src/main/resources/assets/puzzle/icon.png new file mode 100755 index 0000000..c170db5 Binary files /dev/null and b/puzzle-base/src/main/resources/assets/puzzle/icon.png differ diff --git a/puzzle-base/src/main/resources/assets/puzzle/lang/en_us.json b/puzzle-base/src/main/resources/assets/puzzle/lang/en_us.json new file mode 100755 index 0000000..06a6372 --- /dev/null +++ b/puzzle-base/src/main/resources/assets/puzzle/lang/en_us.json @@ -0,0 +1,17 @@ +{ + "puzzle.text.update_available":"An update is available!", + "puzzle.screen.title":"Puzzle Settings", + "puzzle.page.graphics":"Graphics Settings", + "puzzle.page.resources":"Resource Settings", + "puzzle.page.performance":"Performance Settings", + "puzzle.page.misc":"Miscellaneous Settings", + "puzzle.option.ctm":"Connected Textures", + "puzzle.option.inside_ctm":"Connect Inside Textures", + "puzzle.midnightconfig.title":"Title", + "puzzle.midnightconfig.showPuzzleInfo":"Show Puzzle Info", + "puzzle.midnightconfig.showPuzzleInfo.tooltip":"Show Puzzle Info", + "test.midnightconfig.title":"I am a title", + "test.midnightconfig.text":"I am a comment *u*", + "test.midnightconfig.showInfo":"Show Info", + "test.midnightconfig.showInfo.tooltip":"Show more information" +} diff --git a/puzzle-base/src/main/resources/fabric.mod.json b/puzzle-base/src/main/resources/fabric.mod.json new file mode 100755 index 0000000..1c7e434 --- /dev/null +++ b/puzzle-base/src/main/resources/fabric.mod.json @@ -0,0 +1,40 @@ +{ + "schemaVersion": 1, + "id": "puzzle-base", + "version": "${version}", + + "name": "Puzzle", + "description": "Unites optifine replacement mods in a clean & vanilla-style gui", + "authors": [ + "Motschen", + "TeamMidnightDust" + ], + "contact": { + "homepage": "https://www.midnightdust.eu/", + "sources": "https://github.com/TeamMidnightDust/Puzzle", + "issues": "https://github.com/TeamMidnightDust/Puzzle/issues" + }, + + "license": "MIT", + "icon": "assets/puzzle/icon.png", + + "environment": "client", + "entrypoints": { + "client": [ + "net.puzzlemc.core.PuzzleCore" + ] + }, + "custom": { + "modmenu": { + "parent": "puzzle-core" + } + }, + + "mixins": [ + "puzzle-base.mixins.json" + ], + + "depends": { + "fabric": "*" + } +} diff --git a/puzzle-base/src/main/resources/puzzle-base.mixins.json b/puzzle-base/src/main/resources/puzzle-base.mixins.json new file mode 100755 index 0000000..8fd600b --- /dev/null +++ b/puzzle-base/src/main/resources/puzzle-base.mixins.json @@ -0,0 +1,12 @@ +{ + "required": true, + "package": "net.puzzlemc.core.mixin", + "compatibilityLevel": "JAVA_8", + "client": [ + "MixinTitleScreen", + "MixinDebugHud" + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/puzzle-blocks/build.gradle b/puzzle-blocks/build.gradle new file mode 100755 index 0000000..e4d8604 --- /dev/null +++ b/puzzle-blocks/build.gradle @@ -0,0 +1,4 @@ +archivesBaseName = "puzzle-blocks" +dependencies { + api project(":puzzle-base") +} diff --git a/puzzle-blocks/src/main/java/net/puzzlemc/blocks/PuzzleBlocks.java b/puzzle-blocks/src/main/java/net/puzzlemc/blocks/PuzzleBlocks.java new file mode 100755 index 0000000..3319ebe --- /dev/null +++ b/puzzle-blocks/src/main/java/net/puzzlemc/blocks/PuzzleBlocks.java @@ -0,0 +1,87 @@ +package net.puzzlemc.blocks; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.fabric.api.resource.ResourceManagerHelper; +import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; +import net.fabricmc.fabric.impl.blockrenderlayer.BlockRenderLayerMapImpl; +import net.minecraft.block.Block; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.resource.ResourceManager; +import net.minecraft.resource.ResourceType; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; +import net.puzzlemc.core.config.PuzzleConfig; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.InputStream; +import java.util.Arrays; +import java.util.Properties; + +public class PuzzleBlocks implements ClientModInitializer { + Logger LOGGER = LogManager.getLogger("puzzle-blocks"); + + public void onInitializeClient() { + ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() { + @Override + public Identifier getFabricId() { + return new Identifier("puzzle", "blocks"); + } + + @Override + public void reload(ResourceManager manager) { + if (PuzzleConfig.customRenderLayers) { + for (Identifier id : manager.findResources("optifine", path -> path.contains("block.properties"))) { + try (InputStream stream = manager.getResource(id).getInputStream()) { + Properties properties = new Properties(); + properties.load(stream); + + if (properties.get("layer.solid") != null) { + String[] solid_blocks = properties.get("layer.solid").toString().split(" "); + Arrays.stream(solid_blocks).iterator().forEachRemaining(string -> { + if (PuzzleConfig.debugMessages) LOGGER.info(string + " -> solid"); + Block block = Registry.BLOCK.getOrEmpty(Identifier.tryParse(string)).get(); + if (Registry.BLOCK.getOrEmpty(Identifier.tryParse(string)).isPresent()) { + BlockRenderLayerMapImpl.INSTANCE.putBlock(block, RenderLayer.getSolid()); + } + }); + } + if (properties.get("layer.cutout") != null) { + String[] solid_blocks = properties.get("layer.cutout").toString().split(" "); + Arrays.stream(solid_blocks).iterator().forEachRemaining(string -> { + if (PuzzleConfig.debugMessages) LOGGER.info(string + " -> cutout"); + Block block = Registry.BLOCK.getOrEmpty(Identifier.tryParse(string)).get(); + if (Registry.BLOCK.getOrEmpty(Identifier.tryParse(string)).isPresent()) { + BlockRenderLayerMapImpl.INSTANCE.putBlock(block, RenderLayer.getCutout()); + } + }); + } + if (properties.get("layer.cutout_mipped") != null) { + String[] solid_blocks = properties.get("layer.cutout_mipped").toString().split(" "); + Arrays.stream(solid_blocks).iterator().forEachRemaining(string -> { + if (PuzzleConfig.debugMessages) LOGGER.info(string + " -> cutout_mipped"); + Block block = Registry.BLOCK.getOrEmpty(Identifier.tryParse(string)).get(); + if (Registry.BLOCK.getOrEmpty(Identifier.tryParse(string)).isPresent()) { + BlockRenderLayerMapImpl.INSTANCE.putBlock(block, RenderLayer.getCutoutMipped()); + } + }); + } + if (properties.get("layer.translucent") != null) { + String[] solid_blocks = properties.get("layer.translucent").toString().split(" "); + Arrays.stream(solid_blocks).iterator().forEachRemaining(string -> { + if (PuzzleConfig.debugMessages) LOGGER.info(string + " -> translucent"); + Block block = Registry.BLOCK.getOrEmpty(Identifier.tryParse(string)).get(); + if (Registry.BLOCK.getOrEmpty(Identifier.tryParse(string)).isPresent()) { + BlockRenderLayerMapImpl.INSTANCE.putBlock(block, RenderLayer.getTranslucent()); + } + }); + } + } catch (Exception e) { + LogManager.getLogger("Puzzle").error("Error occurred while loading block.properties " + id.toString(), e); + } + } + } + } + }); + } +} diff --git a/puzzle-blocks/src/main/resources/assets/puzzle/icon.png b/puzzle-blocks/src/main/resources/assets/puzzle/icon.png new file mode 100755 index 0000000..c170db5 Binary files /dev/null and b/puzzle-blocks/src/main/resources/assets/puzzle/icon.png differ diff --git a/puzzle-blocks/src/main/resources/fabric.mod.json b/puzzle-blocks/src/main/resources/fabric.mod.json new file mode 100755 index 0000000..60e1023 --- /dev/null +++ b/puzzle-blocks/src/main/resources/fabric.mod.json @@ -0,0 +1,36 @@ +{ + "schemaVersion": 1, + "id": "puzzle-blocks", + "version": "${version}", + + "name": "Puzzle Blocks", + "description": "Lets resourcepacks change render layers of blocks", + "authors": [ + "Motschen", + "TeamMidnightDust" + ], + "contact": { + "homepage": "https://www.midnightdust.eu/", + "sources": "https://github.com/TeamMidnightDust/Puzzle", + "issues": "https://github.com/TeamMidnightDust/Puzzle/issues" + }, + + "license": "MIT", + "icon": "assets/puzzle/icon.png", + + "environment": "client", + "entrypoints": { + "client": [ + "net.puzzlemc.blocks.PuzzleBlocks" + ] + }, + "custom": { + "modmenu": { + "parent": "puzzle" + } + }, + + "depends": { + "fabric": "*" + } +} diff --git a/puzzle-gui/build.gradle b/puzzle-gui/build.gradle new file mode 100755 index 0000000..a37178e --- /dev/null +++ b/puzzle-gui/build.gradle @@ -0,0 +1,33 @@ +archivesBaseName = "puzzle-gui" + +repositories { + maven { url "https://maven.terraformersmc.com/releases" } + maven { + name = 'AperLambda' + url = 'https://aperlambda.github.io/maven' + } + mavenCentral() + flatDir { + dirs 'local_maven' + } +} + +dependencies { + api project(":puzzle-base") + api project(":puzzle-splashscreen") + + api ("com.terraformersmc:modmenu:${project.mod_menu_version}") + modImplementation ("eu.midnightdust:cullleaves:${project.cull_leaves_version}") + modImplementation ("dev.lambdaurora:lambdynamiclights:${project.ldl_version}") + modImplementation ("dev.lambdaurora:lambdabettergrass:${project.lbg_version}") + modImplementation ("com.github.IrisShaders:Iris:${project.iris_version}") + + //modImplementation "dev.lambdaurora:spruceui:${project.spruceui_version}" // Needed for Lambda's mods + modImplementation("org.aperlambda:lambdajcommon:1.8.1") { + exclude group: 'com.google.code.gson' + exclude group: 'com.google.guava' + } +// modImplementation ("com.github.PepperCode1:ConnectedTexturesMod-Fabric:${project.ctmf_version}") { +// exclude module: "modmenu" +// } +} diff --git a/puzzle-gui/local_maven/cullleaves-2.2.0.jar b/puzzle-gui/local_maven/cullleaves-2.2.0.jar new file mode 100755 index 0000000..c9b0696 Binary files /dev/null and b/puzzle-gui/local_maven/cullleaves-2.2.0.jar differ diff --git a/puzzle-gui/local_maven/lambdabettergrass-1.1.2+21w20a.jar b/puzzle-gui/local_maven/lambdabettergrass-1.1.2+21w20a.jar new file mode 100755 index 0000000..e148e5d Binary files /dev/null and b/puzzle-gui/local_maven/lambdabettergrass-1.1.2+21w20a.jar differ diff --git a/puzzle-gui/local_maven/lambdynamiclights-2.0.0+21w20a.jar b/puzzle-gui/local_maven/lambdynamiclights-2.0.0+21w20a.jar new file mode 100755 index 0000000..a649e79 Binary files /dev/null and b/puzzle-gui/local_maven/lambdynamiclights-2.0.0+21w20a.jar differ diff --git a/puzzle-gui/src/main/java/net/puzzlemc/gui/PuzzleApi.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/PuzzleApi.java new file mode 100755 index 0000000..26189a9 --- /dev/null +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/PuzzleApi.java @@ -0,0 +1,39 @@ +package net.puzzlemc.gui; + +import net.puzzlemc.core.config.PuzzleConfig; +import net.puzzlemc.gui.screen.widget.PuzzleWidget; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.ArrayList; +import java.util.List; + +public class PuzzleApi { + private static Logger LOGGER = LogManager.getLogger("puzzle-gui"); + + public static List GRAPHICS_OPTIONS = new ArrayList<>(); + public static List MISC_OPTIONS = new ArrayList<>(); + public static List PERFORMANCE_OPTIONS = new ArrayList<>(); + public static List RESOURCE_OPTIONS = new ArrayList<>(); + + public static void addToGraphicsOptions(PuzzleWidget button) { + GRAPHICS_OPTIONS.add(button); + if (PuzzleConfig.debugMessages) LOGGER.info(button.descriptionText.asString() + " -> Graphics Options"); + } + public static void addToMiscOptions(PuzzleWidget button) { + MISC_OPTIONS.add(button); + if (PuzzleConfig.debugMessages) LOGGER.info(button.descriptionText.asString() + " -> Misc Options"); + } + public static void addToPerformanceOptions(PuzzleWidget button) { + PERFORMANCE_OPTIONS.add(button); + if (PuzzleConfig.debugMessages) LOGGER.info(button.descriptionText.asString() + "- > Performance Options"); + } + public static void addToResourceOptions(PuzzleWidget button) { + RESOURCE_OPTIONS.add(button); + if (PuzzleConfig.debugMessages) LOGGER.info(button.descriptionText.asString() + " -> Resource Options"); + } + @Deprecated public static void addToTextureOptions(PuzzleWidget button) { + RESOURCE_OPTIONS.add(button); + if (PuzzleConfig.debugMessages) LOGGER.info(button.descriptionText.asString() + " -> LEGACY Texture Options"); + } +} diff --git a/puzzle-gui/src/main/java/net/puzzlemc/gui/PuzzleClient.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/PuzzleClient.java new file mode 100755 index 0000000..c314c45 --- /dev/null +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/PuzzleClient.java @@ -0,0 +1,109 @@ +package net.puzzlemc.gui; + +import dev.lambdaurora.lambdabettergrass.LBGConfig; +import dev.lambdaurora.lambdabettergrass.LambdaBetterGrass; +import dev.lambdaurora.lambdynlights.DynamicLightsConfig; +import dev.lambdaurora.lambdynlights.LambDynLights; +import eu.midnightdust.cullleaves.config.CullLeavesConfig; +import net.puzzlemc.core.config.PuzzleConfig; +import net.puzzlemc.gui.screen.widget.PuzzleWidget; +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.MinecraftClient; +import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; +import net.minecraft.util.Formatting; +import net.puzzlemc.splashscreen.PuzzleSplashScreen; +//import team.chisel.ctm.client.CTMClient; +//import team.chisel.ctm.client.config.ConfigManager; + +public class PuzzleClient implements ClientModInitializer { + + public final static String id = "puzzle"; + public static final Text YES = new TranslatableText("gui.yes").formatted(Formatting.GREEN); + public static final Text NO = new TranslatableText("gui.no").formatted(Formatting.RED); + + @Override + public void onInitializeClient() { + PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.of("Puzzle"))); + PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.of("Check for Updates"), (button) -> button.setMessage(PuzzleConfig.checkUpdates ? YES : NO), (button) -> { + PuzzleConfig.checkUpdates = !PuzzleConfig.checkUpdates; + PuzzleConfig.write(id); + })); + PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.of("Show Puzzle version info"), (button) -> button.setMessage(PuzzleConfig.showPuzzleInfo ? YES : NO), (button) -> { + PuzzleConfig.showPuzzleInfo = !PuzzleConfig.showPuzzleInfo; + PuzzleConfig.write(id); + })); + PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("Puzzle"))); + if (FabricLoader.getInstance().isModLoaded("puzzle-splashscreen")) { + PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("Use resourcepack splash screen "), (button) -> button.setMessage(PuzzleConfig.resourcepackSplashScreen ? YES : NO), (button) -> { + PuzzleConfig.resourcepackSplashScreen = !PuzzleConfig.resourcepackSplashScreen; + PuzzleConfig.write(id); + PuzzleSplashScreen.resetColors(); + MinecraftClient.getInstance().getTextureManager().registerTexture(PuzzleSplashScreen.LOGO, new PuzzleSplashScreen.LogoTexture()); + })); + } + if (FabricLoader.getInstance().isModLoaded("puzzle-randomentities")) { + PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("Random Entity Textures"), (button) -> button.setMessage(PuzzleConfig.randomEntityTextures ? YES : NO), (button) -> { + PuzzleConfig.randomEntityTextures = !PuzzleConfig.randomEntityTextures; + PuzzleConfig.write(id); + })); + } + if (FabricLoader.getInstance().isModLoaded("puzzle-models")) { + PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("Unlimited Model Rotations"), (button) -> button.setMessage(PuzzleConfig.unlimitedRotations ? YES : NO), (button) -> { + PuzzleConfig.unlimitedRotations = !PuzzleConfig.unlimitedRotations; + PuzzleConfig.write(id); + })); + PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("Bigger Custom Models"), (button) -> button.setMessage(PuzzleConfig.biggerModels ? YES : NO), (button) -> { + PuzzleConfig.biggerModels = !PuzzleConfig.biggerModels; + PuzzleConfig.write(id); + })); + } + if (FabricLoader.getInstance().isModLoaded("puzzle-blocks")) { + PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("Render Layer Overwrites"), (button) -> button.setMessage(PuzzleConfig.customRenderLayers ? YES : NO), (button) -> { + PuzzleConfig.customRenderLayers = !PuzzleConfig.customRenderLayers; + PuzzleConfig.write(id); + })); + } + + if (FabricLoader.getInstance().isModLoaded("cullleaves")) { + PuzzleApi.addToPerformanceOptions(new PuzzleWidget(Text.of("CullLeaves"))); + PuzzleApi.addToPerformanceOptions(new PuzzleWidget(Text.of("Cull Leaves"), (button) -> button.setMessage(CullLeavesConfig.enabled ? YES : NO), (button) -> { + CullLeavesConfig.enabled = !CullLeavesConfig.enabled; + CullLeavesConfig.write("cullleaves"); + MinecraftClient.getInstance().worldRenderer.reload(); + })); + } + + if (FabricLoader.getInstance().isModLoaded("lambdynlights")) { + DynamicLightsConfig ldlConfig = LambDynLights.get().config; + PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.of("LambDynamicLights"))); + PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("lambdynlights.option.mode"), (button) -> button.setMessage(ldlConfig.getDynamicLightsMode().getTranslatedText()), (button) -> ldlConfig.setDynamicLightsMode(ldlConfig.getDynamicLightsMode().next()))); + PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("").append("DynLights: ").append(new TranslatableText("lambdynlights.option.entities")), (button) -> button.setMessage(ldlConfig.hasEntitiesLightSource() ? YES : NO), (button) -> ldlConfig.setEntitiesLightSource(!ldlConfig.hasEntitiesLightSource()))); + PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("").append("DynLights: ").append(new TranslatableText("lambdynlights.option.block_entities")), (button) -> button.setMessage(ldlConfig.hasBlockEntitiesLightSource() ? YES : NO), (button) -> ldlConfig.setBlockEntitiesLightSource(!ldlConfig.hasBlockEntitiesLightSource()))); + PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("").append("DynLights: ").append(new TranslatableText("entity.minecraft.creeper")), (button) -> button.setMessage(ldlConfig.getCreeperLightingMode().getTranslatedText()), (button) -> ldlConfig.setCreeperLightingMode(ldlConfig.getCreeperLightingMode().next()))); + PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("").append("DynLights: ").append(new TranslatableText("block.minecraft.tnt")), (button) -> button.setMessage(ldlConfig.getTntLightingMode().getTranslatedText()), (button) -> ldlConfig.setTntLightingMode(ldlConfig.getTntLightingMode().next()))); + PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("").append("DynLights: ").append(new TranslatableText("lambdynlights.option.water_sensitive")), (button) -> button.setMessage(ldlConfig.hasWaterSensitiveCheck() ? YES : NO), (button) -> ldlConfig.setWaterSensitiveCheck(!ldlConfig.hasWaterSensitiveCheck()))); + } +// if (FabricLoader.getInstance().isModLoaded("ctm")) { +// PuzzleApi.addToTextureOptions(new PuzzleWidget(Text.of("ConnectedTexturesMod for Fabric"))); +// ConfigManager ctmfConfigManager = CTMClient.getConfigManager(); +// ConfigManager.Config ctmfConfig = CTMClient.getConfigManager().getConfig(); +// PuzzleApi.addToTextureOptions(new PuzzleWidget(new TranslatableText("puzzle.option.ctm"), (button) -> button.setMessage(ctmfConfig.disableCTM ? NO : YES), (button) -> { +// ctmfConfig.disableCTM = !ctmfConfig.disableCTM; +// ctmfConfigManager.onConfigChange(); +// })); +// PuzzleApi.addToTextureOptions(new PuzzleWidget(new TranslatableText("puzzle.option.inside_ctm"), (button) -> button.setMessage(ctmfConfig.connectInsideCTM ? YES : NO), (button) -> { +// ctmfConfig.connectInsideCTM = !ctmfConfig.connectInsideCTM; +// ctmfConfigManager.onConfigChange(); +// })); +// } + + if (FabricLoader.getInstance().isModLoaded("lambdabettergrass")) { + LBGConfig lbgConfig = LambdaBetterGrass.get().config; + PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.of("LambdaBetterGrass"))); + PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("lambdabettergrass.option.mode"), (button) -> button.setMessage(lbgConfig.getMode().getTranslatedText()), (button) -> lbgConfig.setMode(lbgConfig.getMode().next()))); + PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("lambdabettergrass.option.better_snow"), (button) -> button.setMessage(lbgConfig.hasBetterLayer() ? YES : NO), (button) -> lbgConfig.setBetterLayer(!lbgConfig.hasBetterLayer()))); + } + } +} diff --git a/puzzle-gui/src/main/java/net/puzzlemc/gui/config/ModMenuIntegration.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/config/ModMenuIntegration.java new file mode 100755 index 0000000..543b41a --- /dev/null +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/config/ModMenuIntegration.java @@ -0,0 +1,28 @@ +package net.puzzlemc.gui.config; + +import com.google.common.collect.ImmutableMap; +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; +import net.puzzlemc.gui.screen.PuzzleOptionsScreen; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import java.util.Map; + +@Environment(EnvType.CLIENT) +public class ModMenuIntegration implements ModMenuApi { + + // Used to set the config screen for all modules // +// @Override +// public Map> getProvidedConfigScreenFactories() { +// Map> map = ImmutableMap.of(); +// map.put("puzzle",PuzzleOptionsScreen::new); +// map.put("puzzle-gui",PuzzleOptionsScreen::new); +// map.put("puzzle-blocks",PuzzleOptionsScreen::new); +// map.put("puzzle-base",PuzzleOptionsScreen::new); +// map.put("puzzle-models",PuzzleOptionsScreen::new); +// map.put("puzzle-randomentities",PuzzleOptionsScreen::new); +// map.put("puzzle-splashscreen",PuzzleOptionsScreen::new); +// return map; +// } +} \ No newline at end of file diff --git a/src/main/java/eu/midnightdust/puzzle/mixin/MixinOptionsScreen.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/mixin/MixinOptionsScreen.java similarity index 61% rename from src/main/java/eu/midnightdust/puzzle/mixin/MixinOptionsScreen.java rename to puzzle-gui/src/main/java/net/puzzlemc/gui/mixin/MixinOptionsScreen.java index e98b8f8..e3de779 100755 --- a/src/main/java/eu/midnightdust/puzzle/mixin/MixinOptionsScreen.java +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/mixin/MixinOptionsScreen.java @@ -1,8 +1,8 @@ -package eu.midnightdust.puzzle.mixin; +package net.puzzlemc.gui.mixin; -import eu.midnightdust.puzzle.screen.PuzzleOptionsScreen; +import net.puzzlemc.gui.screen.PuzzleOptionsScreen; import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.options.OptionsScreen; +import net.minecraft.client.gui.screen.option.OptionsScreen; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.text.Text; import net.minecraft.text.TranslatableText; @@ -11,6 +11,8 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import java.util.Objects; + @Mixin(OptionsScreen.class) public class MixinOptionsScreen extends Screen { @@ -21,9 +23,7 @@ public class MixinOptionsScreen extends Screen { @Inject(at = @At("TAIL"),method = "init") public void init(CallbackInfo ci) { PuzzleOptionsScreen puzzleScreen = new PuzzleOptionsScreen(this); - this.addButton(new ButtonWidget(this.width / 2 - 155, this.height / 6 + 144 - 6, 150, 20, new TranslatableText("puzzle.screen.title").append("..."), (button) -> { - this.client.openScreen(puzzleScreen); - })); + this.addDrawableChild(new ButtonWidget(this.width / 2 - 155, this.height / 6 + 144 - 6, 150, 20, new TranslatableText("puzzle.screen.title").append("..."), (button) -> Objects.requireNonNull(this.client).openScreen(puzzleScreen))); } } diff --git a/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/IrisButton.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/IrisButton.java new file mode 100755 index 0000000..976dc72 --- /dev/null +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/IrisButton.java @@ -0,0 +1,18 @@ +package net.puzzlemc.gui.screen; + +import net.coderbot.iris.gui.screen.ShaderPackScreen; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.DrawableHelper; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.widget.ButtonWidget; + +import java.util.Objects; + +public class IrisButton extends DrawableHelper { + public static ButtonWidget getButton(int x, int y, int width, int height, Screen parent, MinecraftClient client) { + ShaderPackScreen shaderPackPage = new ShaderPackScreen(parent); + return new ButtonWidget(x, y, width, height, shaderPackPage.getTitle().copy().append("..."), (button) -> { + Objects.requireNonNull(client).openScreen(shaderPackPage); + }); + } +} diff --git a/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/LoadingScreenBackgrond.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/LoadingScreenBackgrond.java new file mode 100755 index 0000000..8194c45 --- /dev/null +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/LoadingScreenBackgrond.java @@ -0,0 +1,14 @@ +package net.puzzlemc.gui.screen; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.util.math.MatrixStack; + +public class LoadingScreenBackgrond { + public static void render(MinecraftClient client, MatrixStack matrices, int width, int height, float delta) { +// if (client.world != null) { +// LogManager.getLogManager().getLogger("Puzzle").info(client.world.getDimension().toString()); +// } +// client.getTextureManager().bindTexture(new Identifier("minecraft","optifine/gui/loading/background0.png")); +// DrawableHelper.drawTexture(matrices,0,0,width,height,0,0,width,height,width,height); + } +} diff --git a/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/PuzzleOptionsScreen.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/PuzzleOptionsScreen.java new file mode 100755 index 0000000..7e1e8bc --- /dev/null +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/PuzzleOptionsScreen.java @@ -0,0 +1,49 @@ +package net.puzzlemc.gui.screen; + +import net.fabricmc.loader.api.FabricLoader; +import net.puzzlemc.gui.screen.page.GraphicsPage; +import net.puzzlemc.gui.screen.page.MiscPage; +import net.puzzlemc.gui.screen.page.PerformancePage; +import net.puzzlemc.gui.screen.page.ResourcesPage; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.gui.screen.ScreenTexts; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.TranslatableText; + +import java.util.Objects; + +public class PuzzleOptionsScreen extends Screen { + + public PuzzleOptionsScreen(Screen parent) { + super(new TranslatableText("puzzle.screen.title")); + this.parent = parent; + } + private final Screen parent; + + @Override + protected void init() { + super.init(); + GraphicsPage graphicsPage = new GraphicsPage(this); + MiscPage miscPage = new MiscPage(this); + PerformancePage performancePage = new PerformancePage(this); + ResourcesPage resourcesPage = new ResourcesPage(this); + + this.addDrawableChild(new ButtonWidget(this.width / 2 - 155, this.height / 6 + 48 - 6, 150, 20, graphicsPage.getTitle().copy().append("..."), (button) -> Objects.requireNonNull(client).openScreen(graphicsPage))); + this.addDrawableChild(new ButtonWidget(this.width / 2 + 5, this.height / 6 + 48 - 6, 150, 20, resourcesPage.getTitle().copy().append("..."), (button) -> Objects.requireNonNull(client).openScreen(resourcesPage))); + this.addDrawableChild(new ButtonWidget(this.width / 2 - 155, this.height / 6 + 72 - 6, 150, 20, performancePage.getTitle().copy().append("..."), (button) -> Objects.requireNonNull(client).openScreen(performancePage))); + this.addDrawableChild(new ButtonWidget(this.width / 2 + 5, this.height / 6 + 72 - 6, 150, 20, miscPage.getTitle().copy().append("..."), (button) -> Objects.requireNonNull(client).openScreen(miscPage))); + if (FabricLoader.getInstance().isModLoaded("iris")) { + this.addDrawableChild(IrisButton.getButton(this.width / 2 - 155, this.height / 6 + 96 - 6, 150, 20, this, client)); + } + this.addDrawableChild(new ButtonWidget(this.width / 2 - 100, this.height / 6 + 168, 200, 20, ScreenTexts.DONE, (button) -> Objects.requireNonNull(client).openScreen(parent))); + } + + @Override + public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { + this.renderBackground(matrices); + + super.render(matrices, mouseX, mouseY, delta); + drawCenteredText(matrices, textRenderer, title, width/2, 15, 0xFFFFFF); + } +} diff --git a/src/main/java/eu/midnightdust/puzzle/screen/page/AbstractPuzzleOptionsPage.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/AbstractPuzzleOptionsPage.java similarity index 73% rename from src/main/java/eu/midnightdust/puzzle/screen/page/AbstractPuzzleOptionsPage.java rename to puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/AbstractPuzzleOptionsPage.java index f678e09..e410bfe 100755 --- a/src/main/java/eu/midnightdust/puzzle/screen/page/AbstractPuzzleOptionsPage.java +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/AbstractPuzzleOptionsPage.java @@ -1,7 +1,7 @@ -package eu.midnightdust.puzzle.screen.page; +package net.puzzlemc.gui.screen.page; -import eu.midnightdust.puzzle.screen.widget.PuzzleOptionListWidget; -import eu.midnightdust.puzzle.screen.widget.PuzzleWidget; +import net.puzzlemc.gui.screen.widget.PuzzleOptionListWidget; +import net.puzzlemc.gui.screen.widget.PuzzleWidget; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.ScreenTexts; import net.minecraft.client.gui.widget.ButtonWidget; @@ -26,13 +26,11 @@ public abstract class AbstractPuzzleOptionsPage extends Screen { protected void init() { this.list = new PuzzleOptionListWidget(this.client, this.width, this.height, 32, this.height - 32, 25); list.addAll(options); - this.children.add(this.list); + this.addSelectableChild(this.list); super.init(); - this.addButton(new ButtonWidget(this.width / 2 - 100, this.height - 28, 200, 20, ScreenTexts.DONE, (button) -> { - Objects.requireNonNull(client).openScreen(parent); - })); + this.addDrawableChild(new ButtonWidget(this.width / 2 - 100, this.height - 28, 200, 20, ScreenTexts.DONE, (button) -> Objects.requireNonNull(client).openScreen(parent))); } @Override diff --git a/src/main/java/eu/midnightdust/puzzle/screen/page/GraphicsPage.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/GraphicsPage.java similarity index 64% rename from src/main/java/eu/midnightdust/puzzle/screen/page/GraphicsPage.java rename to puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/GraphicsPage.java index 4ec396c..b629e98 100755 --- a/src/main/java/eu/midnightdust/puzzle/screen/page/GraphicsPage.java +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/GraphicsPage.java @@ -1,7 +1,6 @@ -package eu.midnightdust.puzzle.screen.page; +package net.puzzlemc.gui.screen.page; -import eu.midnightdust.puzzle.PuzzleApi; -import eu.midnightdust.puzzle.screen.page.AbstractPuzzleOptionsPage; +import net.puzzlemc.gui.PuzzleApi; import net.minecraft.client.gui.screen.Screen; import net.minecraft.text.TranslatableText; diff --git a/src/main/java/eu/midnightdust/puzzle/screen/page/MiscPage.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/MiscPage.java similarity index 74% rename from src/main/java/eu/midnightdust/puzzle/screen/page/MiscPage.java rename to puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/MiscPage.java index 53a254f..908b1f5 100755 --- a/src/main/java/eu/midnightdust/puzzle/screen/page/MiscPage.java +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/MiscPage.java @@ -1,6 +1,6 @@ -package eu.midnightdust.puzzle.screen.page; +package net.puzzlemc.gui.screen.page; -import eu.midnightdust.puzzle.PuzzleApi; +import net.puzzlemc.gui.PuzzleApi; import net.minecraft.client.gui.screen.Screen; import net.minecraft.text.TranslatableText; diff --git a/src/main/java/eu/midnightdust/puzzle/screen/page/PerformancePage.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/PerformancePage.java similarity index 76% rename from src/main/java/eu/midnightdust/puzzle/screen/page/PerformancePage.java rename to puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/PerformancePage.java index d1a5d44..00692c4 100755 --- a/src/main/java/eu/midnightdust/puzzle/screen/page/PerformancePage.java +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/PerformancePage.java @@ -1,6 +1,6 @@ -package eu.midnightdust.puzzle.screen.page; +package net.puzzlemc.gui.screen.page; -import eu.midnightdust.puzzle.PuzzleApi; +import net.puzzlemc.gui.PuzzleApi; import net.minecraft.client.gui.screen.Screen; import net.minecraft.text.TranslatableText; diff --git a/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/ResourcesPage.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/ResourcesPage.java new file mode 100755 index 0000000..a457b3d --- /dev/null +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/page/ResourcesPage.java @@ -0,0 +1,12 @@ +package net.puzzlemc.gui.screen.page; + +import net.puzzlemc.gui.PuzzleApi; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.text.TranslatableText; + +public class ResourcesPage extends AbstractPuzzleOptionsPage { + + public ResourcesPage(Screen parent) { + super(parent, new TranslatableText("puzzle.page.resources"), PuzzleApi.RESOURCE_OPTIONS); + } +} diff --git a/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/ButtonType.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/ButtonType.java new file mode 100755 index 0000000..0ddef07 --- /dev/null +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/ButtonType.java @@ -0,0 +1,5 @@ +package net.puzzlemc.gui.screen.widget; + +public enum ButtonType { + TEXT, BUTTON, SLIDER, TEXT_FIELD +} diff --git a/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/DummyButtonWidget.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/DummyButtonWidget.java new file mode 100755 index 0000000..f766e66 --- /dev/null +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/DummyButtonWidget.java @@ -0,0 +1,10 @@ +package net.puzzlemc.gui.screen.widget; + +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.text.Text; + +public class DummyButtonWidget extends ButtonWidget { + public DummyButtonWidget() { + super(-1,-1,0,0,Text.of(""),null); + } +} diff --git a/src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleButtonWidget.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleButtonWidget.java similarity index 91% rename from src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleButtonWidget.java rename to puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleButtonWidget.java index 455983f..f7f1d46 100755 --- a/src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleButtonWidget.java +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleButtonWidget.java @@ -1,4 +1,4 @@ -package eu.midnightdust.puzzle.screen.widget; +package net.puzzlemc.gui.screen.widget; import net.minecraft.client.gui.widget.ButtonWidget; import net.minecraft.client.util.math.MatrixStack; diff --git a/src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleOptionListWidget.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleOptionListWidget.java similarity index 56% rename from src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleOptionListWidget.java rename to puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleOptionListWidget.java index 4ce3377..a26a7f0 100755 --- a/src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleOptionListWidget.java +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleOptionListWidget.java @@ -1,4 +1,4 @@ -package eu.midnightdust.puzzle.screen.widget; +package net.puzzlemc.gui.screen.widget; import com.google.common.collect.ImmutableMap; import net.fabricmc.api.EnvType; @@ -6,8 +6,8 @@ import net.fabricmc.api.Environment; import net.minecraft.client.MinecraftClient; import net.minecraft.client.font.TextRenderer; import net.minecraft.client.gui.Element; -import net.minecraft.client.gui.widget.AbstractButtonWidget; -import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.Selectable; +import net.minecraft.client.gui.widget.ClickableWidget; import net.minecraft.client.gui.widget.ElementListWidget; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; @@ -26,23 +26,22 @@ public class PuzzleOptionListWidget extends ElementListWidget buttons) { - for (int i = 0; i < buttons.size(); ++i) { - PuzzleWidget button = buttons.get(i); - if (button.buttonType == ButtonType.BUTTON) { + for (PuzzleWidget button : buttons) { + if (button.buttonType == ButtonType.TEXT) { + this.addButton(new DummyButtonWidget(), button.descriptionText); + } else if (button.buttonType == ButtonType.BUTTON) { this.addButton(new PuzzleButtonWidget(this.width / 2 - 155 + 160, 0, 150, 20, button.buttonTextAction, button.onPress), button.descriptionText); - } - else if (button.buttonType == ButtonType.SLIDER) { - this.addButton(new PuzzleSliderWidget(button.min,button.max,this.width / 2 - 155 + 160, 0, 150, 20, ((TranslatableText) button.buttonText),1), button.descriptionText); - } - else if (button.buttonType == ButtonType.TEXT_FIELD) { - this.addButton(new PuzzleTextFieldWidget(textRenderer,this.width / 2 - 155 + 160, 0, 150, 20,null, button.buttonText), button.descriptionText); - } - else LogManager.getLogger("Puzzle").warn("Button " + button + " is missing the buttonType variable. This shouldn't happen!"); + } else if (button.buttonType == ButtonType.SLIDER) { + this.addButton(new PuzzleSliderWidget(button.min, button.max, this.width / 2 - 155 + 160, 0, 150, 20, ((TranslatableText) button.buttonText), 1), button.descriptionText); + } else if (button.buttonType == ButtonType.TEXT_FIELD) { + this.addButton(new PuzzleTextFieldWidget(textRenderer, this.width / 2 - 155 + 160, 0, 150, 20, null, button.buttonText), button.descriptionText); + } else + LogManager.getLogger("Puzzle").warn("Button " + button + " is missing the buttonType variable. This shouldn't happen!"); } } @@ -54,11 +53,11 @@ public class PuzzleOptionListWidget extends ElementListWidget getHoveredButton(double mouseX, double mouseY) { + public Optional getHoveredButton(double mouseX, double mouseY) { for (ButtonEntry buttonEntry : this.children()) { - for (AbstractButtonWidget abstractButtonWidget : buttonEntry.buttons) { - if (abstractButtonWidget.isMouseOver(mouseX, mouseY)) { - return Optional.of(abstractButtonWidget); + for (ClickableWidget widget : buttonEntry.buttons) { + if (widget.isMouseOver(mouseX, mouseY)) { + return Optional.of(widget); } } } @@ -67,15 +66,15 @@ public class PuzzleOptionListWidget extends ElementListWidget { private static final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer; - private final List buttons; - private final Map buttonsWithText; + private final List buttons; + private final Map buttonsWithText; - private ButtonEntry(ImmutableMap buttons) { + private ButtonEntry(ImmutableMap buttons) { this.buttons = buttons.keySet().asList(); this.buttonsWithText = buttons; } - public static ButtonEntry create(AbstractButtonWidget button, Text text) { + public static ButtonEntry create(ClickableWidget button, Text text) { return new ButtonEntry(ImmutableMap.of(button, text)); } @@ -83,12 +82,18 @@ public class PuzzleOptionListWidget extends ElementListWidget { button.y = y; button.render(matrices, mouseX, mouseY, tickDelta); - drawTextWithShadow(matrices,textRenderer, text,x+15,y+5,0xFFFFFF); + if (button instanceof DummyButtonWidget) drawCenteredText(matrices,textRenderer, text,x + 200,y+5,0xFFFFFF); + else drawTextWithShadow(matrices,textRenderer, text,x+15,y+5,0xFFFFFF); }); } public List children() { return buttons; } + + @Override + public List method_37025() { + return null; + } } } diff --git a/src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleSliderWidget.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleSliderWidget.java similarity index 89% rename from src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleSliderWidget.java rename to puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleSliderWidget.java index ca03c7e..f2c120d 100755 --- a/src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleSliderWidget.java +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleSliderWidget.java @@ -1,4 +1,4 @@ -package eu.midnightdust.puzzle.screen.widget; +package net.puzzlemc.gui.screen.widget; import net.minecraft.client.gui.widget.SliderWidget; import net.minecraft.text.LiteralText; @@ -19,7 +19,7 @@ public class PuzzleSliderWidget extends SliderWidget { @Override protected void updateMessage() { Text text = new LiteralText((int) (min + this.value * difference) + ""); - this.setMessage(new TranslatableText("label").append(": ").append((Text) text)); + this.setMessage(new TranslatableText("label").append(": ").append(text)); } @Override diff --git a/src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleTextFieldWidget.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleTextFieldWidget.java similarity index 77% rename from src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleTextFieldWidget.java rename to puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleTextFieldWidget.java index e872e36..7227bdd 100755 --- a/src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleTextFieldWidget.java +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleTextFieldWidget.java @@ -1,9 +1,7 @@ -package eu.midnightdust.puzzle.screen.widget; +package net.puzzlemc.gui.screen.widget; import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.widget.SliderWidget; import net.minecraft.client.gui.widget.TextFieldWidget; -import net.minecraft.text.LiteralText; import net.minecraft.text.Text; import net.minecraft.text.TranslatableText; import org.jetbrains.annotations.Nullable; diff --git a/src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleWidget.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleWidget.java similarity index 78% rename from src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleWidget.java rename to puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleWidget.java index f3f2a22..fba802a 100755 --- a/src/main/java/eu/midnightdust/puzzle/screen/widget/PuzzleWidget.java +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleWidget.java @@ -1,9 +1,9 @@ -package eu.midnightdust.puzzle.screen.widget; +package net.puzzlemc.gui.screen.widget; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; -import net.minecraft.client.gui.widget.AbstractButtonWidget; import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.widget.ClickableWidget; import net.minecraft.text.Text; import net.minecraft.text.TranslatableText; @@ -17,6 +17,15 @@ public class PuzzleWidget { public ButtonWidget.PressAction onPress; public PuzzleWidget.SaveAction onSave; + /** + * Puzzle Text Widget Container + * @param descriptionText The text you want to display. + */ + public PuzzleWidget(Text descriptionText) { + this.buttonType = ButtonType.TEXT; + this.descriptionText = descriptionText; + } + /** * Puzzle Button Widget Container * @param descriptionText Tells the user what the option does. @@ -49,10 +58,10 @@ public class PuzzleWidget { } @Environment(EnvType.CLIENT) public interface SaveAction { - void onSave(AbstractButtonWidget button); + void onSave(ClickableWidget button); } @Environment(EnvType.CLIENT) public interface TextAction { - void setTitle(AbstractButtonWidget button); + void setTitle(ClickableWidget button); } } diff --git a/puzzle-gui/src/main/java/net/puzzlemc/gui/util/ColorUtil.java b/puzzle-gui/src/main/java/net/puzzlemc/gui/util/ColorUtil.java new file mode 100755 index 0000000..c0109fc --- /dev/null +++ b/puzzle-gui/src/main/java/net/puzzlemc/gui/util/ColorUtil.java @@ -0,0 +1,17 @@ +package net.puzzlemc.gui.util; + +import java.awt.*; + +public class ColorUtil { + /** + * @credit https://stackoverflow.com/questions/4129666/how-to-convert-hex-to-rgb-using-java + * @param colorStr e.g. "FFFFFF" + * @return + */ + public static Color hex2Rgb(String colorStr) { + return new Color( + Integer.valueOf( colorStr.substring( 0, 2 ), 16 ), + Integer.valueOf( colorStr.substring( 2, 4 ), 16 ), + Integer.valueOf( colorStr.substring( 4, 6 ), 16 )); + } +} diff --git a/puzzle-gui/src/main/resources/assets/puzzle/icon.png b/puzzle-gui/src/main/resources/assets/puzzle/icon.png new file mode 100755 index 0000000..c170db5 Binary files /dev/null and b/puzzle-gui/src/main/resources/assets/puzzle/icon.png differ diff --git a/puzzle-gui/src/main/resources/assets/puzzle/lang/en_us.json b/puzzle-gui/src/main/resources/assets/puzzle/lang/en_us.json new file mode 100755 index 0000000..06a6372 --- /dev/null +++ b/puzzle-gui/src/main/resources/assets/puzzle/lang/en_us.json @@ -0,0 +1,17 @@ +{ + "puzzle.text.update_available":"An update is available!", + "puzzle.screen.title":"Puzzle Settings", + "puzzle.page.graphics":"Graphics Settings", + "puzzle.page.resources":"Resource Settings", + "puzzle.page.performance":"Performance Settings", + "puzzle.page.misc":"Miscellaneous Settings", + "puzzle.option.ctm":"Connected Textures", + "puzzle.option.inside_ctm":"Connect Inside Textures", + "puzzle.midnightconfig.title":"Title", + "puzzle.midnightconfig.showPuzzleInfo":"Show Puzzle Info", + "puzzle.midnightconfig.showPuzzleInfo.tooltip":"Show Puzzle Info", + "test.midnightconfig.title":"I am a title", + "test.midnightconfig.text":"I am a comment *u*", + "test.midnightconfig.showInfo":"Show Info", + "test.midnightconfig.showInfo.tooltip":"Show more information" +} diff --git a/puzzle-gui/src/main/resources/fabric.mod.json b/puzzle-gui/src/main/resources/fabric.mod.json new file mode 100755 index 0000000..358efe8 --- /dev/null +++ b/puzzle-gui/src/main/resources/fabric.mod.json @@ -0,0 +1,43 @@ +{ + "schemaVersion": 1, + "id": "puzzle-gui", + "version": "${version}", + + "name": "Puzzle GUI", + "description": "Unites optifine replacement mods in a clean & vanilla-style gui", + "authors": [ + "Motschen", + "TeamMidnightDust" + ], + "contact": { + "homepage": "https://www.midnightdust.eu/", + "sources": "https://github.com/TeamMidnightDust/Puzzle", + "issues": "https://github.com/TeamMidnightDust/Puzzle/issues" + }, + + "license": "MIT", + "icon": "assets/puzzle/icon.png", + + "environment": "client", + "entrypoints": { + "client": [ + "net.puzzlemc.gui.PuzzleClient" + ], + "modmenu": [ + "net.puzzlemc.gui.config.ModMenuIntegration" + ] + }, + "custom": { + "modmenu": { + "parent": "puzzle" + } + }, + + "mixins": [ + "puzzle-gui.mixins.json" + ], + + "depends": { + "fabric": "*" + } +} diff --git a/src/main/resources/puzzle.mixins.json b/puzzle-gui/src/main/resources/puzzle-gui.mixins.json similarity index 75% rename from src/main/resources/puzzle.mixins.json rename to puzzle-gui/src/main/resources/puzzle-gui.mixins.json index c31e076..30039cb 100755 --- a/src/main/resources/puzzle.mixins.json +++ b/puzzle-gui/src/main/resources/puzzle-gui.mixins.json @@ -1,6 +1,6 @@ { "required": true, - "package": "eu.midnightdust.puzzle.mixin", + "package": "net.puzzlemc.gui.mixin", "compatibilityLevel": "JAVA_8", "client": [ "MixinOptionsScreen" diff --git a/puzzle-models/build.gradle b/puzzle-models/build.gradle new file mode 100755 index 0000000..caec712 --- /dev/null +++ b/puzzle-models/build.gradle @@ -0,0 +1,9 @@ +archivesBaseName = "puzzle-models" + +minecraft { + accessWidener = file("src/main/resources/puzzle-models.accesswidener") +} + +dependencies { + api project(":puzzle-base") +} diff --git a/puzzle-models/src/main/java/net/puzzlemc/models/mixin/MixinModelElementDeserializer.java b/puzzle-models/src/main/java/net/puzzlemc/models/mixin/MixinModelElementDeserializer.java new file mode 100755 index 0000000..715ab3f --- /dev/null +++ b/puzzle-models/src/main/java/net/puzzlemc/models/mixin/MixinModelElementDeserializer.java @@ -0,0 +1,48 @@ +package net.puzzlemc.models.mixin; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import net.minecraft.client.render.model.json.ModelElement; +import net.minecraft.util.JsonHelper; +import net.minecraft.util.math.Vec3f; +import net.puzzlemc.core.config.PuzzleConfig; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ModelElement.Deserializer.class) +public abstract class MixinModelElementDeserializer { + @Shadow protected abstract Vec3f deserializeVec3f(JsonObject object, String name); + + @Inject(at = @At("HEAD"),method = "deserializeRotationAngle", cancellable = true) + private void puzzle$deserializeRotationAngle(JsonObject object, CallbackInfoReturnable cir) { + if (PuzzleConfig.unlimitedRotations) { + float angle = JsonHelper.getFloat(object, "angle"); + cir.setReturnValue(angle); + } + } + @Inject(at = @At("HEAD"),method = "deserializeTo", cancellable = true) + private void puzzle$deserializeTo(JsonObject object, CallbackInfoReturnable cir) { + if (PuzzleConfig.biggerModels) { + Vec3f vec3f = this.deserializeVec3f(object, "to"); + if (!(vec3f.getX() < -32.0F) && !(vec3f.getY() < -32.0F) && !(vec3f.getZ() < -32.0F) && !(vec3f.getX() > 48.0F) && !(vec3f.getY() > 48.0F) && !(vec3f.getZ() > 48.0F)) { + cir.setReturnValue(vec3f); + } else { + throw new JsonParseException("'to' specifier exceeds the allowed boundaries: " + vec3f); + } + } + } + @Inject(at = @At("HEAD"),method = "deserializeFrom", cancellable = true) + private void puzzle$deserializeFrom(JsonObject object, CallbackInfoReturnable cir) { + if (PuzzleConfig.biggerModels) { + Vec3f vec3f = this.deserializeVec3f(object, "from"); + if (!(vec3f.getX() < -32.0F) && !(vec3f.getY() < -32.0F) && !(vec3f.getZ() < -32.0F) && !(vec3f.getX() > 48.0F) && !(vec3f.getY() > 48.0F) && !(vec3f.getZ() > 48.0F)) { + cir.setReturnValue(vec3f); + } else { + throw new JsonParseException("'from' specifier exceeds the allowed boundaries: " + vec3f); + } + } + } +} diff --git a/puzzle-models/src/main/resources/assets/puzzle/icon.png b/puzzle-models/src/main/resources/assets/puzzle/icon.png new file mode 100755 index 0000000..c170db5 Binary files /dev/null and b/puzzle-models/src/main/resources/assets/puzzle/icon.png differ diff --git a/puzzle-models/src/main/resources/fabric.mod.json b/puzzle-models/src/main/resources/fabric.mod.json new file mode 100755 index 0000000..03223a0 --- /dev/null +++ b/puzzle-models/src/main/resources/fabric.mod.json @@ -0,0 +1,35 @@ +{ + "schemaVersion": 1, + "id": "puzzle-models", + "version": "${version}", + + "name": "Puzzle Models", + "description": "Provides more freedom for item and block models!", + "authors": [ + "Motschen", + "TeamMidnightDust" + ], + "contact": { + "homepage": "https://www.midnightdust.eu/", + "sources": "https://github.com/TeamMidnightDust/Puzzle", + "issues": "https://github.com/TeamMidnightDust/Puzzle/issues" + }, + "custom": { + "modmenu": { + "parent": "puzzle" + } + }, + + "license": "MIT", + "icon": "assets/puzzle/icon.png", + + "environment": "client", + "accessWidener" : "puzzle-models.accesswidener", + "mixins": [ + "puzzle-models.mixins.json" + ], + + "depends": { + "fabric": "*" + } +} diff --git a/puzzle-models/src/main/resources/puzzle-models.accesswidener b/puzzle-models/src/main/resources/puzzle-models.accesswidener new file mode 100755 index 0000000..ccaef1d --- /dev/null +++ b/puzzle-models/src/main/resources/puzzle-models.accesswidener @@ -0,0 +1,2 @@ +accessWidener v1 named +accessible class net/minecraft/client/render/model/json/ModelElement$Deserializer \ No newline at end of file diff --git a/puzzle-models/src/main/resources/puzzle-models.mixins.json b/puzzle-models/src/main/resources/puzzle-models.mixins.json new file mode 100755 index 0000000..d69dfa3 --- /dev/null +++ b/puzzle-models/src/main/resources/puzzle-models.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "net.puzzlemc.models.mixin", + "compatibilityLevel": "JAVA_8", + "client": [ + "MixinModelElementDeserializer" + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/puzzle-splashscreen/build.gradle b/puzzle-splashscreen/build.gradle new file mode 100755 index 0000000..692ec32 --- /dev/null +++ b/puzzle-splashscreen/build.gradle @@ -0,0 +1,5 @@ +archivesBaseName = "puzzle-splashscreen" + +dependencies { + api project(":puzzle-base") +} diff --git a/puzzle-splashscreen/src/main/java/net/puzzlemc/splashscreen/PuzzleSplashScreen.java b/puzzle-splashscreen/src/main/java/net/puzzlemc/splashscreen/PuzzleSplashScreen.java new file mode 100755 index 0000000..9d9ccb2 --- /dev/null +++ b/puzzle-splashscreen/src/main/java/net/puzzlemc/splashscreen/PuzzleSplashScreen.java @@ -0,0 +1,127 @@ +package net.puzzlemc.splashscreen; + +import net.fabricmc.api.ClientModInitializer; +import net.puzzlemc.core.config.PuzzleConfig; +import net.puzzlemc.core.util.ColorUtil; +import net.puzzlemc.splashscreen.util.ConfigTexture; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.resource.ResourceManagerHelper; +import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.hud.BackgroundHelper; +import net.minecraft.client.resource.metadata.TextureResourceMetadata; +import net.minecraft.client.texture.NativeImage; +import net.minecraft.client.texture.ResourceTexture; +import net.minecraft.resource.DefaultResourcePack; +import net.minecraft.resource.ResourceManager; +import net.minecraft.resource.ResourceType; +import net.minecraft.util.Identifier; +import org.apache.logging.log4j.LogManager; + +import java.awt.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.Properties; + +public class PuzzleSplashScreen implements ClientModInitializer { + public static final Identifier LOGO = new Identifier("textures/gui/title/mojangstudios.png"); + public static File CONFIG_PATH = new File(String.valueOf(FabricLoader.getInstance().getConfigDir().resolve(".puzzle_cache"))); + public static Path LOGO_TEXTURE = Paths.get(CONFIG_PATH + "/mojangstudios.png"); + private static final MinecraftClient client = MinecraftClient.getInstance(); + + public static void resetColors() { + PuzzleConfig.backgroundColor = 15675965; + PuzzleConfig.progressBarColor = 16777215; + PuzzleConfig.progressFrameColor = 16777215; + PuzzleConfig.write("puzzle"); + } + + public void onInitializeClient() { + if (!CONFIG_PATH.exists()) { // Run when config directory is nonexistant // + if (CONFIG_PATH.mkdir()) { // Create our custom config directory // + try { + Files.setAttribute(CONFIG_PATH.toPath(), "dos:hidden", true); + } catch (IOException ignored) { + } + } + } + ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() { + @Override + public Identifier getFabricId() { + return new Identifier("puzzle", "splash_screen"); + } + + @Override + public void reload(ResourceManager manager) { + if (PuzzleConfig.resourcepackSplashScreen) { + PuzzleSplashScreen.resetColors(); + client.getTextureManager().registerTexture(LOGO, new LogoTexture()); + + for (Identifier id : manager.findResources("optifine", path -> path.contains("color.properties"))) { + try (InputStream stream = manager.getResource(id).getInputStream()) { + Properties properties = new Properties(); + properties.load(stream); + + if (properties.get("screen.loading") != null) { + Color backgroundColorRGB = ColorUtil.hex2Rgb(properties.get("screen.loading").toString()); + PuzzleConfig.backgroundColor = BackgroundHelper.ColorMixer.getArgb(backgroundColorRGB.getAlpha(), backgroundColorRGB.getRed(), backgroundColorRGB.getGreen(), backgroundColorRGB.getGreen()); + } + if (properties.get("screen.loading.bar") != null) { + Color progressFrameColorRGB = ColorUtil.hex2Rgb(properties.get("screen.loading.bar").toString()); + PuzzleConfig.progressFrameColor = BackgroundHelper.ColorMixer.getArgb(progressFrameColorRGB.getAlpha(), progressFrameColorRGB.getRed(), progressFrameColorRGB.getGreen(), progressFrameColorRGB.getGreen()); + } + if (properties.get("screen.loading.progress") != null) { + Color progressBarColorRGB = ColorUtil.hex2Rgb(properties.get("screen.loading.progress").toString()); + PuzzleConfig.progressBarColor = BackgroundHelper.ColorMixer.getArgb(progressBarColorRGB.getAlpha(), progressBarColorRGB.getRed(), progressBarColorRGB.getGreen(), progressBarColorRGB.getGreen()); + } + if (properties.get("screen.loading") != null) { + PuzzleConfig.write("puzzle"); + } + } catch (Exception e) { + LogManager.getLogger("Puzzle").error("Error occurred while loading color.properties " + id.toString(), e); + } + } + for (Identifier id : manager.findResources("textures", path -> path.contains("mojangstudios.png"))) { + try (InputStream stream = manager.getResource(id).getInputStream()) { + //LogManager.getLogger().info("Logo copied to cache!"); + Files.copy(stream, LOGO_TEXTURE, StandardCopyOption.REPLACE_EXISTING); + client.getTextureManager().registerTexture(LOGO, new ConfigTexture(LOGO)); + } catch (Exception e) { + LogManager.getLogger("Puzzle").error("Error occurred while loading custom minecraft logo " + id.toString(), e); + } + } + } + } + }); + } + @Environment(EnvType.CLIENT) + public static class LogoTexture extends ResourceTexture { + public LogoTexture() { super(LOGO); } + + protected TextureData loadTextureData(ResourceManager resourceManager) { + MinecraftClient minecraftClient = MinecraftClient.getInstance(); + DefaultResourcePack defaultResourcePack = minecraftClient.getResourcePackProvider().getPack(); + try { + InputStream inputStream = defaultResourcePack.open(ResourceType.CLIENT_RESOURCES, LOGO); + TextureData var6; + try { + var6 = new TextureData(new TextureResourceMetadata(true, true), NativeImage.read(inputStream)); + } finally { + if (inputStream != null) { + inputStream.close(); + } + } + return var6; + } catch (IOException var18) { + return new TextureData(var18); + } + } + } +} diff --git a/puzzle-splashscreen/src/main/java/net/puzzlemc/splashscreen/mixin/MixinSplashScreen.java b/puzzle-splashscreen/src/main/java/net/puzzlemc/splashscreen/mixin/MixinSplashScreen.java new file mode 100755 index 0000000..15db3f1 --- /dev/null +++ b/puzzle-splashscreen/src/main/java/net/puzzlemc/splashscreen/mixin/MixinSplashScreen.java @@ -0,0 +1,52 @@ +package net.puzzlemc.splashscreen.mixin; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.SplashScreen; +import net.minecraft.util.Identifier; +import net.minecraft.util.Util; +import net.minecraft.util.math.MathHelper; +import net.puzzlemc.core.config.PuzzleConfig; +import net.puzzlemc.splashscreen.PuzzleSplashScreen; +import net.puzzlemc.splashscreen.util.ConfigTexture; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = SplashScreen.class, priority = 2000) +public class MixinSplashScreen { + @Shadow @Final static Identifier LOGO; + @Shadow @Final private boolean reloading; + @Shadow private long reloadStartTime; + @Shadow private long reloadCompleteTime; + + @Inject(method = "init(Lnet/minecraft/client/MinecraftClient;)V", at = @At("TAIL"), cancellable=true) + private static void init(MinecraftClient client, CallbackInfo ci) { // Load our custom textures at game start // + if (PuzzleConfig.resourcepackSplashScreen && PuzzleSplashScreen.LOGO_TEXTURE.toFile().exists()) client.getTextureManager().registerTexture(LOGO, new ConfigTexture(LOGO)); + } + @ModifyArg(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/SplashScreen;fill(Lnet/minecraft/client/util/math/MatrixStack;IIIII)V"), index = 5) + private int modifyBackgroundColor(int color) { // Set the Background Color to our configured value // + long l = Util.getMeasuringTimeMs(); + if (this.reloading && this.reloadStartTime == -1L) { + this.reloadStartTime = l; + } + + float f = this.reloadCompleteTime > -1L ? (float)(l - this.reloadCompleteTime) / 1000.0F : -1.0F; + int m = MathHelper.ceil((1.0F - MathHelper.clamp(f - 1.0F, 0.0F, 1.0F)) * 255.0F); + + return PuzzleConfig.backgroundColor | m << 24; + } + + @ModifyArg(method = "renderProgressBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/SplashScreen;fill(Lnet/minecraft/client/util/math/MatrixStack;IIIII)V"), index = 5) + private int modifyProgressFrame(int color) { // Set the Progress Bar Frame Color to our configured value // + return PuzzleConfig.progressFrameColor | 255 << 24; + } + @ModifyArg(method = "renderProgressBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/SplashScreen;fill(Lnet/minecraft/client/util/math/MatrixStack;IIIII)V", ordinal = 4), index = 5) + private int modifyProgressColor(int color) { // Set the Progress Bar Color to our configured value // + return PuzzleConfig.progressBarColor | 255 << 24; + } + +} diff --git a/puzzle-splashscreen/src/main/java/net/puzzlemc/splashscreen/util/ConfigTexture.java b/puzzle-splashscreen/src/main/java/net/puzzlemc/splashscreen/util/ConfigTexture.java new file mode 100755 index 0000000..b854636 --- /dev/null +++ b/puzzle-splashscreen/src/main/java/net/puzzlemc/splashscreen/util/ConfigTexture.java @@ -0,0 +1,38 @@ +package net.puzzlemc.splashscreen.util; + +import net.minecraft.client.resource.metadata.TextureResourceMetadata; +import net.minecraft.client.texture.NativeImage; +import net.minecraft.client.texture.ResourceTexture; +import net.minecraft.resource.ResourceManager; +import net.minecraft.util.Identifier; +import net.puzzlemc.splashscreen.PuzzleSplashScreen; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +public class ConfigTexture extends ResourceTexture { + + // Load textures from the config directory // + public ConfigTexture(Identifier location) { + super(location); + } + + protected TextureData loadTextureData(ResourceManager resourceManager) { + try { + InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.LOGO_TEXTURE)); + TextureData texture; + + try { + texture = new TextureData(new TextureResourceMetadata(false, true), NativeImage.read(input)); + } finally { + input.close(); + } + + return texture; + } catch (IOException var18) { + return new TextureData(var18); + } + } + +} \ No newline at end of file diff --git a/puzzle-splashscreen/src/main/resources/assets/puzzle/icon.png b/puzzle-splashscreen/src/main/resources/assets/puzzle/icon.png new file mode 100755 index 0000000..c170db5 Binary files /dev/null and b/puzzle-splashscreen/src/main/resources/assets/puzzle/icon.png differ diff --git a/puzzle-splashscreen/src/main/resources/fabric.mod.json b/puzzle-splashscreen/src/main/resources/fabric.mod.json new file mode 100755 index 0000000..8722a59 --- /dev/null +++ b/puzzle-splashscreen/src/main/resources/fabric.mod.json @@ -0,0 +1,40 @@ +{ + "schemaVersion": 1, + "id": "puzzle-splashscreen", + "version": "${version}", + + "name": "Puzzle Splash Screen", + "description": "Allows resourcepacks to define a custom splash screen", + "authors": [ + "Motschen", + "TeamMidnightDust" + ], + "contact": { + "homepage": "https://www.midnightdust.eu/", + "sources": "https://github.com/TeamMidnightDust/Puzzle", + "issues": "https://github.com/TeamMidnightDust/Puzzle/issues" + }, + + "license": "MIT", + "icon": "assets/puzzle/icon.png", + + "environment": "client", + "entrypoints": { + "client": [ + "net.puzzlemc.splashscreen.PuzzleSplashScreen" + ] + }, + "custom": { + "modmenu": { + "parent": "puzzle" + } + }, + + "mixins": [ + "puzzle-splashscreen.mixins.json" + ], + + "depends": { + "fabric": "*" + } +} diff --git a/puzzle-splashscreen/src/main/resources/puzzle-splashscreen.mixins.json b/puzzle-splashscreen/src/main/resources/puzzle-splashscreen.mixins.json new file mode 100755 index 0000000..f66436e --- /dev/null +++ b/puzzle-splashscreen/src/main/resources/puzzle-splashscreen.mixins.json @@ -0,0 +1,11 @@ +{ + "required": true, + "package": "net.puzzlemc.splashscreen.mixin", + "compatibilityLevel": "JAVA_8", + "client": [ + "MixinSplashScreen" + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 5b60df3..d0779af 100755 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,5 @@ pluginManagement { repositories { - jcenter() maven { name = 'Fabric' url = 'https://maven.fabricmc.net/' @@ -8,3 +7,10 @@ pluginManagement { gradlePluginPortal() } } +include 'puzzle-base' + +include 'puzzle-splashscreen' +include 'puzzle-models' +include 'puzzle-blocks' +//include 'puzzle-randomentities' +include 'puzzle-gui' diff --git a/src/main/java/eu/midnightdust/puzzle/PuzzleApi.java b/src/main/java/eu/midnightdust/puzzle/PuzzleApi.java deleted file mode 100755 index 5789f5c..0000000 --- a/src/main/java/eu/midnightdust/puzzle/PuzzleApi.java +++ /dev/null @@ -1,19 +0,0 @@ -package eu.midnightdust.puzzle; - -import eu.midnightdust.puzzle.screen.widget.PuzzleWidget; -import net.minecraft.text.Text; - -import java.util.ArrayList; -import java.util.List; - -public class PuzzleApi { - public static List GRAPHICS_OPTIONS = new ArrayList<>(); - public static List MISC_OPTIONS = new ArrayList<>(); - public static List PERFORMANCE_OPTIONS = new ArrayList<>(); - public static List TEXTURE_OPTIONS = new ArrayList<>(); - - public static void addToGraphicsOptions(PuzzleWidget button) {GRAPHICS_OPTIONS.add(button);} - public static void addToMiscOptions(PuzzleWidget button) {MISC_OPTIONS.add(button);} - public static void addToPerformanceOptions(PuzzleWidget button) {PERFORMANCE_OPTIONS.add(button);} - public static void addToTextureOptions(PuzzleWidget button) {TEXTURE_OPTIONS.add(button);} -} diff --git a/src/main/java/eu/midnightdust/puzzle/PuzzleClient.java b/src/main/java/eu/midnightdust/puzzle/PuzzleClient.java deleted file mode 100755 index 7ab7408..0000000 --- a/src/main/java/eu/midnightdust/puzzle/PuzzleClient.java +++ /dev/null @@ -1,59 +0,0 @@ -package eu.midnightdust.puzzle; - -import eu.midnightdust.cullleaves.config.CullLeavesConfig; -import eu.midnightdust.puzzle.screen.widget.PuzzleWidget; -import me.lambdaurora.lambdabettergrass.LBGConfig; -import me.lambdaurora.lambdabettergrass.LambdaBetterGrass; -import me.lambdaurora.lambdynlights.DynamicLightsConfig; -import me.lambdaurora.lambdynlights.LambDynLights; -import net.fabricmc.api.ClientModInitializer; -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.MinecraftClient; -import net.minecraft.text.Text; -import net.minecraft.text.TranslatableText; -import net.minecraft.util.Formatting; -import team.chisel.ctm.client.CTMClient; -import team.chisel.ctm.client.config.ConfigManager; - -public class PuzzleClient implements ClientModInitializer { - - public static final Text YES = new TranslatableText("gui.yes").formatted(Formatting.GREEN); - public static final Text NO = new TranslatableText("gui.no").formatted(Formatting.RED); - - @Override - public void onInitializeClient() { - if (FabricLoader.getInstance().isModLoaded("cullleaves")) { - PuzzleApi.addToPerformanceOptions(new PuzzleWidget(Text.of("Cull Leaves"), (button) -> button.setMessage(CullLeavesConfig.enabled ? YES : NO), (button) -> { - CullLeavesConfig.enabled = !CullLeavesConfig.enabled; - CullLeavesConfig.write(); - MinecraftClient.getInstance().worldRenderer.reload(); - })); - } - if (FabricLoader.getInstance().isModLoaded("lambdynlights")) { - DynamicLightsConfig ldlConfig = LambDynLights.get().config; - PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("lambdynlights.option.mode"), (button) -> button.setMessage(ldlConfig.getDynamicLightsMode().getTranslatedText()), (button) -> ldlConfig.setDynamicLightsMode(ldlConfig.getDynamicLightsMode().next()))); - PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("lambdynlights.option.mode").append(": ").append(new TranslatableText("lambdynlights.option.entities")), (button) -> button.setMessage(ldlConfig.hasEntitiesLightSource() ? YES : NO), (button) -> ldlConfig.setEntitiesLightSource(!ldlConfig.hasEntitiesLightSource()))); - PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("lambdynlights.option.mode").append(": ").append(new TranslatableText("lambdynlights.option.block_entities")), (button) -> button.setMessage(ldlConfig.hasBlockEntitiesLightSource() ? YES : NO), (button) -> ldlConfig.setBlockEntitiesLightSource(!ldlConfig.hasBlockEntitiesLightSource()))); - PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("lambdynlights.option.mode").append(": ").append(new TranslatableText("entity.minecraft.creeper")), (button) -> button.setMessage(ldlConfig.getCreeperLightingMode().getTranslatedText()), (button) -> ldlConfig.setCreeperLightingMode(ldlConfig.getCreeperLightingMode().next()))); - PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("lambdynlights.option.mode").append(": ").append(new TranslatableText("block.minecraft.tnt")), (button) -> button.setMessage(ldlConfig.getTntLightingMode().getTranslatedText()), (button) -> ldlConfig.setTntLightingMode(ldlConfig.getTntLightingMode().next()))); - PuzzleApi.addToGraphicsOptions(new PuzzleWidget(new TranslatableText("lambdynlights.option.mode").append(": ").append(new TranslatableText("lambdynlights.option.water_sensitive")), (button) -> button.setMessage(ldlConfig.hasWaterSensitiveCheck() ? YES : NO), (button) -> ldlConfig.setWaterSensitiveCheck(!ldlConfig.hasWaterSensitiveCheck()))); - } - if (FabricLoader.getInstance().isModLoaded("ctm")) { - ConfigManager ctmfConfigManager = CTMClient.getConfigManager(); - ConfigManager.Config ctmfConfig = CTMClient.getConfigManager().getConfig(); - PuzzleApi.addToTextureOptions(new PuzzleWidget(new TranslatableText("puzzle.option.ctm"), (button) -> button.setMessage(ctmfConfig.disableCTM ? NO : YES), (button) -> { - ctmfConfig.disableCTM = !ctmfConfig.disableCTM; - ctmfConfigManager.onConfigChange(); - })); - PuzzleApi.addToTextureOptions(new PuzzleWidget(new TranslatableText("puzzle.option.inside_ctm"), (button) -> button.setMessage(ctmfConfig.connectInsideCTM ? YES : NO), (button) -> { - ctmfConfig.connectInsideCTM = !ctmfConfig.connectInsideCTM; - ctmfConfigManager.onConfigChange(); - })); - } - if (FabricLoader.getInstance().isModLoaded("lambdabettergrass")) { - LBGConfig lbgConfig = LambdaBetterGrass.get().config; - PuzzleApi.addToTextureOptions(new PuzzleWidget(new TranslatableText("lambdabettergrass.option.mode"), (button) -> button.setMessage(lbgConfig.getMode().getTranslatedText()), (button) -> lbgConfig.setMode(lbgConfig.getMode().next()))); - PuzzleApi.addToTextureOptions(new PuzzleWidget(new TranslatableText("lambdabettergrass.option.better_snow"), (button) -> button.setMessage(lbgConfig.hasBetterLayer() ? YES : NO), (button) -> lbgConfig.setBetterLayer(!lbgConfig.hasBetterLayer()))); - } - } -} diff --git a/src/main/java/eu/midnightdust/puzzle/config/ModMenuIntegration.java b/src/main/java/eu/midnightdust/puzzle/config/ModMenuIntegration.java deleted file mode 100755 index 6e8048b..0000000 --- a/src/main/java/eu/midnightdust/puzzle/config/ModMenuIntegration.java +++ /dev/null @@ -1,16 +0,0 @@ -package eu.midnightdust.puzzle.config; - -import com.terraformersmc.modmenu.api.ConfigScreenFactory; -import com.terraformersmc.modmenu.api.ModMenuApi; -import eu.midnightdust.puzzle.screen.PuzzleOptionsScreen; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; - -@Environment(EnvType.CLIENT) -public class ModMenuIntegration implements ModMenuApi { - - @Override - public ConfigScreenFactory getModConfigScreenFactory() { - return PuzzleOptionsScreen::new; - } -} \ No newline at end of file diff --git a/src/main/java/eu/midnightdust/puzzle/screen/PuzzleOptionsScreen.java b/src/main/java/eu/midnightdust/puzzle/screen/PuzzleOptionsScreen.java deleted file mode 100755 index 7e9f730..0000000 --- a/src/main/java/eu/midnightdust/puzzle/screen/PuzzleOptionsScreen.java +++ /dev/null @@ -1,55 +0,0 @@ -package eu.midnightdust.puzzle.screen; - -import eu.midnightdust.puzzle.screen.page.GraphicsPage; -import eu.midnightdust.puzzle.screen.page.MiscPage; -import eu.midnightdust.puzzle.screen.page.PerformancePage; -import eu.midnightdust.puzzle.screen.page.TexturesPage; -import net.coderbot.iris.gui.screen.ShaderPackScreen; -import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.gui.screen.ScreenTexts; -import net.minecraft.client.gui.widget.ButtonWidget; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.text.TranslatableText; - -import java.util.Objects; - -public class PuzzleOptionsScreen extends Screen { - - public PuzzleOptionsScreen(Screen parent) { - super(new TranslatableText("puzzle.screen.title")); - this.parent = parent; - } - private final Screen parent; - - @Override - protected void init() { - super.init(); - GraphicsPage graphicsPage = new GraphicsPage(this); - MiscPage miscPage = new MiscPage(this); - PerformancePage performancePage = new PerformancePage(this); - TexturesPage texturesPage = new TexturesPage(this); - - this.addButton(new ButtonWidget(this.width / 2 - 155, this.height / 6 + 48 - 6, 150, 20, graphicsPage.getTitle().copy().append("..."), (button) -> Objects.requireNonNull(client).openScreen(graphicsPage))); - this.addButton(new ButtonWidget(this.width / 2 + 5, this.height / 6 + 48 - 6, 150, 20, texturesPage.getTitle().copy().append("..."), (button) -> Objects.requireNonNull(client).openScreen(texturesPage))); - this.addButton(new ButtonWidget(this.width / 2 - 155, this.height / 6 + 72 - 6, 150, 20, performancePage.getTitle().copy().append("..."), (button) -> Objects.requireNonNull(client).openScreen(performancePage))); - this.addButton(new ButtonWidget(this.width / 2 + 5, this.height / 6 + 72 - 6, 150, 20, miscPage.getTitle().copy().append("..."), (button) -> Objects.requireNonNull(client).openScreen(miscPage))); - if (FabricLoader.getInstance().isModLoaded("iris")) { - try { - ShaderPackScreen shaderPackPage = new ShaderPackScreen(this); - this.addButton(new ButtonWidget(this.width / 2 - 155, this.height / 6 + 96 - 6, 150, 20, shaderPackPage.getTitle().copy().append("..."), (button) -> Objects.requireNonNull(client).openScreen(shaderPackPage))); - } - catch (Exception | Error ignored) { - } - } - this.addButton(new ButtonWidget(this.width / 2 - 100, this.height / 6 + 168, 200, 20, ScreenTexts.DONE, (button) -> Objects.requireNonNull(client).openScreen(parent))); - } - - @Override - public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) { - this.renderBackground(matrices); - - super.render(matrices, mouseX, mouseY, delta); - drawCenteredText(matrices, textRenderer, title, width/2, 15, 0xFFFFFF); - } -} diff --git a/src/main/java/eu/midnightdust/puzzle/screen/page/TexturesPage.java b/src/main/java/eu/midnightdust/puzzle/screen/page/TexturesPage.java deleted file mode 100755 index 3f205da..0000000 --- a/src/main/java/eu/midnightdust/puzzle/screen/page/TexturesPage.java +++ /dev/null @@ -1,13 +0,0 @@ -package eu.midnightdust.puzzle.screen.page; - -import eu.midnightdust.puzzle.PuzzleApi; -import eu.midnightdust.puzzle.screen.page.AbstractPuzzleOptionsPage; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.text.TranslatableText; - -public class TexturesPage extends AbstractPuzzleOptionsPage { - - public TexturesPage(Screen parent) { - super(parent, new TranslatableText("puzzle.page.textures"), PuzzleApi.TEXTURE_OPTIONS); - } -} diff --git a/src/main/java/eu/midnightdust/puzzle/screen/widget/ButtonType.java b/src/main/java/eu/midnightdust/puzzle/screen/widget/ButtonType.java deleted file mode 100755 index 6f746ab..0000000 --- a/src/main/java/eu/midnightdust/puzzle/screen/widget/ButtonType.java +++ /dev/null @@ -1,5 +0,0 @@ -package eu.midnightdust.puzzle.screen.widget; - -public enum ButtonType { - BUTTON, SLIDER, TEXT_FIELD -} diff --git a/src/main/resources/assets/puzzle/icon512.png b/src/main/resources/assets/puzzle/icon512.png deleted file mode 100755 index e8b9a81..0000000 Binary files a/src/main/resources/assets/puzzle/icon512.png and /dev/null differ diff --git a/src/main/resources/assets/puzzle/lang/en_us.json b/src/main/resources/assets/puzzle/lang/en_us.json index 59871c3..06a6372 100755 --- a/src/main/resources/assets/puzzle/lang/en_us.json +++ b/src/main/resources/assets/puzzle/lang/en_us.json @@ -1,9 +1,17 @@ { + "puzzle.text.update_available":"An update is available!", "puzzle.screen.title":"Puzzle Settings", "puzzle.page.graphics":"Graphics Settings", - "puzzle.page.textures":"Texture Settings", + "puzzle.page.resources":"Resource Settings", "puzzle.page.performance":"Performance Settings", "puzzle.page.misc":"Miscellaneous Settings", "puzzle.option.ctm":"Connected Textures", - "puzzle.option.inside_ctm":"Connect Inside Textures" + "puzzle.option.inside_ctm":"Connect Inside Textures", + "puzzle.midnightconfig.title":"Title", + "puzzle.midnightconfig.showPuzzleInfo":"Show Puzzle Info", + "puzzle.midnightconfig.showPuzzleInfo.tooltip":"Show Puzzle Info", + "test.midnightconfig.title":"I am a title", + "test.midnightconfig.text":"I am a comment *u*", + "test.midnightconfig.showInfo":"Show Info", + "test.midnightconfig.showInfo.tooltip":"Show more information" } diff --git a/src/main/resources/assets/puzzle/logo.pdn b/src/main/resources/assets/puzzle/logo.pdn deleted file mode 100755 index c441be5..0000000 Binary files a/src/main/resources/assets/puzzle/logo.pdn and /dev/null differ diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 4fcc8f0..06656d9 100755 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -4,10 +4,10 @@ "version": "${version}", "name": "Puzzle", - "description": "Unites optifine replacement mods in a clean & vanilla-style gui", + "description": "Fancy and performance-improving features.", "authors": [ - "Motschen", - "TeamMidnightDust" + "PuzzleMC", + "Motschen" ], "contact": { "homepage": "https://www.midnightdust.eu/", @@ -18,19 +18,7 @@ "license": "MIT", "icon": "assets/puzzle/icon.png", - "environment": "*", - "entrypoints": { - "client": [ - "eu.midnightdust.puzzle.PuzzleClient" - ], - "modmenu": [ - "eu.midnightdust.puzzle.config.ModMenuIntegration" - ] - }, - - "mixins": [ - "puzzle.mixins.json" - ], + "environment": "client", "depends": { "fabric": "*"