├── .gitignore ├── LICENSE ├── Puzzle_Splashscreen_Template.zip ├── README.md ├── build.gradle ├── common ├── build.gradle └── src │ └── main │ ├── java │ └── net │ │ └── puzzlemc │ │ ├── core │ │ ├── PuzzleCore.java │ │ └── config │ │ │ └── PuzzleConfig.java │ │ ├── gui │ │ ├── PuzzleApi.java │ │ ├── PuzzleGui.java │ │ ├── compat │ │ │ ├── BorderlessMiningCompat.java │ │ │ ├── CITRCompat.java │ │ │ ├── ColormaticCompat.java │ │ │ ├── ContinuityCompat.java │ │ │ ├── CullLeavesCompat.java │ │ │ ├── EMFCompat.java │ │ │ ├── ETFCompat.java │ │ │ ├── IrisCompat.java │ │ │ ├── LBGCompat.java │ │ │ └── LDLCompat.java │ │ ├── mixin │ │ │ └── MixinOptionsScreen.java │ │ └── screen │ │ │ ├── PuzzleOptionsScreen.java │ │ │ └── widget │ │ │ ├── ButtonType.java │ │ │ ├── PuzzleButtonWidget.java │ │ │ ├── PuzzleOptionListWidget.java │ │ │ ├── PuzzleSliderWidget.java │ │ │ ├── PuzzleTextFieldWidget.java │ │ │ └── PuzzleWidget.java │ │ ├── models │ │ └── mixin │ │ │ └── MixinModelElementDeserializer.java │ │ └── splashscreen │ │ ├── PuzzleSplashScreen.java │ │ └── mixin │ │ ├── MixinSplashScreen.java │ │ └── RenderPipelinesAccessor.java │ └── resources │ ├── architectury.puzzle.json │ ├── assets │ └── puzzle │ │ ├── icon.png │ │ ├── lang │ │ ├── be_by.json │ │ ├── de_de.json │ │ ├── el_gr.json │ │ ├── en_us.json │ │ ├── es_es.json │ │ ├── et_ee.json │ │ ├── ko_kr.json │ │ ├── pl_pl.json │ │ ├── pt_br.json │ │ ├── ru_ru.json │ │ ├── vi_vn.json │ │ ├── zh_cn.json │ │ └── zh_tw.json │ │ └── textures │ │ └── gui │ │ └── sprites │ │ └── icon │ │ └── button.png │ ├── puzzle-gui.mixins.json │ ├── puzzle-models.accesswidener │ ├── puzzle-models.mixins.json │ └── puzzle-splashscreen.mixins.json ├── fabric ├── build.gradle └── src │ └── main │ ├── java │ └── net │ │ └── puzzlemc │ │ └── fabric │ │ ├── PuzzleFabric.java │ │ └── modmenu │ │ └── ModMenuIntegration.java │ └── resources │ └── fabric.mod.json ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── neoforge ├── build.gradle ├── gradle.properties └── src │ └── main │ ├── java │ └── net │ │ └── puzzlemc │ │ └── neoforge │ │ ├── PuzzleNeoForge.java │ │ └── mixin │ │ └── splashscreen │ │ └── MixinNeoForgeLoadingOverlay.java │ └── resources │ ├── META-INF │ └── neoforge.mods.toml │ ├── puzzle-splashscreen_neoforge.mixins.json │ └── puzzle.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # gradle 2 | 3 | .gradle/ 4 | out/ 5 | classes/ 6 | build/ 7 | 8 | # idea 9 | 10 | .idea/ 11 | *.iml 12 | *.ipr 13 | *.iws 14 | 15 | # vscode 16 | 17 | .settings/ 18 | .vscode/ 19 | bin/ 20 | .classpath 21 | .project 22 | 23 | # fabric 24 | 25 | run/ 26 | 27 | # unfinished 28 | puzzle-randomentities/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 MidnightDust 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Puzzle_Splashscreen_Template.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PuzzleMC/Puzzle/7caadedcf1349f403e5adbd7c26ed2713805403c/Puzzle_Splashscreen_Template.zip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Puzzle 2 | Unites optifine replacement mods in a clean & vanilla-style gui 3 | 4 | [![Download from Curseforge](https://cf.way2muchnoise.eu/full_563977_downloads%20on%20Curseforge.svg?badge_style=for_the_badge)](https://www.curseforge.com/minecraft/mc-mods/puzzle) [![Download from Modrinth](https://img.shields.io/modrinth/dt/puzzle?color=4&label=Download%20from%20Modrinth&style=for-the-badge)](https://modrinth.com/mod/puzzle) 5 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | import groovy.json.JsonSlurper 2 | import groovy.json.JsonOutput 3 | 4 | plugins { 5 | id "architectury-plugin" version "3.4-SNAPSHOT" 6 | id "dev.architectury.loom" version "1.10-SNAPSHOT" apply false 7 | id "me.shedaniel.unified-publishing" version "0.1.+" apply false 8 | id 'com.github.johnrengelman.shadow' version '8.1.1' apply false 9 | } 10 | 11 | architectury { 12 | minecraft = rootProject.minecraft_version 13 | } 14 | 15 | subprojects { 16 | apply plugin: "dev.architectury.loom" 17 | 18 | repositories { 19 | maven { 20 | url = "https://api.modrinth.com/maven" 21 | } 22 | maven { url "https://maven.terraformersmc.com/releases" } 23 | maven { 24 | name = 'AperLambda' 25 | url = 'https://aperlambda.github.io/maven' 26 | } 27 | mavenCentral() 28 | maven { 29 | name 'Gegy' 30 | url 'https://maven.gegy.dev' 31 | } 32 | 33 | maven { 34 | url "https://www.cursemaven.com" 35 | content { 36 | includeGroup "curse.maven" 37 | } 38 | } 39 | maven { 40 | name = 'JitPack' 41 | url 'https://jitpack.io' 42 | } 43 | maven { 44 | url "https://maven.shedaniel.me/" 45 | } 46 | maven { url "https://maven.quiltmc.org/repository/release/" } 47 | } 48 | 49 | dependencies { 50 | minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" 51 | // The following line declares the yarn mappings you may select this one as well. 52 | mappings loom.layered { 53 | it.mappings("net.fabricmc:yarn:$rootProject.yarn_mappings:v2") 54 | it.mappings("dev.architectury:yarn-mappings-patch-neoforge:$rootProject.yarn_mappings_patch_neoforge_version") 55 | } 56 | modCompileOnlyApi ("maven.modrinth:cull-leaves:${project.cull_leaves_version}") 57 | 58 | modCompileOnlyApi ("maven.modrinth:iris:${project.iris_version}") 59 | modCompileOnly ("maven.modrinth:cit-resewn:${project.cit_resewn_version}") 60 | modCompileOnlyApi ("maven.modrinth:continuity:${project.continuity_version}") 61 | modCompileOnlyApi ("maven.modrinth:animatica:${project.animatica_version}") 62 | modCompileOnlyApi ("maven.modrinth:colormatic:${project.colormatic_version}") 63 | modCompileOnlyApi ("maven.modrinth:borderless-mining:${project.borderless_mining_version}") 64 | modCompileOnlyApi ("maven.modrinth:dynamic-fps:${project.dynamic_fps_version}") 65 | modCompileOnlyApi ("com.moandjiezana.toml:toml4j:${project.toml4j_version}") 66 | modCompileOnlyApi ("maven.modrinth:entitytexturefeatures:${project.etf_version}") 67 | modCompileOnlyApi ("maven.modrinth:entity-model-features:${project.emf_version}") 68 | modCompileOnlyApi ("maven.modrinth:completeconfig:${project.complete_config_version}") 69 | //modImplementation ("maven.modrinth:exordium:${project.exordium_version}") 70 | 71 | 72 | modCompileOnlyApi ("maven.modrinth:lambdynamiclights:${project.ldl_version}") 73 | modCompileOnly("dev.lambdaurora.lambdynamiclights:lambdynamiclights-api:${project.ldl_version}") 74 | modCompileOnlyApi ("maven.modrinth:lambdabettergrass:${project.lbg_version}") 75 | modCompileOnlyApi "dev.lambdaurora:spruceui:${project.spruceui_version}" 76 | } 77 | } 78 | 79 | allprojects { 80 | apply plugin: "java" 81 | apply plugin: "architectury-plugin" 82 | apply plugin: "maven-publish" 83 | 84 | archivesBaseName = rootProject.archives_base_name 85 | version = rootProject.mod_version 86 | group = rootProject.maven_group 87 | 88 | tasks.withType(JavaCompile) { 89 | options.encoding = "UTF-8" 90 | options.release = 21 91 | } 92 | ext { 93 | releaseChangelog = { 94 | def changes = new StringBuilder() 95 | changes << "## Puzzle v$project.version for $project.minecraft_version\n[View the changelog](https://www.github.com/PuzzleMC/Puzzle/commits/)" 96 | def proc = "git log --max-count=1 --pretty=format:%s".execute() 97 | proc.in.eachLine { line -> 98 | def processedLine = line.toString() 99 | if (!processedLine.contains("New translations") && !processedLine.contains("Merge") && !processedLine.contains("branch")) { 100 | changes << "\n- ${processedLine.capitalize()}" 101 | } 102 | } 103 | proc.waitFor() 104 | return changes.toString() 105 | } 106 | } 107 | processResources { 108 | // Minify json resources 109 | doLast { 110 | fileTree(dir: outputs.files.asPath, include: "**/*.json").each { 111 | File file -> file.text = JsonOutput.toJson(new JsonSlurper().parse(file)) 112 | } 113 | } 114 | } 115 | 116 | java { 117 | withSourcesJar() 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /common/build.gradle: -------------------------------------------------------------------------------- 1 | architectury { 2 | common(rootProject.enabled_platforms.split(",")) 3 | } 4 | loom { 5 | accessWidenerPath = file("src/main/resources/puzzle-models.accesswidener") 6 | } 7 | 8 | dependencies { 9 | // We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies 10 | // Do NOT use other classes from fabric loader 11 | modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" 12 | modCompileOnly "maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric" 13 | 14 | modCompileOnly "org.quiltmc:quilt-loader:${rootProject.quilt_loader_version}" 15 | modCompileOnlyApi "org.quiltmc.quilted-fabric-api:quilted-fabric-api:${rootProject.quilt_fabric_api_version}" 16 | modCompileOnlyApi ("org.aperlambda:lambdajcommon:1.8.1") { 17 | exclude group: 'com.google.code.gson' 18 | exclude group: 'com.google.guava' 19 | } 20 | } 21 | 22 | publishing { 23 | publications { 24 | mavenCommon(MavenPublication) { 25 | artifactId = rootProject.archives_base_name 26 | from components.java 27 | } 28 | } 29 | 30 | // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. 31 | repositories { 32 | // Add repositories to publish to here. 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/core/PuzzleCore.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.core; 2 | 3 | import net.puzzlemc.core.config.PuzzleConfig; 4 | import net.puzzlemc.gui.PuzzleGui; 5 | import net.puzzlemc.splashscreen.PuzzleSplashScreen; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | 9 | public class PuzzleCore { 10 | public final static String MOD_ID = "puzzle"; 11 | public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); 12 | 13 | public static void initModules() { 14 | PuzzleConfig.init(MOD_ID, PuzzleConfig.class); 15 | PuzzleGui.init(); 16 | PuzzleSplashScreen.init(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/core/config/PuzzleConfig.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.core.config; 2 | 3 | import eu.midnightdust.lib.config.MidnightConfig; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | public class PuzzleConfig extends MidnightConfig { 9 | private static final String GUI = "gui"; 10 | private static final String INTERNAL = "internal"; 11 | private static final String FEATURES = "features"; 12 | 13 | @Entry(category = GUI, name = "Disabled integrations") public static List disabledIntegrations = new ArrayList<>(); 14 | @Entry(category = GUI, name = "Enable Puzzle button") public static boolean enablePuzzleButton = true; 15 | 16 | @Entry(category = FEATURES, name = "puzzle.option.resourcepack_splash_screen") public static boolean resourcepackSplashScreen = true; 17 | @Entry(category = FEATURES, name = "puzzle.option.unlimited_model_rotations") public static boolean unlimitedRotations = true; 18 | @Entry(category = FEATURES, name = "puzzle.option.bigger_custom_models") public static boolean biggerModels = true; 19 | 20 | @Entry(category = INTERNAL, name = "Enable debug messages") public static boolean debugMessages = false; 21 | @Entry(category = INTERNAL, name = "Has custom splash screen") public static boolean hasCustomSplashScreen = false; 22 | @Entry(category = INTERNAL, name = "Splash Background Color") public static int backgroundColor = 15675965; 23 | @Entry(category = INTERNAL, name = "Splash Progress Bar Color") public static int progressBarColor = 16777215; 24 | @Entry(category = INTERNAL, name = "Splash Progress Bar Background Color") public static int progressBarBackgroundColor = 15675965; 25 | @Entry(category = INTERNAL, name = "Splash Progress Bar Frame Color") public static int progressFrameColor = 16777215; 26 | @Entry(category = INTERNAL, name = "puzzle.option.better_splash_screen_blend") public static boolean disableBlend = false; 27 | @Entry(category = INTERNAL, name = "Custom Blend Function") public static List customBlendFunction = new ArrayList<>(); 28 | } 29 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/PuzzleApi.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui; 2 | 3 | import net.puzzlemc.core.config.PuzzleConfig; 4 | import net.puzzlemc.gui.screen.widget.PuzzleWidget; 5 | 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | import static net.puzzlemc.core.PuzzleCore.LOGGER; 10 | 11 | public class PuzzleApi { 12 | public static List GRAPHICS_OPTIONS = new ArrayList<>(); 13 | public static List MISC_OPTIONS = new ArrayList<>(); 14 | public static List PERFORMANCE_OPTIONS = new ArrayList<>(); 15 | public static List RESOURCE_OPTIONS = new ArrayList<>(); 16 | 17 | public static void addToGraphicsOptions(PuzzleWidget button) { 18 | GRAPHICS_OPTIONS.add(button); 19 | if (PuzzleConfig.debugMessages) 20 | LOGGER.info("{} -> Graphics Options", button.descriptionText.getContent().toString()); 21 | } 22 | public static void addToMiscOptions(PuzzleWidget button) { 23 | MISC_OPTIONS.add(button); 24 | if (PuzzleConfig.debugMessages) 25 | LOGGER.info("{} -> Misc Options", button.descriptionText.getContent().toString()); 26 | } 27 | public static void addToPerformanceOptions(PuzzleWidget button) { 28 | PERFORMANCE_OPTIONS.add(button); 29 | if (PuzzleConfig.debugMessages) 30 | LOGGER.info("{}- > Performance Options", button.descriptionText.getContent().toString()); 31 | } 32 | public static void addToResourceOptions(PuzzleWidget button) { 33 | RESOURCE_OPTIONS.add(button); 34 | if (PuzzleConfig.debugMessages) 35 | LOGGER.info("{} -> Resource Options", button.descriptionText.getContent().toString()); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/PuzzleGui.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui; 2 | 3 | import eu.midnightdust.core.MidnightLib; 4 | import eu.midnightdust.lib.util.PlatformFunctions; 5 | import net.minecraft.util.Identifier; 6 | import net.puzzlemc.core.config.PuzzleConfig; 7 | import net.puzzlemc.gui.compat.*; 8 | import net.puzzlemc.gui.screen.widget.PuzzleWidget; 9 | import net.minecraft.client.MinecraftClient; 10 | import net.minecraft.text.Text; 11 | import net.minecraft.util.Formatting; 12 | import net.puzzlemc.splashscreen.PuzzleSplashScreen; 13 | 14 | import static net.puzzlemc.core.PuzzleCore.LOGGER; 15 | 16 | public class PuzzleGui { 17 | public final static String id = "puzzle"; 18 | public static final Text YES = Text.translatable("gui.yes").formatted(Formatting.GREEN); 19 | public static final Text NO = Text.translatable("gui.no").formatted(Formatting.RED); 20 | public static final Identifier PUZZLE_BUTTON = Identifier.of(id, "icon/button"); 21 | 22 | public static void init() { 23 | MidnightLib.hiddenMods.add("puzzle"); 24 | PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.of("\uD83E\uDDE9 Puzzle"))); 25 | PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.translatable("puzzle.midnightconfig.title"), (button) -> button.setMessage(Text.of("OPEN")), (button) -> { 26 | MinecraftClient.getInstance().setScreen(PuzzleConfig.getScreen(MinecraftClient.getInstance().currentScreen, "puzzle")); 27 | })); 28 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("\uD83E\uDDE9 Puzzle"))); 29 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("puzzle.option.resourcepack_splash_screen"), (button) -> button.setMessage(PuzzleConfig.resourcepackSplashScreen ? YES : NO), (button) -> { 30 | PuzzleConfig.resourcepackSplashScreen = !PuzzleConfig.resourcepackSplashScreen; 31 | PuzzleSplashScreen.resetColors(); 32 | PuzzleConfig.write(id); 33 | MinecraftClient.getInstance().getTextureManager().registerTexture(PuzzleSplashScreen.LOGO, new PuzzleSplashScreen.LogoTexture(PuzzleSplashScreen.LOGO)); 34 | })); 35 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("puzzle.option.unlimited_model_rotations"), (button) -> button.setMessage(PuzzleConfig.unlimitedRotations ? YES : NO), (button) -> { 36 | PuzzleConfig.unlimitedRotations = !PuzzleConfig.unlimitedRotations; 37 | PuzzleConfig.write(id); 38 | })); 39 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("puzzle.option.bigger_custom_models"), (button) -> button.setMessage(PuzzleConfig.biggerModels ? YES : NO), (button) -> { 40 | PuzzleConfig.biggerModels = !PuzzleConfig.biggerModels; 41 | PuzzleConfig.write(id); 42 | })); 43 | if (isActive("cullleaves")) CullLeavesCompat.init(); 44 | if (isActive("colormatic")) ColormaticCompat.init(); 45 | if (isActive("borderlessmining")) BorderlessMiningCompat.init(); 46 | if (isActive("iris")) IrisCompat.init(); 47 | } 48 | 49 | public static boolean lateInitDone = false; 50 | public static void lateInit() { // Some mods are initialized after Puzzle, so we can't access them in our ClientModInitializer 51 | if (isActive("lambdynlights")) LDLCompat.init(); 52 | if (isActive("citresewn")) CITRCompat.init(); 53 | if (isActive("lambdabettergrass")) LBGCompat.init(); 54 | if (isActive("continuity")) ContinuityCompat.init(); 55 | try { 56 | if (isActive("entity_texture_features")) ETFCompat.init(); 57 | if (isActive("entity_model_features")) EMFCompat.init(); 58 | } catch (Exception e) { 59 | LOGGER.error("ETF/EMF config structure changed. Again...", e); 60 | } 61 | 62 | lateInitDone = true; 63 | } 64 | public static boolean isActive(String modid) { 65 | return PlatformFunctions.isModLoaded(modid) && !PuzzleConfig.disabledIntegrations.contains(modid); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/compat/BorderlessMiningCompat.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.compat; 2 | 3 | import link.infra.borderlessmining.config.ConfigHandler; 4 | import net.minecraft.client.MinecraftClient; 5 | import net.minecraft.text.Text; 6 | import net.puzzlemc.gui.PuzzleApi; 7 | import net.puzzlemc.gui.screen.widget.PuzzleWidget; 8 | 9 | import static net.puzzlemc.gui.PuzzleGui.NO; 10 | import static net.puzzlemc.gui.PuzzleGui.YES; 11 | 12 | public class BorderlessMiningCompat { 13 | public static void init() { 14 | PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.of("\uD83E\uDE9F Borderless Mining"))); 15 | ConfigHandler bmConfig = ConfigHandler.getInstance(); 16 | PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.translatable("config.borderlessmining.general.enabled"), (button) -> button.setMessage(bmConfig.isEnabledOrPending() ? YES : NO), (button) -> { 17 | bmConfig.setEnabledPending(!bmConfig.isEnabledOrPending()); 18 | bmConfig.save(); 19 | })); 20 | if (MinecraftClient.IS_SYSTEM_MAC) { 21 | PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.translatable("config.borderlessmining.general.enabledmac"), (button) -> button.setMessage(bmConfig.enableMacOS ? YES : NO), (button) -> { 22 | bmConfig.enableMacOS = !bmConfig.enableMacOS; 23 | bmConfig.setEnabledPending(bmConfig.isEnabled()); 24 | bmConfig.save(); 25 | })); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/compat/CITRCompat.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.compat; 2 | 3 | import net.minecraft.client.MinecraftClient; 4 | import net.minecraft.text.Text; 5 | import net.minecraft.util.Formatting; 6 | import net.puzzlemc.gui.PuzzleApi; 7 | import net.puzzlemc.gui.screen.widget.PuzzleWidget; 8 | import shcm.shsupercm.fabric.citresewn.config.CITResewnConfig; 9 | 10 | import static net.minecraft.screen.ScreenTexts.NO; 11 | import static net.minecraft.screen.ScreenTexts.YES; 12 | 13 | public class CITRCompat { 14 | public static void init() { 15 | if (CITResewnConfig.INSTANCE != null) { 16 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("⛏ CIT Resewn"))); 17 | CITResewnConfig citConfig = CITResewnConfig.INSTANCE; 18 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.citresewn.enabled.title"), (button) -> button.setMessage(citConfig.enabled ? YES : NO), (button) -> { 19 | citConfig.enabled = !citConfig.enabled; 20 | citConfig.write(); 21 | MinecraftClient.getInstance().reloadResources(); 22 | })); 23 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.citresewn.mute_errors.title"), (button) -> button.setMessage(citConfig.mute_errors ? YES : NO), (button) -> { 24 | citConfig.mute_errors = !citConfig.mute_errors; 25 | citConfig.write(); 26 | })); 27 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.citresewn.mute_warns.title"), (button) -> button.setMessage(citConfig.mute_warns ? YES : NO), (button) -> { 28 | citConfig.mute_warns = !citConfig.mute_warns; 29 | citConfig.write(); 30 | })); 31 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.citresewn.broken_paths.title"), (button) -> button.setMessage(citConfig.broken_paths ? YES : NO), (button) -> { 32 | citConfig.broken_paths = !citConfig.broken_paths; 33 | citConfig.write(); 34 | })); 35 | PuzzleApi.addToResourceOptions(new PuzzleWidget(0, 100, Text.translatable("config.citresewn.cache_ms.title"), () -> citConfig.cache_ms, 36 | (button) -> button.setMessage(message(citConfig)), 37 | (slider) -> { 38 | try { 39 | citConfig.cache_ms = slider.getInt(); 40 | } catch (NumberFormatException ignored) { 41 | } 42 | citConfig.write(); 43 | })); 44 | } 45 | } 46 | public static Text message(CITResewnConfig config) { 47 | int ticks = config.cache_ms; 48 | if (ticks <= 1) { 49 | return (Text.translatable("config.citresewn.cache_ms.ticks." + ticks)).formatted(Formatting.AQUA); 50 | } else { 51 | Formatting color = Formatting.DARK_RED; 52 | if (ticks <= 40) color = Formatting.RED; 53 | if (ticks <= 20) color = Formatting.GOLD; 54 | if (ticks <= 10) color = Formatting.DARK_GREEN; 55 | if (ticks <= 5) color = Formatting.GREEN; 56 | 57 | return (Text.translatable("config.citresewn.cache_ms.ticks.any", ticks)).formatted(color); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/compat/ColormaticCompat.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.compat; 2 | 3 | import io.github.kvverti.colormatic.Colormatic; 4 | import io.github.kvverti.colormatic.ColormaticConfig; 5 | import io.github.kvverti.colormatic.ColormaticConfigController; 6 | import net.minecraft.text.Text; 7 | import net.puzzlemc.gui.PuzzleApi; 8 | import net.puzzlemc.gui.screen.widget.PuzzleWidget; 9 | 10 | import static net.puzzlemc.gui.PuzzleGui.NO; 11 | import static net.puzzlemc.gui.PuzzleGui.YES; 12 | 13 | public class ColormaticCompat { 14 | public static void init() { 15 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("\uD83C\uDF08 Colormatic"))); 16 | ColormaticConfig colormaticConfig = Colormatic.config(); 17 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("colormatic.config.option.clearSky"), (button) -> button.setMessage(colormaticConfig.clearSky ? YES : NO), (button) -> { 18 | colormaticConfig.clearSky = !colormaticConfig.clearSky; 19 | ColormaticConfigController.persist(colormaticConfig); 20 | })); 21 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("colormatic.config.option.clearVoid"), (button) -> button.setMessage(colormaticConfig.clearVoid ? YES : NO), (button) -> { 22 | colormaticConfig.clearVoid = !colormaticConfig.clearVoid; 23 | ColormaticConfigController.persist(colormaticConfig); 24 | })); 25 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("colormatic.config.option.blendSkyLight"), (button) -> button.setMessage(colormaticConfig.blendSkyLight ? YES : NO), (button) -> { 26 | colormaticConfig.blendSkyLight = !colormaticConfig.blendSkyLight; 27 | ColormaticConfigController.persist(colormaticConfig); 28 | })); 29 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("colormatic.config.option.flickerBlockLight"), (button) -> button.setMessage(colormaticConfig.flickerBlockLight ? YES : NO), (button) -> { 30 | colormaticConfig.flickerBlockLight = !colormaticConfig.flickerBlockLight; 31 | ColormaticConfigController.persist(colormaticConfig); 32 | })); 33 | PuzzleApi.addToResourceOptions(new PuzzleWidget(0, 100, Text.translatable("colormatic.config.option.relativeBlockLightIntensity"), 34 | () -> (int) (100*(1.0 - colormaticConfig.relativeBlockLightIntensityExponent / -16.0)), 35 | (button) -> button.setMessage(Text.translatable("colormatic.config.option.relativeBlockLightIntensity") 36 | .append(": ") 37 | .append(Text.literal(String.valueOf((int)(100 * Math.exp(ColormaticConfig.scaled(colormaticConfig.relativeBlockLightIntensityExponent))))).append("%"))), 38 | (slider) -> { 39 | try { 40 | colormaticConfig.relativeBlockLightIntensityExponent = ((1.00 - ((slider.getInt())/100f)) * -16.0); 41 | ColormaticConfigController.persist(colormaticConfig); 42 | } 43 | catch (NumberFormatException ignored) {} 44 | })); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/compat/ContinuityCompat.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.compat; 2 | 3 | import me.pepperbell.continuity.client.config.ContinuityConfig; 4 | import me.pepperbell.continuity.client.config.Option; 5 | import net.minecraft.text.Text; 6 | import net.puzzlemc.gui.PuzzleApi; 7 | import net.puzzlemc.gui.screen.widget.PuzzleWidget; 8 | 9 | import static net.puzzlemc.gui.PuzzleGui.NO; 10 | import static net.puzzlemc.gui.PuzzleGui.YES; 11 | 12 | public class ContinuityCompat { 13 | public static void init() { 14 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("▒ Continuity"))); 15 | ContinuityConfig contConfig = ContinuityConfig.INSTANCE; 16 | contConfig.getOptionMapView().forEach((s, option) -> { 17 | if (s.equals("use_manual_culling")) return; 18 | try { 19 | Option.BooleanOption booleanOption = ((Option.BooleanOption)option); 20 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("options.continuity."+s), (button) -> button.setMessage(booleanOption.get() ? YES : NO), (button) -> { 21 | booleanOption.set(!booleanOption.get()); 22 | contConfig.save(); 23 | })); 24 | } catch (Exception ignored) {} 25 | }); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/compat/CullLeavesCompat.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.compat; 2 | 3 | import eu.midnightdust.cullleaves.config.CullLeavesConfig; 4 | import net.minecraft.client.MinecraftClient; 5 | import net.minecraft.text.Text; 6 | import net.puzzlemc.gui.PuzzleApi; 7 | import net.puzzlemc.gui.screen.widget.PuzzleWidget; 8 | 9 | import static net.puzzlemc.gui.PuzzleGui.NO; 10 | import static net.puzzlemc.gui.PuzzleGui.YES; 11 | 12 | public class CullLeavesCompat { 13 | public static void init() { 14 | PuzzleApi.addToPerformanceOptions(new PuzzleWidget(Text.of("\uD83C\uDF43 Cull Leaves"))); 15 | PuzzleApi.addToPerformanceOptions(new PuzzleWidget(Text.translatable("cullleaves.puzzle.option.enabled"), (button) -> button.setMessage(CullLeavesConfig.enabled ? YES : NO), (button) -> { 16 | CullLeavesConfig.enabled = !CullLeavesConfig.enabled; 17 | CullLeavesConfig.write("cullleaves"); 18 | MinecraftClient.getInstance().worldRenderer.reload(); 19 | })); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/compat/EMFCompat.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.compat; 2 | 3 | import eu.midnightdust.lib.util.PlatformFunctions; 4 | import net.minecraft.screen.ScreenTexts; 5 | import net.minecraft.text.Text; 6 | import net.puzzlemc.gui.PuzzleApi; 7 | import net.puzzlemc.gui.screen.widget.PuzzleWidget; 8 | import traben.entity_model_features.EMF; 9 | import traben.entity_model_features.config.EMFConfig; 10 | 11 | import java.util.EnumSet; 12 | import java.util.NavigableSet; 13 | import java.util.Objects; 14 | import java.util.TreeSet; 15 | 16 | public class EMFCompat { 17 | public static void init() { 18 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.literal("\uD83D\uDC37 ").append(Text.translatable("entity_model_features.title")))); 19 | EMFConfig emfConfig = EMF.config().getConfig(); 20 | if (PlatformFunctions.isModLoaded("physicsmod")) { 21 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("entity_model_features.config.physics"), (button) -> button.setMessage(emfConfig.attemptPhysicsModPatch_2 != EMFConfig.PhysicsModCompatChoice.OFF ? 22 | Text.translatable("entity_model_features.config." + (emfConfig.attemptPhysicsModPatch_2 == EMFConfig.PhysicsModCompatChoice.VANILLA ? "physics.1" : "physics.2")) : ScreenTexts.OFF), (button) -> { 23 | final NavigableSet set = 24 | new TreeSet<>(EnumSet.allOf(EMFConfig.PhysicsModCompatChoice.class)); 25 | 26 | emfConfig.attemptPhysicsModPatch_2 = Objects.requireNonNullElseGet( 27 | set.higher(emfConfig.attemptPhysicsModPatch_2), set::first); 28 | EMF.config().saveToFile(); 29 | })); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/compat/ETFCompat.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.compat; 2 | 3 | import net.minecraft.text.Text; 4 | import net.puzzlemc.gui.PuzzleApi; 5 | import net.puzzlemc.gui.screen.widget.PuzzleWidget; 6 | import traben.entity_texture_features.ETFApi; 7 | import traben.entity_texture_features.config.ETFConfig; 8 | 9 | import java.util.EnumSet; 10 | import java.util.NavigableSet; 11 | import java.util.Objects; 12 | import java.util.TreeSet; 13 | 14 | import static net.puzzlemc.gui.PuzzleGui.NO; 15 | import static net.puzzlemc.gui.PuzzleGui.YES; 16 | 17 | public class ETFCompat { 18 | public static void init() { 19 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.literal("\uD83D\uDC2E ").append(Text.translatable("config.entity_texture_features.title")))); 20 | ETFConfig etfConfig = ETFApi.getETFConfigObject(); 21 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.enable_custom_textures.title"), (button) -> button.setMessage(etfConfig.enableCustomTextures ? YES : NO), (button) -> { 22 | etfConfig.enableCustomTextures = !etfConfig.enableCustomTextures; 23 | ETFApi.saveETFConfigChangesAndResetETF(); 24 | })); 25 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.enable_emissive_textures.title"), (button) -> button.setMessage(etfConfig.enableEmissiveTextures ? YES : NO), (button) -> { 26 | etfConfig.enableEmissiveTextures = !etfConfig.enableEmissiveTextures; 27 | ETFApi.saveETFConfigChangesAndResetETF(); 28 | })); 29 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.emissive_mode.title"), (button) -> button.setMessage( 30 | Text.literal(etfConfig.emissiveRenderMode.toString())), (button) -> { 31 | final NavigableSet set = 32 | new TreeSet<>(EnumSet.allOf(ETFConfig.EmissiveRenderModes.class)); 33 | 34 | etfConfig.emissiveRenderMode = Objects.requireNonNullElseGet( 35 | set.higher(etfConfig.emissiveRenderMode), set::first); 36 | ETFApi.saveETFConfigChangesAndResetETF(); 37 | })); 38 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.blinking_mob_settings.title"), (button) -> button.setMessage(etfConfig.enableBlinking ? YES : NO), (button) -> { 39 | etfConfig.enableBlinking = !etfConfig.enableBlinking; 40 | ETFApi.saveETFConfigChangesAndResetETF(); 41 | })); 42 | PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.player_skin_features.title"), (button) -> button.setMessage(etfConfig.skinFeaturesEnabled ? YES : NO), (button) -> { 43 | etfConfig.skinFeaturesEnabled = !etfConfig.skinFeaturesEnabled; 44 | ETFApi.saveETFConfigChangesAndResetETF(); 45 | })); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/compat/IrisCompat.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.compat; 2 | 3 | import net.irisshaders.iris.api.v0.IrisApi; 4 | import net.irisshaders.iris.api.v0.IrisApiConfig; 5 | import net.minecraft.client.MinecraftClient; 6 | import net.minecraft.client.gui.screen.Screen; 7 | import net.minecraft.text.Text; 8 | import net.minecraft.util.Formatting; 9 | import net.puzzlemc.gui.PuzzleApi; 10 | import net.puzzlemc.gui.PuzzleGui; 11 | import net.puzzlemc.gui.screen.widget.PuzzleWidget; 12 | 13 | public class IrisCompat { 14 | public static void init() { 15 | PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.of("\uD83D\uDC41 Iris"))); 16 | PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("iris.puzzle.option.enableShaders"), (button) -> button.setMessage(IrisApi.getInstance().getConfig().areShadersEnabled() ? PuzzleGui.YES : PuzzleGui.NO), (button) -> { 17 | IrisApiConfig irisConfig = IrisApi.getInstance().getConfig(); 18 | irisConfig.setShadersEnabledAndApply(!irisConfig.areShadersEnabled()); 19 | })); 20 | PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("options.iris.shaderPackSelection.title"), (button) -> button.setMessage(Text.literal("➥ ").append(Text.translatable("iris.puzzle.option.open").formatted(Formatting.GOLD))), (button) -> { 21 | MinecraftClient client = MinecraftClient.getInstance(); 22 | client.setScreen((Screen) IrisApi.getInstance().openMainIrisScreenObj(client.currentScreen)); 23 | })); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/compat/LBGCompat.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.compat; 2 | 3 | import dev.lambdaurora.lambdabettergrass.LBGConfig; 4 | import dev.lambdaurora.lambdabettergrass.LambdaBetterGrass; 5 | import net.minecraft.text.Text; 6 | import net.puzzlemc.gui.PuzzleApi; 7 | import net.puzzlemc.gui.screen.widget.PuzzleWidget; 8 | 9 | import static net.puzzlemc.gui.PuzzleGui.NO; 10 | import static net.puzzlemc.gui.PuzzleGui.YES; 11 | 12 | public class LBGCompat { 13 | public static void init() { 14 | LBGConfig lbgConfig = LambdaBetterGrass.get().config; 15 | PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.of("\uD83C\uDF31 LambdaBetterGrass"))); 16 | PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("lambdabettergrass.option.mode"), (button) -> button.setMessage(lbgConfig.getMode().getTranslatedText()), (button) -> lbgConfig.setMode(lbgConfig.getMode().next()))); 17 | PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("lambdabettergrass.option.better_snow"), (button) -> button.setMessage(lbgConfig.hasBetterLayer() ? YES : NO), (button) -> lbgConfig.setBetterLayer(!lbgConfig.hasBetterLayer()))); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/compat/LDLCompat.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.compat; 2 | 3 | import dev.lambdaurora.lambdynlights.DynamicLightsConfig; 4 | import dev.lambdaurora.lambdynlights.LambDynLights; 5 | import net.minecraft.text.Text; 6 | import net.puzzlemc.gui.PuzzleApi; 7 | import net.puzzlemc.gui.screen.widget.PuzzleWidget; 8 | 9 | import static net.puzzlemc.gui.PuzzleGui.NO; 10 | import static net.puzzlemc.gui.PuzzleGui.YES; 11 | 12 | public class LDLCompat { 13 | public static void init() { 14 | DynamicLightsConfig ldlConfig = LambDynLights.get().config; 15 | 16 | PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.of("\uD83D\uDCA1 LambDynamicLights"))); 17 | PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("lambdynlights.option.mode"), (button) -> button.setMessage(ldlConfig.getDynamicLightsMode().getTranslatedText()), (button) -> ldlConfig.setDynamicLightsMode(ldlConfig.getDynamicLightsMode().next()))); 18 | PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.empty().append("DynLights: ").append(Text.translatable("lambdynlights.option.light_sources.entities")), (button) -> button.setMessage(ldlConfig.getEntitiesLightSource().get() ? YES : NO), (button) -> ldlConfig.getEntitiesLightSource().set(!ldlConfig.getEntitiesLightSource().get()))); 19 | PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.empty().append("DynLights: ").append(Text.translatable("entity.minecraft.creeper")), (button) -> button.setMessage(ldlConfig.getCreeperLightingMode().getTranslatedText()), (button) -> ldlConfig.setCreeperLightingMode(ldlConfig.getCreeperLightingMode().next()))); 20 | PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.empty().append("DynLights: ").append(Text.translatable("block.minecraft.tnt")), (button) -> button.setMessage(ldlConfig.getTntLightingMode().getTranslatedText()), (button) -> ldlConfig.setTntLightingMode(ldlConfig.getTntLightingMode().next()))); 21 | PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.empty().append("DynLights: ").append(Text.translatable("lambdynlights.option.light_sources.water_sensitive_check")), (button) -> button.setMessage(ldlConfig.getWaterSensitiveCheck().get() ? YES : NO), (button) -> ldlConfig.getWaterSensitiveCheck().set(!ldlConfig.getWaterSensitiveCheck().get()))); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/mixin/MixinOptionsScreen.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.mixin; 2 | 3 | import eu.midnightdust.core.config.MidnightLibConfig; 4 | import eu.midnightdust.lib.util.PlatformFunctions; 5 | import net.minecraft.client.gui.widget.TextIconButtonWidget; 6 | import net.minecraft.client.gui.widget.ThreePartsLayoutWidget; 7 | import net.puzzlemc.core.config.PuzzleConfig; 8 | import net.puzzlemc.gui.PuzzleGui; 9 | import net.puzzlemc.gui.screen.PuzzleOptionsScreen; 10 | import net.minecraft.client.gui.screen.Screen; 11 | import net.minecraft.client.gui.screen.option.OptionsScreen; 12 | import net.minecraft.text.Text; 13 | import org.spongepowered.asm.mixin.Final; 14 | import org.spongepowered.asm.mixin.Mixin; 15 | import org.spongepowered.asm.mixin.Shadow; 16 | import org.spongepowered.asm.mixin.Unique; 17 | import org.spongepowered.asm.mixin.injection.At; 18 | import org.spongepowered.asm.mixin.injection.Inject; 19 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 20 | 21 | import java.util.Objects; 22 | 23 | @Mixin(OptionsScreen.class) 24 | public abstract class MixinOptionsScreen extends Screen { 25 | @Shadow @Final private ThreePartsLayoutWidget layout; 26 | @Unique TextIconButtonWidget puzzle$button = TextIconButtonWidget.builder(Text.translatable("puzzle.screen.title"), (buttonWidget) -> 27 | (Objects.requireNonNull(this.client)).setScreen(new PuzzleOptionsScreen(this)), true) 28 | .dimension(20, 20).texture(PuzzleGui.PUZZLE_BUTTON, 20, 20).build(); 29 | 30 | private MixinOptionsScreen(Text title) {super(title);} 31 | 32 | @Inject(at = @At("HEAD"), method = "init") 33 | public void puzzle$onInit(CallbackInfo ci) { 34 | if (PuzzleConfig.enablePuzzleButton) { 35 | this.puzzle$setButtonPos(); 36 | this.addDrawableChild(puzzle$button); 37 | } 38 | } 39 | 40 | @Inject(at = @At("TAIL"), method = "refreshWidgetPositions") 41 | public void puzzle$onResize(CallbackInfo ci) { 42 | if (PuzzleConfig.enablePuzzleButton) this.puzzle$setButtonPos(); 43 | } 44 | 45 | @Unique 46 | public void puzzle$setButtonPos() { 47 | int i = 0; 48 | if (PlatformFunctions.isModLoaded("lod")) i = i + 358; 49 | if (MidnightLibConfig.config_screen_list.equals(MidnightLibConfig.ConfigButton.FALSE)) i = i - 25; 50 | puzzle$button.setPosition(this.width / 2 - 178 + i, layout.getY() + layout.getFooterHeight() - 4); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/screen/PuzzleOptionsScreen.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.screen; 2 | 3 | import com.google.common.collect.Lists; 4 | import net.minecraft.client.gui.tab.GridScreenTab; 5 | import net.minecraft.client.gui.tab.Tab; 6 | import net.minecraft.client.gui.tab.TabManager; 7 | import net.minecraft.client.gui.widget.TabNavigationWidget; 8 | import net.minecraft.screen.ScreenTexts; 9 | import net.minecraft.text.Text; 10 | import net.puzzlemc.gui.PuzzleApi; 11 | import net.puzzlemc.gui.PuzzleGui; 12 | import net.puzzlemc.gui.screen.widget.*; 13 | import net.minecraft.client.gui.screen.Screen; 14 | import net.minecraft.client.gui.widget.ButtonWidget; 15 | 16 | import java.util.List; 17 | import java.util.Objects; 18 | 19 | public class PuzzleOptionsScreen extends Screen { 20 | public PuzzleOptionListWidget list; 21 | public List tooltip = null; 22 | public TabManager tabManager = new TabManager(a -> {}, a -> {}); 23 | public Tab prevTab; 24 | public TabNavigationWidget tabNavigation; 25 | public static Text graphicsTab = Text.translatable("puzzle.page.graphics"); 26 | public static Text miscTab = Text.translatable("puzzle.page.misc"); 27 | public static Text performanceTab = Text.translatable("puzzle.page.performance"); 28 | public static Text resourcesTab = Text.translatable("puzzle.page.resources"); 29 | 30 | public PuzzleOptionsScreen(Screen parent) { 31 | super(Text.translatable("puzzle.screen.title")); 32 | this.parent = parent; 33 | } 34 | private final Screen parent; 35 | 36 | @Override 37 | protected void init() { 38 | if (!PuzzleGui.lateInitDone) PuzzleGui.lateInit(); 39 | 40 | List tabs = Lists.newArrayList(); 41 | if (!PuzzleApi.GRAPHICS_OPTIONS.isEmpty()) tabs.add(new GridScreenTab(graphicsTab)); 42 | if (!PuzzleApi.RESOURCE_OPTIONS.isEmpty()) tabs.add(new GridScreenTab(resourcesTab)); 43 | if (!PuzzleApi.PERFORMANCE_OPTIONS.isEmpty()) tabs.add(new GridScreenTab(performanceTab)); 44 | if (!PuzzleApi.MISC_OPTIONS.isEmpty()) tabs.add(new GridScreenTab(miscTab)); 45 | 46 | tabNavigation = TabNavigationWidget.builder(tabManager, this.width).tabs(tabs.toArray(new Tab[0])).build(); 47 | tabNavigation.selectTab(0, false); 48 | tabNavigation.init(); 49 | prevTab = tabManager.getCurrentTab(); 50 | 51 | this.list = new PuzzleOptionListWidget(this.client, this.width, this.height - 57, 24, 25); 52 | fillList(); 53 | 54 | if (tabs.size() > 1) { 55 | this.addDrawableChild(tabNavigation); 56 | list.renderHeaderSeparator = false; 57 | } 58 | 59 | this.addDrawableChild(list); 60 | 61 | super.init(); 62 | this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, (button) -> Objects.requireNonNull(client).setScreen(parent)).dimensions(this.width / 2 - 100, this.height - 26, 200, 20).build()); 63 | } 64 | private void fillList() { 65 | List options = List.of(); 66 | if (tabManager.getCurrentTab() == null) return; 67 | else { 68 | Text title = tabManager.getCurrentTab().getTitle(); 69 | if (title.equals(graphicsTab)) options = PuzzleApi.GRAPHICS_OPTIONS; 70 | else if (title.equals(miscTab)) options = PuzzleApi.MISC_OPTIONS; 71 | else if (title.equals(performanceTab)) 72 | options = PuzzleApi.PERFORMANCE_OPTIONS; 73 | else if (title.equals(resourcesTab)) options = PuzzleApi.RESOURCE_OPTIONS; 74 | } 75 | list.addAll(options); 76 | } 77 | @Override 78 | public boolean keyPressed(int keyCode, int scanCode, int modifiers) { 79 | if (this.tabNavigation.trySwitchTabsWithKey(keyCode)) return true; 80 | return super.keyPressed(keyCode, scanCode, modifiers); 81 | } 82 | @Override 83 | public void tick() { 84 | super.tick(); 85 | if (prevTab != null && prevTab != tabManager.getCurrentTab()) { 86 | prevTab = tabManager.getCurrentTab(); 87 | this.list.clear(); 88 | fillList(); 89 | list.setScrollY(0); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/screen/widget/ButtonType.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.screen.widget; 2 | 3 | public enum ButtonType { 4 | TEXT, BUTTON, SLIDER, TEXT_FIELD 5 | } 6 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleButtonWidget.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.screen.widget; 2 | 3 | import net.minecraft.client.gui.DrawContext; 4 | import net.minecraft.client.gui.widget.ButtonWidget; 5 | import net.minecraft.text.Text; 6 | 7 | import java.util.function.Supplier; 8 | 9 | public class PuzzleButtonWidget extends ButtonWidget { 10 | private final PuzzleWidget.TextAction title; 11 | 12 | public PuzzleButtonWidget(int x, int y, int width, int height, PuzzleWidget.TextAction title, PressAction onPress) { 13 | super(x, y, width, height, Text.of(""), onPress, Supplier::get); 14 | this.title = title; 15 | } 16 | @Override 17 | public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { 18 | try { title.setTitle(this); 19 | } catch (Exception e) {e.fillInStackTrace(); this.visible = false;} 20 | super.renderWidget(context, mouseX, mouseY, delta); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleOptionListWidget.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.screen.widget; 2 | 3 | import eu.midnightdust.lib.config.MidnightConfig; 4 | import net.fabricmc.api.EnvType; 5 | import net.fabricmc.api.Environment; 6 | import net.minecraft.client.MinecraftClient; 7 | import net.minecraft.client.font.TextRenderer; 8 | import net.minecraft.client.gui.DrawContext; 9 | import net.minecraft.client.gui.widget.ClickableWidget; 10 | import net.minecraft.client.resource.language.I18n; 11 | import net.minecraft.text.Text; 12 | import net.minecraft.text.TranslatableTextContent; 13 | import net.minecraft.util.Formatting; 14 | import net.puzzlemc.gui.screen.PuzzleOptionsScreen; 15 | 16 | import java.lang.annotation.Annotation; 17 | import java.util.ArrayList; 18 | import java.util.List; 19 | 20 | import static net.puzzlemc.core.PuzzleCore.LOGGER; 21 | 22 | @Environment(EnvType.CLIENT) 23 | public class PuzzleOptionListWidget extends MidnightConfig.MidnightConfigListWidget { 24 | TextRenderer textRenderer; 25 | 26 | public PuzzleOptionListWidget(MinecraftClient minecraftClient, int i, int j, int k, int l) { 27 | super(minecraftClient, i, j, k, l); 28 | this.centerListVertically = false; 29 | textRenderer = minecraftClient.textRenderer; 30 | } 31 | 32 | public void addAll(List buttons) { 33 | int buttonX = this.width - 160; 34 | for (PuzzleWidget button : buttons) { 35 | try { 36 | if (button.buttonType == ButtonType.TEXT) 37 | this.addButton(List.of(), Text.literal("").append(button.descriptionText).formatted(Formatting.BOLD)); 38 | else if (button.buttonType == ButtonType.BUTTON) 39 | this.addButton(List.of(new PuzzleButtonWidget(buttonX, 0, 150, 20, button.buttonTextAction, button.onPress)), button.descriptionText); 40 | else if (button.buttonType == ButtonType.SLIDER) 41 | this.addButton(List.of(new PuzzleSliderWidget(button.min, button.max, buttonX, 0, 150, 20, button.defaultSliderValue.getAsInt(), button.buttonTextAction, button.changeSliderValue)), button.descriptionText); 42 | else if (button.buttonType == ButtonType.TEXT_FIELD) 43 | this.addButton(List.of(new PuzzleTextFieldWidget(textRenderer, buttonX, 0, 150, 20, button.setTextValue, button.changeTextValue)), button.descriptionText); 44 | else 45 | LOGGER.warn("Button {} is missing the buttonType variable. This shouldn't happen!", button); 46 | } 47 | catch (Exception e) { 48 | LOGGER.error("Failed to add button {}. Likely caused by an update of the specific mod.", button.descriptionText); 49 | } 50 | 51 | } 52 | } 53 | public void addButton(List buttons, Text text) { 54 | MidnightConfig.EntryInfo info = new MidnightConfig.EntryInfo(null, "puzzle"); 55 | if (buttons.isEmpty()) info.comment = new MidnightConfig.Comment(){ 56 | public Class annotationType() {return null;} 57 | public boolean centered() {return true;} 58 | public String category() {return "";} 59 | public String name() {return "";} 60 | public String requiredMod() {return "";} 61 | }; 62 | var entry = new MidnightConfig.ButtonEntry(buttons, text, info); 63 | this.addEntry(entry); 64 | } 65 | public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) { 66 | super.renderWidget(context, mouseX, mouseY, delta); 67 | MidnightConfig.ButtonEntry e = this.getHoveredEntry(); 68 | if (client.currentScreen instanceof PuzzleOptionsScreen page && e != null && !e.buttons.isEmpty() && 69 | e.text.getContent() instanceof TranslatableTextContent content) { 70 | ClickableWidget button = e.buttons.getFirst(); 71 | String key = null; 72 | if (I18n.hasTranslation(content.getKey() + ".tooltip")) key = content.getKey() + ".tooltip"; 73 | else if (I18n.hasTranslation(content.getKey() + ".desc")) key = content.getKey() + ".desc"; 74 | if (key == null && content.getKey().endsWith(".title")) { 75 | String strippedContent = content.getKey().substring(0, content.getKey().length()-6); 76 | if (I18n.hasTranslation(strippedContent + ".tooltip")) key = strippedContent + ".tooltip"; 77 | else if (I18n.hasTranslation(strippedContent + ".desc")) key = strippedContent + ".desc"; 78 | } 79 | 80 | if (key != null) { 81 | List list = new ArrayList<>(); 82 | for (String str : I18n.translate(key).split("\n")) 83 | list.add(Text.literal(str)); 84 | page.tooltip = list; 85 | if (!button.isMouseOver(mouseX, mouseY)) { 86 | context.drawTooltip(textRenderer, list, button.getX(), button.getY() + (button.getHeight() * 2)); 87 | } 88 | else context.drawTooltip(textRenderer, list, mouseX, mouseY); 89 | } 90 | } 91 | } 92 | 93 | @Override 94 | public MidnightConfig.ButtonEntry getHoveredEntry() { 95 | return super.getHoveredEntry(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleSliderWidget.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.screen.widget; 2 | 3 | import net.minecraft.client.gui.widget.SliderWidget; 4 | import net.minecraft.text.Text; 5 | 6 | public class PuzzleSliderWidget extends SliderWidget { 7 | private final int min; 8 | private final int max; 9 | private final PuzzleWidget.TextAction setTextAction; 10 | private final PuzzleWidget.ChangeSliderValueAction changeAction; 11 | 12 | public PuzzleSliderWidget(int min, int max, int x, int y, int width, int height, float defaultValue, PuzzleWidget.TextAction setTextAction, PuzzleWidget.ChangeSliderValueAction changeAction) { 13 | super(x,y,width,height,Text.of(""),(defaultValue-min) / (max - min)); 14 | 15 | this.min = min; 16 | this.max = max; 17 | 18 | this.setTextAction = setTextAction; 19 | this.changeAction = changeAction; 20 | try { 21 | this.updateMessage(); 22 | } catch (Exception e) {e.fillInStackTrace(); this.visible = false;} 23 | } 24 | public int getInt() { 25 | int difference = max - min; 26 | int r = (int) (value * difference); 27 | return r + min; 28 | } 29 | public void setInt(int v) { 30 | value = value / v - value * min; 31 | } 32 | 33 | @Override 34 | protected void updateMessage() { 35 | this.setTextAction.setTitle(this); 36 | } 37 | 38 | @Override 39 | protected void applyValue() { 40 | this.changeAction.onChange(this); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleTextFieldWidget.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.screen.widget; 2 | 3 | import net.minecraft.client.font.TextRenderer; 4 | import net.minecraft.client.gui.widget.TextFieldWidget; 5 | import net.minecraft.text.Text; 6 | 7 | public class PuzzleTextFieldWidget extends TextFieldWidget { 8 | private final PuzzleWidget.SetTextValueAction setValueAction; 9 | private final PuzzleWidget.ChangeTextValueAction change; 10 | 11 | public PuzzleTextFieldWidget(TextRenderer textRenderer, int x, int y, int width, int height, PuzzleWidget.SetTextValueAction setValue, PuzzleWidget.ChangeTextValueAction change) { 12 | super(textRenderer, x, y, width, height, Text.of("")); 13 | this.setValueAction = setValue; 14 | this.change = change; 15 | try { 16 | setValueAction.setTextValue(this); 17 | } catch (Exception e) {e.fillInStackTrace(); this.setVisible(false);} 18 | } 19 | @Override 20 | public void write(String text) { 21 | super.write(text); 22 | this.change.onChange(this); 23 | setValueAction.setTextValue(this); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleWidget.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.gui.screen.widget; 2 | 3 | import net.minecraft.client.gui.widget.ButtonWidget; 4 | import net.minecraft.client.gui.widget.ClickableWidget; 5 | import net.minecraft.client.gui.widget.TextFieldWidget; 6 | import net.minecraft.text.Text; 7 | 8 | import java.util.function.IntSupplier; 9 | 10 | public class PuzzleWidget { 11 | public ButtonType buttonType; 12 | public int min; 13 | public int max; 14 | public Text descriptionText; 15 | public TextAction buttonTextAction; 16 | public ButtonWidget.PressAction onPress; 17 | public PuzzleWidget.SetTextValueAction setTextValue; 18 | public IntSupplier defaultSliderValue; 19 | public PuzzleWidget.ChangeTextValueAction changeTextValue; 20 | public PuzzleWidget.ChangeSliderValueAction changeSliderValue; 21 | 22 | /** 23 | * Puzzle Text Widget Container 24 | * @param descriptionText The text you want to display. 25 | */ 26 | public PuzzleWidget(Text descriptionText) { 27 | this.buttonType = ButtonType.TEXT; 28 | this.descriptionText = descriptionText; 29 | } 30 | 31 | /** 32 | * Puzzle Button Widget Container 33 | * @param descriptionText Tells the user what the option does. 34 | * @param getTitle Function to set the text on the button. 35 | * @param onPress Function to call when the user presses the button. 36 | */ 37 | public PuzzleWidget(Text descriptionText, PuzzleWidget.TextAction getTitle, ButtonWidget.PressAction onPress) { 38 | this.buttonType = ButtonType.BUTTON; 39 | this.descriptionText = descriptionText; 40 | this.buttonTextAction = getTitle; 41 | this.onPress = onPress; 42 | } 43 | /** 44 | * Puzzle Slider Widget Container 45 | */ 46 | public PuzzleWidget(int min, int max, Text descriptionText, IntSupplier defaultSliderValue, PuzzleWidget.TextAction setTextAction, PuzzleWidget.ChangeSliderValueAction changeAction) { 47 | this.buttonType = ButtonType.SLIDER; 48 | this.min = min; 49 | this.max = max; 50 | this.descriptionText = descriptionText; 51 | this.defaultSliderValue = defaultSliderValue; 52 | this.buttonTextAction = setTextAction; 53 | this.changeSliderValue = changeAction; 54 | } 55 | /** 56 | * Puzzle Text Field Widget Container (WIP - Doesn't work) 57 | */ 58 | public PuzzleWidget(int min, int max, Text descriptionText, PuzzleWidget.SetTextValueAction setValue, ChangeTextValueAction changeAction) { 59 | this.buttonType = ButtonType.TEXT_FIELD; 60 | this.min = min; 61 | this.max = max; 62 | this.descriptionText = descriptionText; 63 | this.setTextValue = setValue; 64 | this.changeTextValue = changeAction; 65 | } 66 | public interface ChangeTextValueAction { 67 | void onChange(TextFieldWidget textField); 68 | } 69 | public interface ChangeSliderValueAction { 70 | void onChange(PuzzleSliderWidget slider); 71 | } 72 | public interface SetTextValueAction { 73 | void setTextValue(TextFieldWidget textField); 74 | } 75 | public interface TextAction { 76 | void setTitle(ClickableWidget button); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/models/mixin/MixinModelElementDeserializer.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.models.mixin; 2 | 3 | import com.google.gson.JsonObject; 4 | import com.google.gson.JsonParseException; 5 | import net.minecraft.client.render.model.json.ModelElement; 6 | import net.minecraft.util.JsonHelper; 7 | import net.puzzlemc.core.config.PuzzleConfig; 8 | import org.joml.Vector3f; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.Shadow; 11 | import org.spongepowered.asm.mixin.injection.At; 12 | import org.spongepowered.asm.mixin.injection.Inject; 13 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; 14 | 15 | @Mixin(ModelElement.Deserializer.class) 16 | public abstract class MixinModelElementDeserializer { 17 | @Shadow protected abstract Vector3f deserializeVec3f(JsonObject object, String name); 18 | 19 | @Inject(at = @At("HEAD"),method = "deserializeRotationAngle", cancellable = true) 20 | private void puzzle$deserializeRotationAngle(JsonObject object, CallbackInfoReturnable cir) { 21 | if (PuzzleConfig.unlimitedRotations) { 22 | float angle = JsonHelper.getFloat(object, "angle"); 23 | cir.setReturnValue(angle); 24 | } 25 | } 26 | @Inject(at = @At("HEAD"),method = "deserializeTo", cancellable = true) 27 | private void puzzle$deserializeTo(JsonObject object, CallbackInfoReturnable cir) { 28 | if (PuzzleConfig.biggerModels) { 29 | Vector3f vec3f = this.deserializeVec3f(object, "to"); 30 | if (!(vec3f.x < -32.0F) && !(vec3f.y < -32.0F) && !(vec3f.z < -32.0F) && !(vec3f.x > 48.0F) && !(vec3f.y > 48.0F) && !(vec3f.z > 48.0F)) { 31 | cir.setReturnValue(vec3f); 32 | } else { 33 | throw new JsonParseException("'to' specifier exceeds the allowed boundaries: " + vec3f); 34 | } 35 | } 36 | } 37 | @Inject(at = @At("HEAD"),method = "deserializeFrom", cancellable = true) 38 | private void puzzle$deserializeFrom(JsonObject object, CallbackInfoReturnable cir) { 39 | if (PuzzleConfig.biggerModels) { 40 | Vector3f vec3f = this.deserializeVec3f(object, "from"); 41 | if (!(vec3f.x < -32.0F) && !(vec3f.y < -32.0F) && !(vec3f.z < -32.0F) && !(vec3f.x > 48.0F) && !(vec3f.y > 48.0F) && !(vec3f.z > 48.0F)) { 42 | cir.setReturnValue(vec3f); 43 | } else { 44 | throw new JsonParseException("'from' specifier exceeds the allowed boundaries: " + vec3f); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/splashscreen/PuzzleSplashScreen.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.splashscreen; 2 | 3 | import com.mojang.blaze3d.pipeline.BlendFunction; 4 | import com.mojang.blaze3d.pipeline.RenderPipeline; 5 | import com.mojang.blaze3d.platform.DepthTestFunction; 6 | import com.mojang.blaze3d.platform.DestFactor; 7 | import com.mojang.blaze3d.platform.SourceFactor; 8 | import eu.midnightdust.lib.util.MidnightColorUtil; 9 | import eu.midnightdust.lib.util.PlatformFunctions; 10 | import net.minecraft.client.gui.screen.SplashOverlay; 11 | import net.minecraft.client.render.RenderLayer; 12 | import net.minecraft.client.render.RenderPhase; 13 | import net.minecraft.client.texture.NativeImageBackedTexture; 14 | import net.minecraft.client.texture.TextureContents; 15 | import net.minecraft.resource.*; 16 | import net.minecraft.util.TriState; 17 | import net.minecraft.util.Util; 18 | import net.puzzlemc.core.config.PuzzleConfig; 19 | import net.minecraft.client.MinecraftClient; 20 | import net.minecraft.client.resource.metadata.TextureResourceMetadata; 21 | import net.minecraft.client.texture.NativeImage; 22 | import net.minecraft.client.texture.ResourceTexture; 23 | import net.minecraft.util.Identifier; 24 | import net.puzzlemc.splashscreen.mixin.RenderPipelinesAccessor; 25 | 26 | import java.io.File; 27 | import java.io.FileInputStream; 28 | import java.io.IOException; 29 | import java.io.InputStream; 30 | import java.nio.file.Files; 31 | import java.nio.file.Path; 32 | import java.nio.file.Paths; 33 | import java.nio.file.StandardCopyOption; 34 | import java.util.*; 35 | import java.util.concurrent.atomic.AtomicInteger; 36 | 37 | import static net.puzzlemc.core.PuzzleCore.LOGGER; 38 | import static net.puzzlemc.core.PuzzleCore.MOD_ID; 39 | 40 | public class PuzzleSplashScreen { 41 | public static final Identifier LOGO = Identifier.of("textures/gui/title/mojangstudios.png"); 42 | public static final Identifier BACKGROUND = Identifier.of("puzzle/splash_background.png"); 43 | public static File CONFIG_PATH = new File(String.valueOf(PlatformFunctions.getConfigDirectory().resolve(".puzzle_cache"))); 44 | public static Path LOGO_TEXTURE = Paths.get(CONFIG_PATH + "/mojangstudios.png"); 45 | public static Path BACKGROUND_TEXTURE = Paths.get(CONFIG_PATH + "/splash_background.png"); 46 | private static MinecraftClient client = MinecraftClient.getInstance(); 47 | private static boolean keepBackground = false; 48 | private static RenderLayer CUSTOM_LOGO_LAYER; 49 | 50 | public static void init() { 51 | if (!CONFIG_PATH.exists()) { // Run when config directory is nonexistent // 52 | if (CONFIG_PATH.mkdir()) { // Create our custom config directory // 53 | if (Util.getOperatingSystem().equals(Util.OperatingSystem.WINDOWS)) { 54 | try { Files.setAttribute(CONFIG_PATH.toPath(), "dos:hidden", true); 55 | } catch (IOException ignored) {} 56 | } 57 | } 58 | } 59 | buildRenderLayer(); 60 | } 61 | 62 | public static RenderLayer getCustomLogoRenderLayer() { 63 | return CUSTOM_LOGO_LAYER; 64 | } 65 | 66 | public static void buildRenderLayer() { 67 | if (PuzzleConfig.resourcepackSplashScreen) { 68 | BlendFunction blendFunction = new BlendFunction(SourceFactor.SRC_ALPHA, DestFactor.ONE); 69 | if (PuzzleConfig.disableBlend) blendFunction = null; 70 | else if (PuzzleConfig.customBlendFunction.size() == 4) { 71 | try { 72 | blendFunction = new BlendFunction( 73 | SourceFactor.valueOf(PuzzleConfig.customBlendFunction.get(0)), 74 | DestFactor.valueOf(PuzzleConfig.customBlendFunction.get(1)), 75 | SourceFactor.valueOf(PuzzleConfig.customBlendFunction.get(2)), 76 | DestFactor.valueOf(PuzzleConfig.customBlendFunction.get(3))); 77 | } catch (Exception e) { 78 | LOGGER.error("Incorrect blend function defined in color.properties: {}{}", PuzzleConfig.customBlendFunction, e.getMessage()); 79 | } 80 | } 81 | 82 | var CUSTOM_LOGO_PIPELINE_BUILDER = RenderPipeline.builder(RenderPipelinesAccessor.getPOSITION_TEX_COLOR_SNIPPET()) 83 | .withLocation("pipeline/mojang_logo_puzzle") 84 | .withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST) 85 | .withDepthWrite(false); 86 | CUSTOM_LOGO_PIPELINE_BUILDER = blendFunction != null ? CUSTOM_LOGO_PIPELINE_BUILDER.withBlend(blendFunction) : CUSTOM_LOGO_PIPELINE_BUILDER.withoutBlend(); 87 | 88 | CUSTOM_LOGO_LAYER = RenderLayer.of("mojang_logo_puzzle", 786432, CUSTOM_LOGO_PIPELINE_BUILDER.build(), 89 | RenderLayer.MultiPhaseParameters.builder() 90 | .texture(new RenderPhase.Texture(SplashOverlay.LOGO, TriState.DEFAULT, false)) 91 | .build(false)); 92 | } 93 | } 94 | 95 | public static class ReloadListener implements SynchronousResourceReloader { 96 | public static final ReloadListener INSTANCE = new ReloadListener(); 97 | 98 | private ReloadListener() {} 99 | 100 | @Override 101 | public void reload(ResourceManager manager) { 102 | client = MinecraftClient.getInstance(); 103 | if (PuzzleConfig.resourcepackSplashScreen) { 104 | PuzzleSplashScreen.resetColors(); 105 | client.getTextureManager().registerTexture(LOGO, new LogoTexture(LOGO)); 106 | client.getTextureManager().registerTexture(BACKGROUND, new LogoTexture(BACKGROUND)); 107 | 108 | manager.findResources("optifine", path -> path.getPath().contains("color.properties")).forEach((id, resource) -> { 109 | try (InputStream stream = resource.getInputStream()) { 110 | Properties properties = new Properties(); 111 | properties.load(stream); 112 | 113 | if (properties.get("screen.loading") != null) { 114 | PuzzleConfig.backgroundColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading").toString()).getRGB(); 115 | PuzzleConfig.hasCustomSplashScreen = true; 116 | } 117 | if (properties.get("screen.loading.bar") != null) { 118 | PuzzleConfig.progressBarBackgroundColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.bar").toString()).getRGB(); 119 | PuzzleConfig.hasCustomSplashScreen = true; 120 | } 121 | if (properties.get("screen.loading.progress") != null) { 122 | PuzzleConfig.progressBarColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.progress").toString()).getRGB(); 123 | PuzzleConfig.hasCustomSplashScreen = true; 124 | } 125 | if (properties.get("screen.loading.outline") != null) { 126 | PuzzleConfig.progressFrameColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.outline").toString()).getRGB(); 127 | PuzzleConfig.hasCustomSplashScreen = true; 128 | } 129 | if (properties.get("screen.loading.blend") != null) { 130 | // Recommended blend: SRC_ALPHA ONE_MINUS_SRC_ALPHA ONE ZERO 131 | PuzzleConfig.disableBlend = properties.get("screen.loading.blend").toString().equals("off"); 132 | PuzzleConfig.customBlendFunction = new ArrayList<>(Arrays.stream(properties.get("screen.loading.blend").toString().split(" ")).toList()); 133 | PuzzleConfig.hasCustomSplashScreen = true; 134 | } 135 | 136 | } catch (Exception e) { 137 | LOGGER.error("Error occurred while loading color.properties {}", id.toString(), e); 138 | } 139 | }); 140 | AtomicInteger logoCount = new AtomicInteger(); 141 | manager.findResources("textures", path -> path.getPath().contains("mojangstudios.png")).forEach((id, resource) -> { 142 | try (InputStream stream = resource.getInputStream()) { 143 | Files.copy(stream, LOGO_TEXTURE, StandardCopyOption.REPLACE_EXISTING); 144 | client.getTextureManager().registerTexture(LOGO, new DynamicLogoTexture()); 145 | if (logoCount.get() > 0) PuzzleConfig.hasCustomSplashScreen = true; 146 | logoCount.getAndIncrement(); 147 | } catch (Exception e) { 148 | LOGGER.error("Error occurred while loading custom minecraft logo {}", id.toString(), e); 149 | } 150 | }); 151 | manager.findResources(MOD_ID, path -> path.getPath().contains("splash_background.png")).forEach((id, resource) -> { 152 | try (InputStream stream = resource.getInputStream()) { 153 | Files.copy(stream, BACKGROUND_TEXTURE, StandardCopyOption.REPLACE_EXISTING); 154 | InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.BACKGROUND_TEXTURE)); 155 | client.getTextureManager().registerTexture(BACKGROUND, new NativeImageBackedTexture(() -> "splash_screen_background", NativeImage.read(input))); 156 | keepBackground = true; 157 | PuzzleConfig.hasCustomSplashScreen = true; 158 | } catch (Exception e) { 159 | LOGGER.error("Error occurred while loading custom splash background {}", id.toString(), e); 160 | } 161 | }); 162 | if (!keepBackground) { 163 | try { 164 | Files.delete(BACKGROUND_TEXTURE); 165 | } catch (Exception ignored) {} 166 | } 167 | keepBackground = false; 168 | PuzzleConfig.write(MOD_ID); 169 | buildRenderLayer(); 170 | } 171 | } 172 | } 173 | 174 | public static void resetColors() { 175 | PuzzleConfig.backgroundColor = 15675965; 176 | PuzzleConfig.progressBarColor = 16777215; 177 | PuzzleConfig.progressBarBackgroundColor = 15675965; 178 | PuzzleConfig.progressFrameColor = 16777215; 179 | PuzzleConfig.disableBlend = false; 180 | PuzzleConfig.customBlendFunction = new ArrayList<>(); 181 | PuzzleConfig.hasCustomSplashScreen = false; 182 | } 183 | 184 | public static class LogoTexture extends ResourceTexture { 185 | public LogoTexture(Identifier logo) { super(logo); } 186 | 187 | @Override 188 | public TextureContents loadContents(ResourceManager resourceManager) { 189 | MinecraftClient minecraftClient = MinecraftClient.getInstance(); 190 | DefaultResourcePack defaultResourcePack = minecraftClient.getDefaultResourcePack(); 191 | try { 192 | InputStream inputStream = Objects.requireNonNull(defaultResourcePack.open(ResourceType.CLIENT_RESOURCES, LOGO)).get(); 193 | TextureContents var6; 194 | try { 195 | var6 = new TextureContents(NativeImage.read(inputStream), new TextureResourceMetadata(true, true)); 196 | } finally { 197 | if (inputStream != null) { 198 | inputStream.close(); 199 | } 200 | } 201 | return var6; 202 | } catch (IOException var18) { 203 | return TextureContents.createMissing(); 204 | } 205 | } 206 | } 207 | 208 | public static class DynamicLogoTexture extends ResourceTexture { 209 | public DynamicLogoTexture() { 210 | super(LOGO); 211 | } 212 | @Override 213 | public TextureContents loadContents(ResourceManager resourceManager) { 214 | try { 215 | InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.LOGO_TEXTURE)); 216 | return new TextureContents(NativeImage.read(input), new TextureResourceMetadata(true, true)); 217 | } catch (IOException e) { 218 | LOGGER.error("Encountered an error during logo loading: ", e); 219 | try { 220 | return TextureContents.load(resourceManager, LOGO); 221 | } catch (IOException ex) { 222 | return TextureContents.createMissing(); 223 | } 224 | } 225 | } 226 | } 227 | } 228 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/splashscreen/mixin/MixinSplashScreen.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.splashscreen.mixin; 2 | 3 | import com.llamalad7.mixinextras.injector.wrapoperation.Operation; 4 | import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; 5 | import net.minecraft.client.MinecraftClient; 6 | import net.minecraft.client.gui.DrawContext; 7 | import net.minecraft.client.gui.screen.Overlay; 8 | import net.minecraft.client.gui.screen.SplashOverlay; 9 | import net.minecraft.client.render.*; 10 | import net.minecraft.client.texture.NativeImage; 11 | import net.minecraft.client.texture.NativeImageBackedTexture; 12 | import net.minecraft.client.texture.TextureManager; 13 | import net.minecraft.util.Identifier; 14 | import net.minecraft.util.Util; 15 | import net.minecraft.util.math.ColorHelper; 16 | import net.minecraft.util.math.MathHelper; 17 | import net.puzzlemc.core.config.PuzzleConfig; 18 | import net.puzzlemc.splashscreen.PuzzleSplashScreen; 19 | import org.spongepowered.asm.mixin.Final; 20 | import org.spongepowered.asm.mixin.Mixin; 21 | import org.spongepowered.asm.mixin.Shadow; 22 | import org.spongepowered.asm.mixin.injection.*; 23 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 24 | 25 | import java.io.FileInputStream; 26 | import java.io.IOException; 27 | import java.io.InputStream; 28 | import java.nio.file.Files; 29 | import java.util.function.Function; 30 | import java.util.function.IntSupplier; 31 | 32 | import static net.puzzlemc.splashscreen.PuzzleSplashScreen.BACKGROUND; 33 | 34 | @Mixin(value = SplashOverlay.class, priority = 2000) 35 | public abstract class MixinSplashScreen extends Overlay { 36 | @Shadow @Final public static Identifier LOGO; 37 | @Shadow private long reloadCompleteTime; 38 | @Shadow @Final private MinecraftClient client; 39 | @Shadow @Final private boolean reloading; 40 | @Shadow private long reloadStartTime; 41 | @Shadow 42 | private static int withAlpha(int color, int alpha) { 43 | return 0; 44 | } 45 | 46 | @Inject(method = "init", at = @At("TAIL")) 47 | private static void puzzle$initSplashscreen(TextureManager textureManager, CallbackInfo ci) { // Load our custom textures at game start // 48 | if (PuzzleConfig.resourcepackSplashScreen) { 49 | if (PuzzleSplashScreen.LOGO_TEXTURE.toFile().exists()) { 50 | textureManager.registerTexture(LOGO, new PuzzleSplashScreen.DynamicLogoTexture()); 51 | } 52 | if (PuzzleSplashScreen.BACKGROUND_TEXTURE.toFile().exists()) { 53 | try { 54 | InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.BACKGROUND_TEXTURE)); 55 | textureManager.registerTexture(BACKGROUND, new NativeImageBackedTexture(() -> "splash_screen_background", NativeImage.read(input))); 56 | } catch (IOException ignored) {} 57 | } 58 | } 59 | } 60 | 61 | @Redirect(method = "render", at = @At(value = "INVOKE", target = "Ljava/util/function/IntSupplier;getAsInt()I")) 62 | private int puzzle$modifyBackground(IntSupplier instance) { // Set the Progress Bar Frame Color to our configured value // 63 | return (!PuzzleConfig.resourcepackSplashScreen || PuzzleConfig.progressBarBackgroundColor == 15675965) ? instance.getAsInt() : PuzzleConfig.backgroundColor | 255 << 24; 64 | } 65 | 66 | @WrapOperation(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawTexture(Ljava/util/function/Function;Lnet/minecraft/util/Identifier;IIFFIIIIIII)V")) 67 | private void puzzle$modifyRenderLayer(DrawContext instance, Function renderLayers, Identifier sprite, int x, int y, float u, float v, int width, int height, int regionWidth, int regionHeight, int textureWidth, int textureHeight, int color, Operation original) { 68 | if (PuzzleConfig.resourcepackSplashScreen) 69 | instance.drawTexture(id -> PuzzleSplashScreen.getCustomLogoRenderLayer(), sprite, x, y, u, v, width, height, regionWidth, regionHeight, textureWidth, textureHeight, color); 70 | else instance.drawTexture(renderLayers, sprite, x, y, u, v, width, height, textureWidth, textureHeight, color); 71 | } 72 | 73 | @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;getScaledWindowWidth()I", ordinal = 2)) 74 | private void puzzle$renderSplashBackground(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) { 75 | if (Files.exists(PuzzleSplashScreen.BACKGROUND_TEXTURE) && PuzzleConfig.resourcepackSplashScreen) { 76 | int width = client.getWindow().getScaledWidth(); 77 | int height = client.getWindow().getScaledHeight(); 78 | long l = Util.getMeasuringTimeMs(); 79 | float f = this.reloadCompleteTime > -1L ? (float)(l - this.reloadCompleteTime) / 1000.0F : -1.0F; 80 | float g = this.reloadStartTime> -1L ? (float)(l - this.reloadStartTime) / 500.0F : -1.0F; 81 | float s; 82 | if (f >= 1.0F) s = 1.0F - MathHelper.clamp(f - 1.0F, 0.0F, 1.0F); 83 | else if (reloading) s = MathHelper.clamp(g, 0.0F, 1.0F); 84 | else s = 1.0F; 85 | context.getMatrices().translate(0, 0, 1f); 86 | context.drawTexture(RenderLayer::getGuiTextured, BACKGROUND, 0, 0, 0, 0, width, height, width, height, ColorHelper.getWhite(s)); 87 | } 88 | } 89 | 90 | @Inject(method = "renderProgressBar", at = @At("HEAD")) 91 | private void puzzle$addProgressBarBackground(DrawContext context, int minX, int minY, int maxX, int maxY, float opacity, CallbackInfo ci) { 92 | context.getMatrices().translate(0, 0, 1f); 93 | if (!PuzzleConfig.resourcepackSplashScreen || PuzzleConfig.progressBarBackgroundColor == 15675965) return; 94 | long l = Util.getMeasuringTimeMs(); 95 | float f = this.reloadCompleteTime > -1L ? (float)(l - this.reloadCompleteTime) / 1000.0F : -1.0F; 96 | int m = MathHelper.ceil((1.0F - MathHelper.clamp(f - 1.0F, 0.0F, 1.0F)) * 255.0F); 97 | context.fill(minX, minY, maxX, maxY, withAlpha(PuzzleConfig.progressBarBackgroundColor, m)); 98 | } 99 | 100 | @ModifyArg(method = "renderProgressBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;fill(IIIII)V"), index = 4) 101 | private int puzzle$modifyProgressFrame(int color) { // Set the Progress Bar Frame Color to our configured value // 102 | return (!PuzzleConfig.resourcepackSplashScreen || PuzzleConfig.progressFrameColor == 16777215) ? color : PuzzleConfig.progressFrameColor | 255 << 24; 103 | } 104 | @ModifyArg(method = "renderProgressBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;fill(IIIII)V", ordinal = 0), index = 4) 105 | private int puzzle$modifyProgressColor(int color) { // Set the Progress Bar Color to our configured value // 106 | return (!PuzzleConfig.resourcepackSplashScreen || PuzzleConfig.progressBarColor == 16777215) ? color : PuzzleConfig.progressBarColor | 255 << 24; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /common/src/main/java/net/puzzlemc/splashscreen/mixin/RenderPipelinesAccessor.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.splashscreen.mixin; 2 | 3 | import com.mojang.blaze3d.pipeline.RenderPipeline; 4 | import net.minecraft.client.gl.RenderPipelines; 5 | import org.spongepowered.asm.mixin.Mixin; 6 | import org.spongepowered.asm.mixin.gen.Accessor; 7 | 8 | @Mixin(RenderPipelines.class) 9 | public interface RenderPipelinesAccessor { 10 | @Accessor 11 | static RenderPipeline.Snippet getPOSITION_TEX_COLOR_SNIPPET() { 12 | return null; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /common/src/main/resources/architectury.puzzle.json: -------------------------------------------------------------------------------- 1 | { 2 | "accessWidener": "puzzle-models.accesswidener" 3 | } -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PuzzleMC/Puzzle/7caadedcf1349f403e5adbd7c26ed2713805403c/common/src/main/resources/assets/puzzle/icon.png -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/lang/be_by.json: -------------------------------------------------------------------------------- 1 | { 2 | "puzzle.text.update_available":"Даступна абнаўленне!", 3 | "puzzle.screen.title":"Налады Puzzle", 4 | "puzzle.page.graphics":"Графіка", 5 | "puzzle.page.resources":"Рэсурсы", 6 | "puzzle.page.performance":"Прадукцыйнасць", 7 | "puzzle.page.misc":"Рознае", 8 | "puzzle.option.check_for_updates":"Праверыць абнаўленні", 9 | "puzzle.option.check_for_updates.tooltip":"Уключае ўбудаваны правершчык абнаўленняў", 10 | "puzzle.option.show_version_info":"Паказваць версію Puzzle", 11 | "puzzle.option.show_version_info.tooltip":"Паказваць інфармацыю пра бягучую\nверсію Puzzle и наяўнасць абнаўленняў на\nтытульным экране і меню F3", 12 | "puzzle.option.resourcepack_splash_screen":"Выкарыстанне пакетаў рэсурсаў для сплэшэй", 13 | "puzzle.option.resourcepack_splash_screen.tooltip":"Уключае пакеты рэсурсаў, якія змяняюць\nзагрузачныя экраны/сплэшы\nMinecraft, якія выкарыстоўваюць фармат OptiFine", 14 | "puzzle.option.better_splash_screen_blend":"Палепшанае спалучэнне сплэшэй і лагатыпу", 15 | "puzzle.option.better_splash_screen_blend.tooltip":"Змяняе тып спалучэння\nлагатыпу і сплэшэй\nкаб палепшыць працу з лагатыпамі карыстальніцкіх колераў", 16 | "puzzle.option.unlimited_model_rotations":"Неабмежаванае вярчэнне мадэлі", 17 | "puzzle.option.unlimited_model_rotations.tooltip":"Дазваляе вярчэнне на 360° на карыстальніцкіх мадэляў блокаў/прадметаў", 18 | "puzzle.option.bigger_custom_models":"Павялічаныя карыстальніцкія мадэлі", 19 | "puzzle.option.bigger_custom_models.tooltip":"Павялічвае ліміт памеру\nкарыстальніцкіх мадэляў блокаў/прадметаў\nз 3x3x3 да 5x5x5", 20 | "puzzle.midnightconfig.title":"Пашыраныя налады Puzzle", 21 | "puzzle.midnightconfig.category.gui":"GUI", 22 | "puzzle.midnightconfig.category.features":"Асаблівасці", 23 | "puzzle.midnightconfig.category.debug":"Debug", 24 | "puzzle.midnightconfig.tooltip":"Налады толькі для вопытных карыстальнікаў", 25 | 26 | "cullleaves.puzzle.option.enabled": "Адбракоўваць лісце", 27 | "cullleaves.puzzle.option.enabled.tooltip": "Уключыць адбракоўванне лісця, каб павялічыць прадукцыйнасць", 28 | "iris.puzzle.option.enableShaders": "Уключыць шэйдэры", 29 | "iris.puzzle.option.enableShaders.tooltip": "Дазваляе уключаць ці выключаць шэйдэры", 30 | "iris.puzzle.option.open": "АДКРЫЦЬ", 31 | "options.iris.shaderPackSelection.tooltip": "Адкрывае экран выбару\nшэйдэраў і іх налад", 32 | "lambdabettergrass.option.mode.tooltip": "Робіць бакі\nзямлі з дзёрнам злучанымі з\nверхам гэтага блоку", 33 | "lambdabettergrass.option.better_snow.tooltip": "Дадае крыху бачны слой снег/імху\nна непоўныя блокі, якія\nакружаны снегам/імхом", 34 | "config.dynamicfps.reduce_when_unfocused.tooltip": "Зніжае FPS у Minecraft калі ён не актыўны\n(то бок калі іншая прагракма адчынена ці гульня згорнута)\nкаб захаваць рэсурсы сістэмы", 35 | "config.dynamicfps.unfocused_fps.tooltip": "Колькасць кадраў у секунду, калі\nMinecraft згорнуты", 36 | "config.dynamicfps.restore_when_hovered.tooltip": "Дазваляе скасаваць ці не\nабмежаванне FPS, калі Minecraft актыны\n(то бок актыўны ці наведзены курсорам з панелі задач)", 37 | "config.dynamicfps.run_gc_on_unfocus.tooltip": "Запусціць збіральнік смецця калі\nMinecraft неактыўны,\n каб ачысціць крыху АЗУ", 38 | "config.dynamicfps.unfocused_volume.tooltip": "Гучнасць прайгравальных гукаў\nкалі гульня не актыўна\n(то бок іншае акно абрана)", 39 | "config.dynamicfps.hidden_volume.tooltip": "Гучнасць прайгравальных гукаў\nкали гульня не бачна\n(то бок згорнута, знаходзіцца пад іншымі вокнамі\nці на ішай віртуальнай машыне)", 40 | "entity_texture_features.puzzle.emissive_type.brighter": "§eЯрчэй", 41 | "entity_texture_features.puzzle.emissive_type.default": "§6Стандартна" 42 | } 43 | -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/lang/de_de.json: -------------------------------------------------------------------------------- 1 | { 2 | "puzzle.text.update_available":"Ein Update ist verfügbar!", 3 | "puzzle.screen.title":"Puzzle Einstellungen", 4 | "puzzle.page.graphics":"Grafik", 5 | "puzzle.page.resources":"Resourcen", 6 | "puzzle.page.performance":"Performance", 7 | "puzzle.page.misc":"Sonstiges", 8 | "puzzle.option.check_for_updates":"Auf Updates überprüfen", 9 | "puzzle.option.show_version_info":"Zeige Informationen über Puzzle's Version", 10 | "puzzle.option.resourcepack_splash_screen":"Nutze Resourcepack-Ladebildschirm", 11 | "puzzle.option.better_splash_screen_blend":"Verbessere das Blending des Splash-Screen-Logos", 12 | "puzzle.option.unlimited_model_rotations":"Unbegrenzte Modellrotationen", 13 | "puzzle.option.bigger_custom_models":"Größere benutzerdefinierte Modelle", 14 | "puzzle.midnightconfig.title":"Erweiterte Puzzle Konfiguration", 15 | "puzzle.option.check_for_updates.tooltip": "Aktiviert Puzzle's eingebauten Update-Checker", 16 | "puzzle.option.show_version_info.tooltip": "Zeigt Informationen über die Version\nvon Puzzle und die Verfügbarkeit von Updates\nauf dem Titelbildschirm und im F3-Menü", 17 | "puzzle.option.resourcepack_splash_screen.tooltip": "Ermöglicht Resourcepacks, das Aussehen\ndes Ladebildschirms mit dem\nOptiFine-Format zu verändern", 18 | "puzzle.option.better_splash_screen_blend.tooltip": "Ändert die Art des Blending,\ndie für das Logo auf dem Ladebildschirm benutzt wird,\ndamit es besser mit farbigen Logos funktioniert.", 19 | "puzzle.option.unlimited_model_rotations.tooltip": "Schaltet volle 360° Rotation für\nbenutzerdefinierte Item-/Blockmodelle frei", 20 | "puzzle.option.bigger_custom_models.tooltip": "Erhöht das Größenlimit für\nbenutzerdefinierte Item-/Blockmodelle\nvon 3x3x3 auf 5x5x5", 21 | "puzzle.midnightconfig.tooltip": "Optionen für fortgeschrittene Nutzer", 22 | 23 | "cullleaves.puzzle.option.enabled": "Aktiviere Culling für Blätter", 24 | "cullleaves.puzzle.option.enabled.tooltip": "Fügt Occlusion Culling für \nBlätter hinzu, was die Leistung des \nSpiels verbessert", 25 | "iris.puzzle.option.enableShaders": "Shader aktivieren", 26 | "iris.puzzle.option.enableShaders.tooltip": "Legt fest, ob Shader aktiviert werden sollen", 27 | "iris.puzzle.option.open": "ÖFFNEN", 28 | "options.iris.shaderPackSelection.tooltip": "Öffnet einen Bildschirm, um Shader\nauszuwählen und zu konfigurieren", 29 | "lambdabettergrass.option.mode.tooltip": "Verbindet die Seiten von Grasblöcken\nmit anliegenden Grasblöcken", 30 | "lambdabettergrass.option.better_snow.tooltip": "Fügt eine rein visuelle Schnee-/Moosschicht\nunter nicht-volle Blöcke hinzu,\nwelche von Schnee/Moos umgeben sind", 31 | "config.dynamicfps.reduce_when_unfocused.tooltip": "Reduziert Minecraft's FPS,\nwährend das Spiel nicht im Fokus ist\n(z.B. wenn ein anderes Fenster fokussiert oder das Spiel versteckt ist)\num Strom und Systemressourcen zu sparen", 32 | "config.dynamicfps.unfocused_fps.tooltip": "Die Anzahl der Bilder pro Sekunde (FPS)\nmit denen Minecraft rendern\ndarf, wenn es nicht im Fokus ist", 33 | "config.dynamicfps.restore_when_hovered.tooltip": "Legt fest, ob die Limitierung\nder FPS aufgehoben werden soll, wenn Minecraft in der Vorschau erscheint\n(z.B. in der Taskleiste oder Dock überfahren wird)", 34 | "config.dynamicfps.run_gc_on_unfocus.tooltip": "Lässt einen Garbage Collector laufen,\nwährend Minecraft nicht im Fokus ist\num etwas Arbeitsspeicher (RAM) freizumachen", 35 | "config.dynamicfps.unfocused_volume.tooltip": "Die Lautstärke mit der Minecraft\nGeräusche wiedergeben kann, während es nicht im Fokus ist\n(z.B. wenn ein anderes Fenster fokussiert ist)", 36 | "config.dynamicfps.hidden_volume.tooltip": "Die Lautstärke mit der Minecraft\nGeräusche wiedergeben kann, während es nicht im Fokus ist\n(z.B. wenn es minimiert, von anderen Fenstern verdeckt\noder auf einem anderen virtuellen Desktop ist)", 37 | "entity_texture_features.puzzle.emissive_type.brighter": "§eHeller", 38 | "entity_texture_features.puzzle.emissive_type.default": "§6Normal" 39 | } -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/lang/el_gr.json: -------------------------------------------------------------------------------- 1 | { 2 | "puzzle.text.update_available":"Μια καινούρια έκδοση είναι διαθέσιμη!", 3 | "puzzle.screen.title":"Ρυθμίσεις του Puzzle", 4 | "puzzle.page.graphics":"Γραφικών", 5 | "puzzle.page.resources":"Πόρων", 6 | "puzzle.page.performance":"Απόδοσης", 7 | "puzzle.page.misc":"Διάφορες", 8 | "puzzle.option.check_for_updates":"Έλεγχος για αναβαθμίσεις", 9 | "puzzle.option.show_version_info":"Εμφάνηση έκδοσης του Puzzle", 10 | "puzzle.option.resourcepack_splash_screen":"Οθόνη φόρτωσης πακέτου πόρων", 11 | "puzzle.option.disable_splash_screen_blend":"Μη ανάμηξη λογότυπου οθ. φόρτωσης", 12 | "puzzle.option.emissive_textures":"Λαμπρά Είδη", 13 | "puzzle.option.unlimited_model_rotations":"Απεριόριστες Περιστροφές Μοντέλων", 14 | "puzzle.option.bigger_custom_models":"Μεγαλύτερα Ειδικά Μοντέλα", 15 | "puzzle.option.render_layer_overrides":"Εμφάνηση Παρακάμψεων Στρώσεων", 16 | "puzzle.midnightconfig.title":"Εξειδηκευμένες Ρυθμίσεις του Puzzle" 17 | } 18 | 19 | -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/lang/en_us.json: -------------------------------------------------------------------------------- 1 | { 2 | "puzzle.text.update_available":"An update is available!", 3 | "puzzle.screen.title":"Puzzle Settings", 4 | "puzzle.page.graphics":"Graphics", 5 | "puzzle.page.resources":"Resource", 6 | "puzzle.page.performance":"Performance", 7 | "puzzle.page.misc":"Miscellaneous", 8 | "puzzle.option.check_for_updates":"Check for Updates", 9 | "puzzle.option.check_for_updates.tooltip":"Enables Puzzle's built-in update checker", 10 | "puzzle.option.show_version_info":"Show Puzzle version info", 11 | "puzzle.option.show_version_info.tooltip":"Show information about the current\nPuzzle version and update status on\nthe Title Screen and F3 Menu", 12 | "puzzle.option.resourcepack_splash_screen":"Use resourcepack splash screen", 13 | "puzzle.option.resourcepack_splash_screen.tooltip":"Enables resourcepacks to change the look\nof Minecraft's loading/splash\nscreen using the OptiFine format", 14 | "puzzle.option.better_splash_screen_blend":"Better splash screen logo blending", 15 | "puzzle.option.better_splash_screen_blend.tooltip":"Changes the type of blending used\nby the logo on the splash screen\nto work better with custom colored logos", 16 | "puzzle.option.unlimited_model_rotations":"Unlimited Model Rotations", 17 | "puzzle.option.unlimited_model_rotations.tooltip":"Unlocks full 360° rotation on custom block/item models", 18 | "puzzle.option.bigger_custom_models":"Bigger Custom Models", 19 | "puzzle.option.bigger_custom_models.tooltip":"Increases the limit of\ncustom block/item model sizes\nfrom 3x3x3 to 5x5x5", 20 | "puzzle.midnightconfig.title":"Puzzle Advanced Config", 21 | "puzzle.midnightconfig.category.gui":"GUI", 22 | "puzzle.midnightconfig.category.features":"Features", 23 | "puzzle.midnightconfig.category.internal":"Internal", 24 | "puzzle.midnightconfig.tooltip":"Options for advanced users only", 25 | 26 | "cullleaves.puzzle.option.enabled": "Cull Leaves", 27 | "cullleaves.puzzle.option.enabled.tooltip": "Enable the culling of leaves to enhance performance", 28 | "iris.puzzle.option.enableShaders": "Enable Shaders", 29 | "iris.puzzle.option.enableShaders.tooltip": "Whether or not to enable shaderpacks", 30 | "iris.puzzle.option.open": "OPEN", 31 | "options.iris.shaderPackSelection.tooltip": "Open a screen to select\nshaderpacks and configure them", 32 | "lambdabettergrass.option.mode.tooltip": "Makes the sides of\ngrass blocks connect to\nadjacent grass blocks", 33 | "lambdabettergrass.option.better_snow.tooltip": "Adds a purely visual snow/moss layer\nto non-full blocks that\nare surrounded by snow/moss", 34 | "config.dynamicfps.reduce_when_unfocused.tooltip": "Reduces Minecraft's FPS when unfocused\n(i.e. another window is focused or the game is hidden)\nto save power and system resources", 35 | "config.dynamicfps.unfocused_fps.tooltip": "The amount of frames per second\nMinecraft is allowed to\nrender at while unfocused", 36 | "config.dynamicfps.restore_when_hovered.tooltip": "Whether or not to stop the\nFPS limiting while Minecraft is previewed\n(i.e. hovered on task bar or dock)", 37 | "config.dynamicfps.run_gc_on_unfocus.tooltip": "Run a garbage collector while\nMinecraft is not focused to\nfree up some RAM", 38 | "config.dynamicfps.unfocused_volume.tooltip": "The volume the game should play\nsound at while unfocused\n(i.e. another window is selected)", 39 | "config.dynamicfps.hidden_volume.tooltip": "The volume the game should play\nsound at while not visible\n(i.e. minimized, covered by other windows\nor on another virtual desktop)", 40 | "entity_texture_features.puzzle.emissive_type.brighter": "§eBrighter", 41 | "entity_texture_features.puzzle.emissive_type.default": "§6Default" 42 | } 43 | -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/lang/es_es.json: -------------------------------------------------------------------------------- 1 | { 2 | "puzzle.text.update_available":"¡Hay una actualización disponible!", 3 | "puzzle.screen.title":"Configuración de Puzzle", 4 | "puzzle.page.graphics":"Gráficos", 5 | "puzzle.page.resources":"Recursos", 6 | "puzzle.page.performance":"Rendimiento", 7 | "puzzle.page.misc":"Variado", 8 | "puzzle.option.check_for_updates":"Comprobar Actualizaciones", 9 | "puzzle.option.check_for_updates.tooltip":"Activa el comprobador de actualizaciones integrado de Puzzle.", 10 | "puzzle.option.show_version_info":"Mostrar información de la versión Puzzle", 11 | "puzzle.option.show_version_info.tooltip":"Muestra información sobre la versión actual\nde Puzzle y el estado de actualización\nen la pantalla de título y en el menú F3.", 12 | "puzzle.option.resourcepack_splash_screen":"Usar la Pantalla de Carga del Paquete de Recursos [*]", 13 | "puzzle.option.resourcepack_splash_screen.tooltip":"Permite que los paquetes de recursos\ncambien el aspecto de la pantalla de carga/principal\nde Minecraft utilizando el formato OptiFine.", 14 | "puzzle.option.better_splash_screen_blend":"Mejor Mezcla del Logo de la Pantalla de Carga", 15 | "puzzle.option.better_splash_screen_blend.tooltip":"Cambia el tipo de mezcla utilizada\npor el logotipo de la pantalla de carga\npara que funcione mejor con logotipos\nde colores personalizados.", 16 | "puzzle.option.unlimited_model_rotations":"Rotaciones Ilimitadas de Modelos", 17 | "puzzle.option.unlimited_model_rotations.tooltip":"Desbloquea la rotación completa de 360° en los modelos de bloques/objetos personalizados.", 18 | "puzzle.option.bigger_custom_models":"Modelos Personalizados más Grandes", 19 | "puzzle.option.bigger_custom_models.tooltip":"Aumenta el límite de tamaños\nde los modelos de bloques/objetos personalizados\nde 3x3x3 a 5x5x5.", 20 | "puzzle.midnightconfig.title":"Acceder a las Opciones adicionales de Puzzle para Expertos", 21 | "puzzle.midnightconfig.category.gui":"Interfaz", 22 | "puzzle.midnightconfig.category.features":"Características", 23 | "puzzle.midnightconfig.category.debug":"Depuración", 24 | "puzzle.midnightconfig.tooltip":"Ajustes para usuarios experimentados.", 25 | 26 | "cullleaves.puzzle.option.enabled": "Reducir Cantidad de Hojas", 27 | "cullleaves.puzzle.option.enabled.tooltip": "Permitir reducir la cantidad de hojas para mejorar el rendimiento.", 28 | "iris.puzzle.option.enableShaders": "Activar Sombreadores", 29 | "iris.puzzle.option.enableShaders.tooltip": "Activar o no los paquetes de sombreadores.", 30 | "iris.puzzle.option.open": "ABRIR", 31 | "options.iris.shaderPackSelection.tooltip": "Abre la pantalla de selección\nde los paquetes de sombreadores.", 32 | "lambdabettergrass.option.mode.tooltip": "Hace que los lados de los bloques de\ncésped se conecten con los bloques de\ncésped adyacentes.", 33 | "lambdabettergrass.option.better_snow.tooltip": "Añade una capa de nieve/musgo puramente\nvisual a los bloques no llenos que están rodeados\nde nieve/musgo.", 34 | "config.dynamicfps.reduce_when_unfocused.tooltip": "Reduce los FPS de Minecraft cuando el\njuego se encuentra en segundo plano (es decir,\ncuando otra ventana está en primer plano o el juego\nestá oculto) para ahorrar energía y recursos\ndel sistema.", 35 | "config.dynamicfps.unfocused_fps.tooltip": "La cantidad de fotogramas por segundo que\nMinecraft puede renderizar mientras se\nencuentra en segundo plano.", 36 | "config.dynamicfps.restore_when_hovered.tooltip": "Detener o no la limitación de FPS mientras\ndurante la previsualización de Minecraft\n(por ejemplo cuando se señala en la barra de\ntareas o en el área de notificación).", 37 | "config.dynamicfps.run_gc_on_unfocus.tooltip": "Ejecutar un recolector de basura mientras\nMinecraft se encuentra en segundo plano\npara liberar algo de RAM.", 38 | "config.dynamicfps.unfocused_volume.tooltip": "El volumen del sonido del juego cuando permanece\nen segundo plano (es decir, cuando hay otra\nventana seleccionada).", 39 | "config.dynamicfps.hidden_volume.tooltip": "El volumen del juego cuando no es visible (es decir, minimizado, cubierto por otras ventanas o en otro escritorio virtual).", 40 | "entity_texture_features.puzzle.emissive_type.brighter": "§eResplandeciente", 41 | "entity_texture_features.puzzle.emissive_type.default": "§6Predeterminado" 42 | } 43 | -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/lang/et_ee.json: -------------------------------------------------------------------------------- 1 | { 2 | "puzzle.text.update_available":"Uuendus on saadaval!", 3 | "puzzle.screen.title":"Puzzle sätted", 4 | "puzzle.page.graphics":"Graafika", 5 | "puzzle.page.resources":"Ressursi", 6 | "puzzle.page.performance":"Jõudlus", 7 | "puzzle.page.misc":"Muud", 8 | "puzzle.option.check_for_updates":"Uuenduste kontroll", 9 | "puzzle.option.show_version_info":"Kuva Puzzle versiooniteavet", 10 | "puzzle.option.resourcepack_splash_screen":"Kasuta ressursipaki laadimiskuva", 11 | "puzzle.option.disable_splash_screen_blend":"Keela laadimiskuva logo segunemine", 12 | "puzzle.option.emissive_textures":"Hõõguvad tekstuurid", 13 | "puzzle.option.unlimited_model_rotations":"Lõpmatud mudelipöörded", 14 | "puzzle.option.bigger_custom_models":"Suuremad kohandatud mudelid", 15 | "puzzle.option.render_layer_overrides":"Renderduskihi ülekatted", 16 | "puzzle.midnightconfig.title":"Puzzle täpsem seadistus" 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/lang/ko_kr.json: -------------------------------------------------------------------------------- 1 | { 2 | "puzzle.text.update_available":"업데이트가 가능합니다!", 3 | "puzzle.screen.title":"Puzzle 설정", 4 | "puzzle.page.graphics":"그래픽", 5 | "puzzle.page.resources":"리소스", 6 | "puzzle.page.performance":"성능", 7 | "puzzle.page.misc":"기타", 8 | "puzzle.option.check_for_updates":"업데이트 확인", 9 | "puzzle.option.show_version_info":"Puzzle 버전 정보 보기", 10 | "puzzle.option.resourcepack_splash_screen":"스플래시 화면에서 리소스팩 사용", 11 | "puzzle.option.better_splash_screen_blend":"향상된 스플래시 화면 로고 블렌딩", 12 | "puzzle.option.emissive_textures":"방사성 텍스쳐", 13 | "puzzle.option.unlimited_model_rotations":"모델 회전 제한없음", 14 | "puzzle.option.bigger_custom_models":"향상된 커스텀 모델", 15 | "puzzle.option.render_layer_overrides":"렌더링 레이어 재정의", 16 | "puzzle.midnightconfig.title":"Puzzle 고급 환경설정" 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/lang/pl_pl.json: -------------------------------------------------------------------------------- 1 | { 2 | "puzzle.text.update_available":"Aktualizacja jest dostępna!", 3 | "puzzle.screen.title":"Ustawienia Puzzle", 4 | "puzzle.page.graphics":"Grafiki", 5 | "puzzle.page.resources":"Zasobów", 6 | "puzzle.page.performance":"Wydajności", 7 | "puzzle.page.misc":"Ustawienia", 8 | "puzzle.option.check_for_updates":"Sprawdź aktualizacje", 9 | "puzzle.option.show_version_info":"Pokaż informacje o wersji Puzzle", 10 | "puzzle.option.resourcepack_splash_screen":"Użyj ekranu powitalnego paczek zasobów", 11 | "puzzle.option.disable_splash_screen_blend":"Wyłącz mieszanie loga ekranu powitalnego", 12 | "puzzle.option.emissive_textures":"Emisyjne tekstury", 13 | "puzzle.option.unlimited_model_rotations":"Nielimitowane rotacje modeli", 14 | "puzzle.option.bigger_custom_models":"Większe niestandardowe modele", 15 | "puzzle.option.render_layer_overrides":"Renderuj nadpisania warstw", 16 | "puzzle.midnightconfig.title":"Zaawansowana konfiguracja Puzzle" 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/lang/pt_br.json: -------------------------------------------------------------------------------- 1 | { 2 | "puzzle.text.update_available":"Uma atualização está disponível!", 3 | "puzzle.screen.title":"Puzzle Definições", 4 | "puzzle.page.graphics":"Gráficas", 5 | "puzzle.page.resources":"Recursos", 6 | "puzzle.page.performance":"Desempenho", 7 | "puzzle.page.misc":"Diversas", 8 | "puzzle.option.check_for_updates":"Verifique se há atualizações", 9 | "puzzle.option.check_for_updates.tooltip":"Ativa o verificador de atualização integrado do Puzzle", 10 | "puzzle.option.show_version_info":"Mostrar informações da versão do Puzzle", 11 | "puzzle.option.show_version_info.tooltip":"Mostrar informações sobre o atual\nVersão do Puzzle e status de atualização em\na tela de título e o menu F3", 12 | "puzzle.option.resourcepack_splash_screen":"Use a tela inicial do pacote de recursos", 13 | "puzzle.option.resourcepack_splash_screen.tooltip":"Permite que os pacotes de recursos mudem a aparência\ndo carregamento do Minecraft/splash\ntela usando o formato OptiFine", 14 | "puzzle.option.better_splash_screen_blend":"Melhor combinação do logotipo da tela inicial", 15 | "puzzle.option.better_splash_screen_blend.tooltip":"Muda o tipo de mistura usado\npelo logotipo na tela inicial\npara trabalhar melhor com logotipos coloridos personalizados", 16 | "puzzle.option.unlimited_model_rotations":"Rotações de modelo ilimitadas", 17 | "puzzle.option.unlimited_model_rotations.tooltip":"Desbloqueia rotação total de 360° em modelos de itens/blocos personalizados", 18 | "puzzle.option.bigger_custom_models":"Modelos personalizados maiores", 19 | "puzzle.option.bigger_custom_models.tooltip":"Aumenta o limite de\ntamanhos de modelo de bloco/item personalizados\nde 3x3x3 a 5x5x5", 20 | "puzzle.midnightconfig.title":"Configuração avançada do Puzzle", 21 | "puzzle.midnightconfig.tooltip":"Opções apenas para usuários avançados", 22 | 23 | "cullleaves.puzzle.option.enabled": "Abate de Folhas", 24 | "cullleaves.puzzle.option.enabled.tooltip": "Ative o abate de folhas para melhorar o desempenho", 25 | "iris.puzzle.option.enableShaders": "Ativar sombreadores", 26 | "iris.puzzle.option.enableShaders.tooltip": "Habilitar ou não shaderpacks", 27 | "iris.puzzle.option.open": "ABRIR", 28 | "options.iris.shaderPackSelection.tooltip": "Abra uma tela para selecionar\nshaderpacks e configurá-los", 29 | "lambdabettergrass.option.mode.tooltip": "Faz os lados de\nblocos de grama se conectam a\nblocos de grama adjacentes", 30 | "lambdabettergrass.option.better_snow.tooltip": "Adiciona uma neve puramente visual/camada de musgo\na blocos não completos que\nestão rodeados de neve/musgo", 31 | "config.dynamicfps.reduce_when_unfocused.tooltip": "Reduz o FPS do Minecraft quando desfocado\n(ou seja, outra janela está focada ou o jogo está oculto)\npara economizar energia e recursos do sistema", 32 | "config.dynamicfps.unfocused_fps.tooltip": "A quantidade de quadros por segundo\nMinecraft é permitido\nrenderizar enquanto estiver fora de foco", 33 | "config.dynamicfps.restore_when_hovered.tooltip": "Interromper ou não o\nLimitação de FPS enquanto o Minecraft é visualizado\n(ou seja, pairou na barra de tarefas ou dock)", 34 | "config.dynamicfps.run_gc_on_unfocus.tooltip": "Execute um coletor de lixo enquanto\nMinecraft não está focado em\nliberar um pouco de RAM", 35 | "config.dynamicfps.unfocused_volume.tooltip": "O volume que o jogo deve reproduzir\nsom enquanto desfocado\n(ou seja, outra janela é selecionada)", 36 | "config.dynamicfps.hidden_volume.tooltip": "O volume que o jogo deve reproduzir\nsom em enquanto não visível\n(ou seja, minimizado, coberto por outras janelas\nem em outra área de trabalho virtual)", 37 | "entity_texture_features.puzzle.emissive_type.brighter": "§eMais brilhante", 38 | "entity_texture_features.puzzle.emissive_type.default": "§6Padrão" 39 | } 40 | -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/lang/ru_ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "puzzle.text.update_available":"Доступно обновление!", 3 | "puzzle.screen.title":"Настройки Puzzle", 4 | "puzzle.page.graphics":"Графика", 5 | "puzzle.page.resources":"Ресурсы", 6 | "puzzle.page.performance":"Оптимизация", 7 | "puzzle.page.misc":"Прочие", 8 | "puzzle.option.check_for_updates":"Проверять обновления", 9 | "puzzle.option.check_for_updates.tooltip":"Включить встроенную в Puzzle проверку обновлений", 10 | "puzzle.option.show_version_info":"Показывать информацию о версии", 11 | "puzzle.option.show_version_info.tooltip":"Отображать информацию о текущей версии\nPuzzle и наличии обновлений\nна главном экране и экране отладки", 12 | "puzzle.option.resourcepack_splash_screen":"Пользовательский экран загрузки", 13 | "puzzle.option.resourcepack_splash_screen.tooltip":"Разрешить наборам ресурсов изменять\nвнешний вид экрана загрузки Minecraft,\nиспользуя формат OptiFine", 14 | "puzzle.option.better_splash_screen_blend":"Улучшенное смешивание логотипа", 15 | "puzzle.option.better_splash_screen_blend.tooltip":"Изменить метод смешивания, используемый\nдля логотипа на экране загрузки,\nчтобы улучшить вид с изменёнными цветами", 16 | "puzzle.option.unlimited_model_rotations":"Неограниченные повороты моделей", 17 | "puzzle.option.unlimited_model_rotations.tooltip":"Разрешить поворот частей\nпользовательских моделей\nблоков/предметов на 360°", 18 | "puzzle.option.bigger_custom_models":"Увеличенный размер моделей", 19 | "puzzle.option.bigger_custom_models.tooltip":"Увеличить предельный размер\nпользовательских моделей блоков\nи предметов с 3×3×3 до 5×5×5", 20 | "puzzle.midnightconfig.title":"Расширенные настройки Puzzle", 21 | "puzzle.midnightconfig.category.gui":"Интерфейс", 22 | "puzzle.midnightconfig.category.features":"Функционал", 23 | "puzzle.midnightconfig.category.debug":"Отладка", 24 | "puzzle.midnightconfig.tooltip":"Только для продвинутых пользователей!", 25 | 26 | "cullleaves.puzzle.option.enabled": "Отбраковка листьев", 27 | "cullleaves.puzzle.option.enabled.tooltip": "Включить отбраковку блоков листьев\nдля улучшения производительности", 28 | "iris.puzzle.option.enableShaders": "Шейдеры", 29 | "iris.puzzle.option.enableShaders.tooltip": "Включить выбранный набор шейдеров", 30 | "iris.puzzle.option.open": "Выбрать ", 31 | "options.iris.shaderPackSelection.tooltip": "Открыть экран переключения\nи настройки наборов шейдеров", 32 | "lambdabettergrass.option.mode.tooltip": "Включить соединение текстуры\nтравы у соседних блоков дёрна", 33 | "lambdabettergrass.option.better_snow.tooltip": "Добавить имитацию наличия слоя снега\nили мха для неполных блоков, имеющих\nсоответствующее окружение", 34 | "config.dynamicfps.reduce_when_unfocused.tooltip": "Уменьшать FPS в Minecraft при переходе в фон\nдля экономии энергии и системных ресурсов\n(когда игра свёрнута или активно другое окно)", 35 | "config.dynamicfps.unfocused_fps.tooltip": "Фактическое количество\nкадров в секунду, которое\nMinecraft сможет выводить\nв фоновом режиме", 36 | "config.dynamicfps.restore_when_hovered.tooltip": "Отключать ограничение FPS,\nкогда на окно с Minecraft\nнаведён курсор мыши", 37 | "config.dynamicfps.run_gc_on_unfocus.tooltip": "Запускать сборщик мусора при\nпереходе игры в фон, чтобы\nосвободить пространство в ОЗУ\n(уменьшает число просадок FPS)", 38 | "config.dynamicfps.unfocused_volume.tooltip": "Громкость звука игры в состоянии фона\n(когда активно другое окно)", 39 | "config.dynamicfps.hidden_volume.tooltip": "Громкость звука игры в скрытом состоянии\n(когда окно свёрнуто, закрыто другим окном\nили находится на другом рабочем столе)", 40 | "entity_texture_features.puzzle.emissive_type.brighter": "§eЯркие", 41 | "entity_texture_features.puzzle.emissive_type.default": "§6Обычные", 42 | 43 | "modmenu.descriptionTranslation.puzzle": "Функции улучшения внешнего вида и производительности.", 44 | "modmenu.descriptionTranslation.puzzle-base": "Общий код всех модулей Puzzle.", 45 | "modmenu.descriptionTranslation.puzzle-gui": "Альтернативы Optifine, объединённые в едином меню.", 46 | "modmenu.descriptionTranslation.puzzle-models": "Больше свободы моделям блоков и предметов!", 47 | "modmenu.descriptionTranslation.puzzle-splashscreen": "Свой экран загрузки при помощи наборов ресурсов." 48 | } 49 | -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/lang/vi_vn.json: -------------------------------------------------------------------------------- 1 | { 2 | "puzzle.text.update_available":"Đã có bản cập nhật!", 3 | "puzzle.screen.title":"Cài đặt Puzzle", 4 | "puzzle.page.graphics":"Đồ họa", 5 | "puzzle.page.resources":"Tài nguyên", 6 | "puzzle.page.performance":"Hiệu năng", 7 | "puzzle.page.misc":"Khác", 8 | "puzzle.option.check_for_updates":"Kiểm tra cập nhật", 9 | "puzzle.option.check_for_updates.tooltip":"Bật trình kiểm tra cập nhật tích hợp của Puzzle", 10 | "puzzle.option.show_version_info":"Hiển thị thông tin phiên bản Puzzle", 11 | "puzzle.option.show_version_info.tooltip":"Hiển thị thông tin về phiên bản \nPuzzle hiện tại và trạng thái cập nhật trên\nMàn hình Tiêu đề và Menu F3", 12 | "puzzle.option.resourcepack_splash_screen":"Sử dụng màn hình đốm gói tài nguyên", 13 | "puzzle.option.resourcepack_splash_screen.tooltip":"Cho phép gói tài nguyên thay đổi giao diện\nmàn hình tải/đốm\ncủa Minecraft bằng định dạng OptiFine", 14 | "puzzle.option.better_splash_screen_blend":"Logo màn hình đốm tốt hơn", 15 | "puzzle.option.better_splash_screen_blend.tooltip":"Thay đổi kiểu hòa trộn được sử dụng\nbởi biểu trưng trên màn hình đốm\nđể hoạt động tốt hơn với các biểu trưng có màu tùy chỉnh", 16 | "puzzle.option.unlimited_model_rotations":"Xoay mô hình không giới hạn", 17 | "puzzle.option.unlimited_model_rotations.tooltip":"Mở khóa xoay 360° đầy đủ trên các mô hình khối/vật phẩm tùy chỉnh", 18 | "puzzle.option.bigger_custom_models":"Mô hình tùy chỉnh lớn hơn", 19 | "puzzle.option.bigger_custom_models.tooltip":"Tăng giới hạn của\nkích thước mô hình khối/vật phẩm tùy chỉnh\ntừ 3x3x3 lên 5x5x5", 20 | "puzzle.midnightconfig.title":"Cấu hình Puzzle nâng cao", 21 | "puzzle.midnightconfig.category.gui":"GUI", 22 | "puzzle.midnightconfig.category.features":"Tính năng", 23 | "puzzle.midnightconfig.category.debug":"Gỡ lỗi", 24 | "puzzle.midnightconfig.tooltip":"Tùy chọn chỉ dành cho người dùng nâng cao", 25 | 26 | "cullleaves.puzzle.option.enabled": "Loại bỏ Lá", 27 | "cullleaves.puzzle.option.enabled.tooltip": "Bật tính năng loại bỏ lá để nâng cao hiệu suất", 28 | "iris.puzzle.option.enableShaders": "Bật Shader", 29 | "iris.puzzle.option.enableShaders.tooltip": "Bật shaderpack", 30 | "iris.puzzle.option.open": "MỞ", 31 | "options.iris.shaderPackSelection.tooltip": "Mở một màn hình để chọn\nshaderpack và định cấu hình chúng", 32 | "lambdabettergrass.option.mode.tooltip": "Làm cho các cạnh của\nkhối cỏ kết nối với\nkhối cỏ liền kề", 33 | "lambdabettergrass.option.better_snow.tooltip": "Thêm một lớp tuyết/rêu hoàn toàn trực quan\nvào các khối không đầy đủ\nđược bao quanh bởi tuyết/rêu", 34 | "config.dynamicfps.reduce_when_unfocused.tooltip": "Giảm FPS của Minecraft khi không tập trung\n(tức là một cửa sổ khác được tập trung hoặc trò chơi bị ẩn)\nđể tiết kiệm năng lượng và tài nguyên hệ thống", 35 | "config.dynamicfps.unfocused_fps.tooltip": "Lượng khung hình mỗi giây\nMinecraft được phép\nkết xuất khi không tập trung", 36 | "config.dynamicfps.restore_when_hovered.tooltip": "Dừng giới hạn\nFPS trong khi Minecraft được xem trước\n(tức là được di chuột trên thanh tác vụ hoặc thanh công cụ)", 37 | "config.dynamicfps.run_gc_on_unfocus.tooltip": "Chạy trình thu gom rác trong khi\nMinecraft không tập trung vào\ngiải phóng một số RAM", 38 | "config.dynamicfps.unfocused_volume.tooltip": "Âm lượng mà trò chơi sẽ phát\nâm thanh khi không tập trung\n(tức là một cửa sổ khác được chọn)", 39 | "config.dynamicfps.hidden_volume.tooltip": "Âm lượng mà trò chơi sẽ phát\nâm thanh trong khi không hiển thị\n(tức là được thu nhỏ, bị che bởi các cửa sổ khác\ncũng như trên màn hình ảo khác)", 40 | "entity_texture_features.puzzle.emissive_type.brighter": "§eSáng hơn", 41 | "entity_texture_features.puzzle.emissive_type.default": "§6Mặc định" 42 | } 43 | -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/lang/zh_cn.json: -------------------------------------------------------------------------------- 1 | { 2 | "puzzle.text.update_available":"更新可用!", 3 | "puzzle.screen.title":"Puzzle 设置", 4 | "puzzle.page.graphics":"图像设置", 5 | "puzzle.page.resources":"资源设置", 6 | "puzzle.page.performance":"性能设置", 7 | "puzzle.page.misc":"杂项设置", 8 | "puzzle.option.check_for_updates":"检查更新", 9 | "puzzle.option.show_version_info":"显示 Puzzle 版本信息", 10 | "puzzle.option.resourcepack_splash_screen":"使用资源包提供的闪烁标语", 11 | "puzzle.option.disable_splash_screen_blend":"禁用闪烁标语闪烁", 12 | "puzzle.option.emissive_textures":"发光纹理", 13 | "puzzle.option.unlimited_model_rotations":"无限制模型旋转", 14 | "puzzle.option.bigger_custom_models":"更大的自定义模型", 15 | "puzzle.option.render_layer_overrides":"渲染层覆盖", 16 | "puzzle.midnightconfig.title":"Puzzle 高级设置" 17 | } 18 | -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/lang/zh_tw.json: -------------------------------------------------------------------------------- 1 | { 2 | "puzzle.text.update_available":"有新的更新可用!", 3 | "puzzle.screen.title":"Puzzle 設定", 4 | "puzzle.page.graphics":"圖形", 5 | "puzzle.page.resources":"資源", 6 | "puzzle.page.performance":"效能", 7 | "puzzle.page.misc":"其他", 8 | "puzzle.option.check_for_updates":"檢查更新", 9 | "puzzle.option.check_for_updates.tooltip":"啟用 Puzzle 內建的更新檢查器", 10 | "puzzle.option.show_version_info":"顯示 Puzzle 版本資訊", 11 | "puzzle.option.show_version_info.tooltip":"在標題畫面和 F3 選單上顯示\n目前 Puzzle 版本和更新狀態的資訊", 12 | "puzzle.option.resourcepack_splash_screen":"使用資源包的啟動畫面", 13 | "puzzle.option.resourcepack_splash_screen.tooltip":"允許資源包使用 OptiFine 格式變更\nMinecraft 的載入/啟動畫面", 14 | "puzzle.option.better_splash_screen_blend":"更好的啟動畫面標誌混合", 15 | "puzzle.option.better_splash_screen_blend.tooltip":"變更啟動畫面標誌使用的混合類型,\n使其更好地與自訂顏色的標誌配合使用", 16 | "puzzle.option.unlimited_model_rotations":"無限模型旋轉", 17 | "puzzle.option.unlimited_model_rotations.tooltip":"解鎖自訂方塊/物品模型的完整 360° 旋轉", 18 | "puzzle.option.bigger_custom_models":"更大的自訂模型", 19 | "puzzle.option.bigger_custom_models.tooltip":"將自訂方塊/物品模型的大小限制\n從 3×3×3 增加到 5×5×5", 20 | "puzzle.midnightconfig.title":"Puzzle 進階設定", 21 | "puzzle.midnightconfig.category.gui":"介面", 22 | "puzzle.midnightconfig.category.features":"功能", 23 | "puzzle.midnightconfig.category.internal":"內部", 24 | "puzzle.midnightconfig.tooltip":"僅供進階使用者使用的選項", 25 | 26 | "cullleaves.puzzle.option.enabled": "剔除樹葉", 27 | "cullleaves.puzzle.option.enabled.tooltip": "啟用樹葉剔除以提升效能", 28 | "iris.puzzle.option.enableShaders": "啟用光影", 29 | "iris.puzzle.option.enableShaders.tooltip": "是否啟用光影包", 30 | "iris.puzzle.option.open": "開啟", 31 | "options.iris.shaderPackSelection.tooltip": "開啟一個畫面以選擇\n並設定光影包", 32 | "lambdabettergrass.option.mode.tooltip": "使草地的側面與\n相鄰的草地連接", 33 | "lambdabettergrass.option.better_snow.tooltip": "為被雪/苔蘚包圍的非完整方塊\n加入純粹視覺上的雪/苔蘚層", 34 | "config.dynamicfps.reduce_when_unfocused.tooltip": "在未聚焦時降低 Minecraft 的 FPS\n(例如,另一個視窗被聚焦或遊戲被隱藏)\n以節省電力和系統資源", 35 | "config.dynamicfps.unfocused_fps.tooltip": "Minecraft 在未聚焦時\n允許繪製的 FPS", 36 | "config.dynamicfps.restore_when_hovered.tooltip": "當預覽 Minecraft 時是否停止\nFPS 限制(例如,將滑鼠懸停在工作列或 Dock 上)", 37 | "config.dynamicfps.run_gc_on_unfocus.tooltip": "在 Minecraft 未聚焦時執行垃圾回收器\n以釋放一些記憶體", 38 | "config.dynamicfps.unfocused_volume.tooltip": "遊戲在未聚焦時播放聲音的音量\n(例如,選取了另一個視窗)", 39 | "config.dynamicfps.hidden_volume.tooltip": "遊戲在不可見時播放聲音的音量\n(例如,最小化、被其他視窗覆蓋\n或在另一個虛擬桌面上)", 40 | "entity_texture_features.puzzle.emissive_type.brighter": "§e更亮", 41 | "entity_texture_features.puzzle.emissive_type.default": "§6預設" 42 | } 43 | -------------------------------------------------------------------------------- /common/src/main/resources/assets/puzzle/textures/gui/sprites/icon/button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PuzzleMC/Puzzle/7caadedcf1349f403e5adbd7c26ed2713805403c/common/src/main/resources/assets/puzzle/textures/gui/sprites/icon/button.png -------------------------------------------------------------------------------- /common/src/main/resources/puzzle-gui.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "package": "net.puzzlemc.gui.mixin", 4 | "compatibilityLevel": "JAVA_17", 5 | "client": [ 6 | "MixinOptionsScreen" 7 | ], 8 | "injectors": { 9 | "defaultRequire": 1 10 | } 11 | } -------------------------------------------------------------------------------- /common/src/main/resources/puzzle-models.accesswidener: -------------------------------------------------------------------------------- 1 | accessWidener v1 named 2 | accessible class net/minecraft/client/render/model/json/ModelElement$Deserializer 3 | accessible method net/minecraft/client/render/RenderLayer of (Ljava/lang/String;ILcom/mojang/blaze3d/pipeline/RenderPipeline;Lnet/minecraft/client/render/RenderLayer$MultiPhaseParameters;)Lnet/minecraft/client/render/RenderLayer$MultiPhase; 4 | accessible class net/minecraft/client/render/RenderLayer$MultiPhaseParameters 5 | accessible class net/minecraft/client/render/RenderPhase$Texture 6 | accessible method net/minecraft/client/render/RenderLayer$MultiPhaseParameters$Builder texture (Lnet/minecraft/client/render/RenderPhase$TextureBase;)Lnet/minecraft/client/render/RenderLayer$MultiPhaseParameters$Builder; 7 | accessible method net/minecraft/client/render/RenderLayer$MultiPhaseParameters$Builder build (Z)Lnet/minecraft/client/render/RenderLayer$MultiPhaseParameters; -------------------------------------------------------------------------------- /common/src/main/resources/puzzle-models.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "package": "net.puzzlemc.models.mixin", 4 | "compatibilityLevel": "JAVA_17", 5 | "client": [ 6 | "MixinModelElementDeserializer" 7 | ], 8 | "injectors": { 9 | "defaultRequire": 1 10 | } 11 | } -------------------------------------------------------------------------------- /common/src/main/resources/puzzle-splashscreen.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "package": "net.puzzlemc.splashscreen.mixin", 4 | "compatibilityLevel": "JAVA_17", 5 | "client": [ 6 | "MixinSplashScreen", 7 | "RenderPipelinesAccessor" 8 | ], 9 | "injectors": { 10 | "defaultRequire": 1 11 | } 12 | } -------------------------------------------------------------------------------- /fabric/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.github.johnrengelman.shadow' 3 | id "me.shedaniel.unified-publishing" 4 | } 5 | repositories { 6 | maven { url "https://maven.terraformersmc.com/releases" } 7 | } 8 | 9 | architectury { 10 | platformSetupLoomIde() 11 | fabric() 12 | } 13 | 14 | configurations { 15 | common 16 | shadowCommon // Don't use shadow from the shadow plugin since it *excludes* files. 17 | compileClasspath.extendsFrom common 18 | runtimeClasspath.extendsFrom common 19 | developmentFabric.extendsFrom common 20 | archivesBaseName = rootProject.archives_base_name + "-fabric" 21 | version = rootProject.mod_version + "+" + rootProject.minecraft_version 22 | } 23 | 24 | dependencies { 25 | modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" 26 | modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" 27 | modImplementation include ("maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric") 28 | 29 | modImplementation ("com.terraformersmc:modmenu:${project.modmenu_version}") { 30 | exclude(group: "net.fabricmc.fabric-api") 31 | } 32 | 33 | common(project(path: ":common", configuration: "namedElements")) { transitive false } 34 | shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } 35 | } 36 | 37 | processResources { 38 | inputs.property "version", rootProject.version 39 | 40 | filesMatching("fabric.mod.json") { 41 | expand "version": rootProject.version 42 | } 43 | } 44 | 45 | shadowJar { 46 | exclude "architectury.common.json" 47 | 48 | configurations = [project.configurations.shadowCommon] 49 | archiveClassifier = "dev-shadow" 50 | } 51 | 52 | remapJar { 53 | input.set shadowJar.archiveFile 54 | dependsOn shadowJar 55 | } 56 | 57 | sourcesJar { 58 | def commonSources = project(":common").sourcesJar 59 | dependsOn commonSources 60 | from commonSources.archiveFile.map { zipTree(it) } 61 | } 62 | 63 | components.java { 64 | withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { 65 | skip() 66 | } 67 | } 68 | 69 | unifiedPublishing { 70 | project { 71 | displayName = "Puzzle $rootProject.version - Fabric $project.minecraft_version" 72 | releaseType = "$project.release_type" 73 | changelog = releaseChangelog() 74 | gameVersions = [] 75 | gameLoaders = ["fabric","quilt"] 76 | mainPublication remapJar 77 | relations { 78 | depends { 79 | curseforge = "fabric-api" 80 | modrinth = "fabric-api" 81 | } 82 | includes { 83 | curseforge = "midnightlib" 84 | modrinth = "midnightlib" 85 | } 86 | } 87 | 88 | var CURSEFORGE_TOKEN = project.findProperty("CURSEFORGE_TOKEN") ?: System.getenv("CURSEFORGE_TOKEN") 89 | if (CURSEFORGE_TOKEN != null) { 90 | curseforge { 91 | token = CURSEFORGE_TOKEN 92 | id = rootProject.curseforge_id 93 | gameVersions.addAll "Java 21", project.minecraft_version 94 | if (project.supported_versions != "") gameVersions.addAll project.supported_versions 95 | } 96 | } 97 | 98 | var MODRINTH_TOKEN = project.findProperty("MODRINTH_TOKEN") ?: System.getenv("MODRINTH_TOKEN") 99 | if (MODRINTH_TOKEN != null) { 100 | modrinth { 101 | token = MODRINTH_TOKEN 102 | id = rootProject.modrinth_id 103 | version = "$rootProject.version-$project.name" 104 | gameVersions.addAll project.minecraft_version 105 | if (project.supported_versions != "") gameVersions.addAll project.supported_versions 106 | } 107 | } 108 | } 109 | } -------------------------------------------------------------------------------- /fabric/src/main/java/net/puzzlemc/fabric/PuzzleFabric.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.fabric; 2 | 3 | import net.fabricmc.api.ClientModInitializer; 4 | import net.fabricmc.fabric.api.resource.ResourceManagerHelper; 5 | import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; 6 | import net.minecraft.resource.ResourceManager; 7 | import net.minecraft.resource.ResourceType; 8 | import net.minecraft.util.Identifier; 9 | import net.puzzlemc.core.PuzzleCore; 10 | import net.puzzlemc.splashscreen.PuzzleSplashScreen; 11 | 12 | public class PuzzleFabric implements ClientModInitializer { 13 | @Override 14 | public void onInitializeClient() { 15 | PuzzleCore.initModules(); 16 | 17 | ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() { 18 | @Override 19 | public Identifier getFabricId() { 20 | return Identifier.of("puzzle", "splash_screen"); 21 | } 22 | @Override 23 | public void reload(ResourceManager manager) { 24 | PuzzleSplashScreen.ReloadListener.INSTANCE.reload(manager); 25 | } 26 | }); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /fabric/src/main/java/net/puzzlemc/fabric/modmenu/ModMenuIntegration.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.fabric.modmenu; 2 | 3 | import com.terraformersmc.modmenu.api.ConfigScreenFactory; 4 | import com.terraformersmc.modmenu.api.ModMenuApi; 5 | import net.puzzlemc.gui.screen.PuzzleOptionsScreen; 6 | 7 | public class ModMenuIntegration implements ModMenuApi { 8 | @Override 9 | public ConfigScreenFactory getModConfigScreenFactory() { 10 | return PuzzleOptionsScreen::new; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /fabric/src/main/resources/fabric.mod.json: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 1, 3 | "id": "puzzle", 4 | "version": "${version}", 5 | 6 | "name": "Puzzle", 7 | "description": "Unites optifine replacement mods in a clean & vanilla-style gui", 8 | "authors": [ 9 | "PuzzleMC", 10 | "Motschen" 11 | ], 12 | "contact": { 13 | "homepage": "https://www.midnightdust.eu/", 14 | "sources": "https://github.com/TeamMidnightDust/Puzzle", 15 | "issues": "https://github.com/TeamMidnightDust/Puzzle/issues" 16 | }, 17 | 18 | "license": "MIT", 19 | "icon": "assets/puzzle/icon.png", 20 | 21 | "environment": "client", 22 | 23 | "entrypoints": { 24 | "client": [ 25 | "net.puzzlemc.fabric.PuzzleFabric" 26 | ], 27 | "modmenu": [ 28 | "net.puzzlemc.fabric.modmenu.ModMenuIntegration" 29 | ] 30 | }, 31 | 32 | "mixins": [ 33 | "puzzle-gui.mixins.json", 34 | "puzzle-models.mixins.json", 35 | "puzzle-splashscreen.mixins.json" 36 | ], 37 | 38 | "depends": { 39 | "fabric": "*", 40 | "minecraft": ">=1.21" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Done to increase the memory available to gradle. 2 | org.gradle.jvmargs=-Xmx2G 3 | 4 | minecraft_version=1.21.5 5 | supported_versions= 6 | yarn_mappings=1.21.5+build.1 7 | enabled_platforms=fabric,neoforge 8 | 9 | # Mod Properties 10 | mod_version = 2.1.0 11 | maven_group = net.puzzlemc 12 | archives_base_name = puzzle 13 | release_type=release 14 | curseforge_id=563977 15 | modrinth_id=3IuO68q1 16 | 17 | # Modloaders 18 | fabric_loader_version=0.16.10 19 | fabric_api_version=0.119.5+1.21.5 20 | 21 | neoforge_version=21.5.3-beta 22 | yarn_mappings_patch_neoforge_version = 1.21+build.4 23 | 24 | # Libraries 25 | midnightlib_version = 1.7.0+1.21.4 26 | modmenu_version = 13.0.0-beta.1 27 | 28 | # Mod Integrations 29 | cull_leaves_version = 3.0.2-fabric 30 | ldl_version = 4.0.0+1.21.4 31 | lbg_version = 1.5.2+1.20.1 32 | iris_version = 1.8.0-beta.3+1.21-fabric 33 | continuity_version = 3.0.0-beta.5+1.21 34 | animatica_version = 0.6.1+1.21 35 | colormatic_version = 3.1.2 36 | borderless_mining_version = 1.1.8+1.20.1 37 | dynamic_fps_version = 3.6.3 38 | toml4j_version = 0.7.2 39 | cit_resewn_version = 1.1.3+1.20 40 | complete_config_version = 2.3.0 41 | spruceui_version=5.0.0+1.20 42 | emf_version=2.4.1 43 | etf_version=6.2.10 44 | exordium_version=1.2.1-1.20.2 45 | # Required for LBG 46 | quilt_loader_version=0.19.0-beta.18 47 | quilt_fabric_api_version=7.0.1+0.83.0-1.20 48 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PuzzleMC/Puzzle/7caadedcf1349f403e5adbd7c26ed2713805403c/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /neoforge/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.github.johnrengelman.shadow' 3 | id "me.shedaniel.unified-publishing" 4 | } 5 | 6 | repositories { 7 | maven { 8 | name = 'NeoForged' 9 | url = 'https://maven.neoforged.net/releases' 10 | } 11 | } 12 | 13 | 14 | architectury { 15 | platformSetupLoomIde() 16 | neoForge() 17 | } 18 | 19 | loom { 20 | accessWidenerPath = project(":common").loom.accessWidenerPath 21 | } 22 | 23 | configurations { 24 | common { 25 | canBeResolved = true 26 | canBeConsumed = false 27 | } 28 | compileClasspath.extendsFrom common 29 | runtimeClasspath.extendsFrom common 30 | developmentNeoForge.extendsFrom common 31 | 32 | // Files in this configuration will be bundled into your mod using the Shadow plugin. 33 | // Don't use the `shadow` configuration from the plugin itself as it's meant for excluding files. 34 | shadowBundle { 35 | canBeResolved = true 36 | canBeConsumed = false 37 | } 38 | archivesBaseName = rootProject.archives_base_name + "-neoforge" 39 | version = rootProject.mod_version + "+" + rootProject.minecraft_version 40 | } 41 | 42 | dependencies { 43 | neoForge "net.neoforged:neoforge:$rootProject.neoforge_version" 44 | modImplementation ("maven.modrinth:midnightlib:${rootProject.midnightlib_version}-neoforge") 45 | 46 | common(project(path: ':common', configuration: 'namedElements')) { transitive false } 47 | shadowBundle project(path: ':common', configuration: 'transformProductionNeoForge') 48 | } 49 | 50 | processResources { 51 | inputs.property 'version', rootProject.version 52 | 53 | filesMatching('META-INF/neoforge.mods.toml') { 54 | expand version: rootProject.version 55 | } 56 | } 57 | 58 | shadowJar { 59 | configurations = [project.configurations.shadowBundle] 60 | archiveClassifier = 'dev-shadow' 61 | } 62 | 63 | remapJar { 64 | input.set shadowJar.archiveFile 65 | } 66 | 67 | sourcesJar { 68 | def commonSources = project(":common").sourcesJar 69 | dependsOn commonSources 70 | from commonSources.archiveFile.map { zipTree(it) } 71 | } 72 | 73 | components.java { 74 | withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { 75 | skip() 76 | } 77 | } 78 | 79 | unifiedPublishing { 80 | project { 81 | displayName = "Puzzle $rootProject.version - NeoForge $project.minecraft_version" 82 | releaseType = "alpha" 83 | changelog = releaseChangelog() 84 | gameVersions = [] 85 | gameLoaders = ["neoforge"] 86 | mainPublication remapJar 87 | relations { 88 | depends { 89 | curseforge = "midnightlib" 90 | modrinth = "midnightlib" 91 | } 92 | } 93 | 94 | var CURSEFORGE_TOKEN = project.findProperty("CURSEFORGE_TOKEN") ?: System.getenv("CURSEFORGE_TOKEN") 95 | if (CURSEFORGE_TOKEN != null) { 96 | curseforge { 97 | token = CURSEFORGE_TOKEN 98 | id = rootProject.curseforge_id 99 | gameVersions.addAll "Java 21", project.minecraft_version 100 | if (project.supported_versions != "") gameVersions.addAll project.supported_versions 101 | } 102 | } 103 | 104 | var MODRINTH_TOKEN = project.findProperty("MODRINTH_TOKEN") ?: System.getenv("MODRINTH_TOKEN") 105 | if (MODRINTH_TOKEN != null) { 106 | modrinth { 107 | token = MODRINTH_TOKEN 108 | id = rootProject.modrinth_id 109 | version = "$rootProject.version-$project.name" 110 | gameVersions.addAll project.minecraft_version 111 | if (project.supported_versions != "") gameVersions.addAll project.supported_versions 112 | } 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /neoforge/gradle.properties: -------------------------------------------------------------------------------- 1 | loom.platform=neoforge -------------------------------------------------------------------------------- /neoforge/src/main/java/net/puzzlemc/neoforge/PuzzleNeoForge.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.neoforge; 2 | 3 | import net.minecraft.util.Identifier; 4 | import net.neoforged.api.distmarker.Dist; 5 | import net.neoforged.bus.api.SubscribeEvent; 6 | import net.neoforged.fml.ModList; 7 | import net.neoforged.fml.common.EventBusSubscriber; 8 | import net.neoforged.fml.common.Mod; 9 | import net.neoforged.neoforge.client.event.AddClientReloadListenersEvent; 10 | import net.neoforged.neoforge.client.gui.IConfigScreenFactory; 11 | import net.puzzlemc.core.PuzzleCore; 12 | import net.puzzlemc.gui.screen.PuzzleOptionsScreen; 13 | import net.puzzlemc.splashscreen.PuzzleSplashScreen; 14 | 15 | import static net.puzzlemc.core.PuzzleCore.MOD_ID; 16 | 17 | @Mod(value = MOD_ID, dist = Dist.CLIENT) 18 | public class PuzzleNeoForge { 19 | public PuzzleNeoForge() { 20 | PuzzleCore.initModules(); 21 | ModList.get().getModContainerById(MOD_ID).orElseThrow().registerExtensionPoint(IConfigScreenFactory.class, (client, parent) -> new PuzzleOptionsScreen(parent)); 22 | } 23 | 24 | @EventBusSubscriber(modid = MOD_ID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT) 25 | public static class MidnightLibBusEvents { 26 | @SubscribeEvent 27 | public static void onResourceReload(AddClientReloadListenersEvent event) { 28 | event.addListener(Identifier.of(MOD_ID, "splash_screen"), PuzzleSplashScreen.ReloadListener.INSTANCE); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /neoforge/src/main/java/net/puzzlemc/neoforge/mixin/splashscreen/MixinNeoForgeLoadingOverlay.java: -------------------------------------------------------------------------------- 1 | package net.puzzlemc.neoforge.mixin.splashscreen; 2 | 3 | import net.minecraft.client.MinecraftClient; 4 | import net.minecraft.client.gui.DrawContext; 5 | import net.minecraft.client.gui.screen.SplashOverlay; 6 | import net.minecraft.resource.ResourceReload; 7 | import net.neoforged.neoforge.client.loading.NeoForgeLoadingOverlay; 8 | import net.puzzlemc.core.config.PuzzleConfig; 9 | import org.spongepowered.asm.mixin.Mixin; 10 | import org.spongepowered.asm.mixin.injection.At; 11 | import org.spongepowered.asm.mixin.injection.Inject; 12 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; 13 | 14 | import java.util.Optional; 15 | import java.util.function.Consumer; 16 | 17 | @Mixin(NeoForgeLoadingOverlay.class) 18 | public class MixinNeoForgeLoadingOverlay extends SplashOverlay { 19 | public MixinNeoForgeLoadingOverlay(MinecraftClient client, ResourceReload monitor, Consumer> exceptionHandler, boolean reloading) { 20 | super(client, monitor, exceptionHandler, reloading); 21 | } 22 | 23 | @Inject(method = "render", at = @At("HEAD"), cancellable = true) // Replaces the NeoForge loading screen in later stages with the (customized) vanilla version 24 | private void redirectNeoForgeLoading(DrawContext context, int mouseX, int mouseY, float tickDelta, CallbackInfo ci) { 25 | if (PuzzleConfig.resourcepackSplashScreen && PuzzleConfig.hasCustomSplashScreen) { 26 | super.render(context, mouseX, mouseY, tickDelta); 27 | ci.cancel(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /neoforge/src/main/resources/META-INF/neoforge.mods.toml: -------------------------------------------------------------------------------- 1 | modLoader = "javafml" 2 | loaderVersion = "[2,)" 3 | #issueTrackerURL = "" 4 | license = "MIT License" 5 | 6 | [[mods]] 7 | modId = "puzzle" 8 | version = "${version}" 9 | displayName = "Puzzle" 10 | logoFile = "puzzle.png" 11 | authors = "PuzzleMC, Motschen" 12 | description = ''' 13 | Unites optifine replacement mods in a clean & vanilla-style gui 14 | ''' 15 | 16 | [[mixins]] 17 | config = "puzzle-gui.mixins.json" 18 | [[mixins]] 19 | config = "puzzle-models.mixins.json" 20 | [[mixins]] 21 | config = "puzzle-splashscreen.mixins.json" 22 | [[mixins]] 23 | config = "puzzle-splashscreen_neoforge.mixins.json" 24 | 25 | [[dependencies.puzzle]] 26 | modId = "neoforge" 27 | mandatory = true 28 | versionRange = "[21.0,)" 29 | ordering = "NONE" 30 | side = "CLIENT" 31 | 32 | [[dependencies.puzzle]] 33 | modId = "minecraft" 34 | mandatory = true 35 | versionRange = "[1.21,)" 36 | ordering = "NONE" 37 | side = "CLIENT" -------------------------------------------------------------------------------- /neoforge/src/main/resources/puzzle-splashscreen_neoforge.mixins.json: -------------------------------------------------------------------------------- 1 | { 2 | "required": true, 3 | "package": "net.puzzlemc.neoforge.mixin", 4 | "compatibilityLevel": "JAVA_17", 5 | "client": [ 6 | "splashscreen.MixinNeoForgeLoadingOverlay" 7 | ], 8 | "injectors": { 9 | "defaultRequire": 1 10 | } 11 | } -------------------------------------------------------------------------------- /neoforge/src/main/resources/puzzle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PuzzleMC/Puzzle/7caadedcf1349f403e5adbd7c26ed2713805403c/neoforge/src/main/resources/puzzle.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | maven { url "https://maven.fabricmc.net/" } 4 | maven { url "https://maven.architectury.dev/" } 5 | maven { url "https://maven.neoforged.net/releases" } 6 | gradlePluginPortal() 7 | } 8 | } 9 | 10 | include("common") 11 | include("fabric") 12 | include("neoforge") 13 | //include("quilt") 14 | 15 | rootProject.name = "puzzle" 16 | --------------------------------------------------------------------------------