32 Commits

Author SHA1 Message Date
Martin Prokoph
ab83b2744a Fix mixin apply error 2024-11-05 19:10:09 +01:00
Martin Prokoph
9ee7ab1b89 Update to 1.21.3 2024-11-05 10:29:04 +01:00
Martin Prokoph
07af46da3c Handle incorrectly defined blend functions
- Now logs a warning instead of crashing
2024-09-24 23:40:12 +02:00
Martin Prokoph
f230cf3a4e Merge pull request #81 from C4BR3R4/patch-1
Create es_es.json
2024-09-24 23:37:10 +02:00
C4BR3R4
8646efb161 Create es_es.json
Changelog: http://c4br3r4.es/index.php?topic=1234.0
2024-09-07 14:17:47 +02:00
Martin Prokoph
fb1852dc2b Actually disable blending & Update example pack
- Blending will now be disabled when set to "off" instead of using the default blend function
2024-09-07 12:33:28 +02:00
Martin Prokoph
9dbe28242a Publishing: Add MidnightLib to the relations 2024-09-06 18:52:10 +02:00
Martin Prokoph
35c613a536 Puzzle 2.0.0 - Multiplatform & Cleaner code
- Removed intrusive branding (previously visible on Title screen and F3 menu)
- De-modularized: Previously, Puzzle was split into multiple modules which complicated the development process and was just unnecessary
- Experimental NeoForge support
- Many small improvements
- puzzle-splashscreen: Improved  background image blending
- puzzle-splashscreen: Added support for custom blend functions for full OptiFine parity
2024-09-06 18:44:27 +02:00
Martin Prokoph
651483af22 Update to 1.21 2024-06-16 18:53:43 +02:00
Martin Prokoph
b3b49cb8b8 Port to 1.20.6
- Port to 1.20.6
- Move compatibility code into individual classes
2024-05-04 19:55:04 +02:00
Martin Prokoph
39261272bf Puzzle 1.6.1 for 1.20.4
- Update to 1.20.4
- Re-Use MidnightConfig's list widget -> prettier background
2023-12-11 21:33:54 +01:00
Motschen
bc01662cda Puzzle 1.6.0 - 1.20.2 & Stability improvements
- Port to 1.20.2
- Improve stability by skipping outdated compat entries
- Update EMF integration
2023-09-24 21:18:45 +02:00
Martin Prokoph
1dc7245a99 Merge pull request #72 from Gazmanovich/1.20-1
Create be_by.json
2023-09-23 12:24:59 +02:00
Martin Prokoph
860d969c1d Merge pull request #69 from ImVietnam/patch-1
Create vi_vn.json
2023-09-23 12:24:37 +02:00
Alex Gazmanovich
acd3dbf9e2 Create be_by.json 2023-08-09 12:02:14 +03:00
I_am_Vietnam
cbd48603d2 Create vi_vn.json 2023-07-19 11:18:10 +07:00
Motschen
f91274dd90 Puzzle 1.5.2 - Fix crash without ModMenu
Fixes #67 & #68
2023-07-12 11:34:38 +02:00
Motschen
884ee8caf6 Puzzle 1.5.1 - 1.20 & Fixes
- Update to 1.20
- Fix version string behaving weirdly with ModMenu installed
- Integration for CEM replaced with EMF
2023-06-10 18:55:29 +02:00
Martin Prokoph
c921f3ff99 Update Traditional Chinese by @notlin4
Update Traditional Chinese by @notlin4
2023-06-10 16:52:45 +02:00
Martin Prokoph
8532a24b5e Merge pull request #59 from notlin4/patch-1
Update Traditional Chinese
2023-06-10 16:50:25 +02:00
Martin Prokoph
3a873df26a Merge pull request #60 from Felix14-v2/1.19.4
Update ru_ru.json
2023-06-10 16:49:57 +02:00
Martin Prokoph
e3615a79c4 Merge pull request #62 from Madis0/patch-2
Readme badges
2023-05-24 19:02:01 +02:00
Madis Otenurm
2704c2c80b Update README.md 2023-05-16 07:43:05 +03:00
Felix14-v2
83897109fe Update ru_ru.json
Oops
2023-04-21 15:41:08 +03:00
Felix14-v2
fc20a1b182 Update ru_ru.json 2023-04-21 15:29:29 +03:00
notlin4
927faea146 Update Traditional Chinese 2023-04-16 14:33:21 +08:00
Motschen
b979d5ac61 Puzzle 1.5.0 - 1.19.4, Options overhaul, Fixed splash screen
- Port to 1.19.4
- Overhaul the Puzzle Options screen
  - Categories are now displayed via tabs
- Fix #50 (Splash screen logo being pixelated)
- Add compatibility with Exordium
2023-03-15 18:54:29 +01:00
Martin Prokoph
12cdcba470 Merge pull request #54 from FITFC/1.19.3
Added lang/pt_br
2023-03-15 15:48:50 +01:00
FITFC
c9aa80f09f Added lang/pt_br 2022-12-24 12:45:21 -05:00
Motschen
12015d6ba4 Puzzle 1.4.2 - Update to 1.19.3
Here's a little Christmas present for y'all!
Puzzle now has 1.19.3 support.
2022-12-24 17:53:39 +01:00
Martin Prokoph
a8c89b11c7 Merge pull request #45 from Felix14-v2/1.19
Update ru_ru.json
2022-08-02 20:46:26 +00:00
Felix14-v2
f8ff656daa Update ru_ru.json 2022-08-02 23:35:50 +03:00
97 changed files with 1776 additions and 1651 deletions

Binary file not shown.

View File

@@ -1,2 +1,4 @@
# Puzzle
Unites optifine replacement mods in a clean & vanilla-style gui
[![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)

View File

@@ -1,168 +1,118 @@
// Based on https://github.com/OnyxStudios/Cardinal-Components-API/blob/1.17/build.gradle
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
plugins {
id "fabric-loom" version "0.12-SNAPSHOT" apply false
id "com.matthewprenger.cursegradle" version "1.4.0"
id "maven-publish"
id "java-library"
id "architectury-plugin" version "3.4-SNAPSHOT"
id "dev.architectury.loom" version "1.7-SNAPSHOT" apply false
id "me.shedaniel.unified-publishing" version "0.1.+" apply false
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
}
group = "net.puzzlemc"
archivesBaseName = "puzzle"
architectury {
minecraft = rootProject.minecraft_version
}
subprojects {
apply plugin: 'fabric-loom'
apply plugin: 'com.matthewprenger.cursegradle'
apply plugin: 'maven-publish'
apply plugin: 'java-library'
archivesBaseName = project.name
group = "${rootProject.group}.${rootProject.archivesBaseName}"
}
allprojects {
apply plugin: "fabric-loom"
sourceCompatibility = targetCompatibility = JavaVersion.VERSION_17
version = System.getenv("TRAVIS_TAG") ?: rootProject.mod_version
configurations {
dev
}
apply plugin: "dev.architectury.loom"
repositories {
maven { url 'https://jitpack.io' }
maven {
url = "https://api.modrinth.com/maven"
}
maven { url "https://maven.terraformersmc.com/releases" }
maven {
name = 'AperLambda'
url = 'https://aperlambda.github.io/maven'
}
mavenCentral()
maven {
name 'Gegy'
url 'https://maven.gegy.dev'
}
maven {
url "https://www.cursemaven.com"
content {
includeGroup "curse.maven"
}
}
maven {
name = 'JitPack'
url 'https://jitpack.io'
}
maven {
url "https://maven.shedaniel.me/"
}
maven { url "https://maven.quiltmc.org/repository/release/" }
}
dependencies {
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
mappings "net.fabricmc:yarn:${rootProject.yarn_mappings}:v2"
modApi "net.fabricmc:fabric-loader:${rootProject.loader_version}"
modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_version}"
// The following line declares the yarn mappings you may select this one as well.
mappings loom.layered {
it.mappings("net.fabricmc:yarn:$rootProject.yarn_mappings:v2")
it.mappings("dev.architectury:yarn-mappings-patch-neoforge:$rootProject.yarn_mappings_patch_neoforge_version")
}
modCompileOnlyApi ("maven.modrinth:cull-leaves:${project.cull_leaves_version}")
modCompileOnlyApi ("maven.modrinth:iris:${project.iris_version}")
modCompileOnly ("maven.modrinth:cit-resewn:${project.cit_resewn_version}")
modCompileOnlyApi ("maven.modrinth:continuity:${project.continuity_version}")
modCompileOnlyApi ("maven.modrinth:animatica:${project.animatica_version}")
modCompileOnlyApi ("maven.modrinth:colormatic:${project.colormatic_version}")
modCompileOnlyApi ("maven.modrinth:borderless-mining:${project.borderless_mining_version}")
modCompileOnlyApi ("maven.modrinth:dynamic-fps:${project.dynamic_fps_version}")
modCompileOnlyApi ("com.moandjiezana.toml:toml4j:${project.toml4j_version}")
modCompileOnlyApi ("maven.modrinth:entitytexturefeatures:${project.etf_version}")
modCompileOnlyApi ("maven.modrinth:entity-model-features:${project.emf_version}")
modCompileOnlyApi ("maven.modrinth:completeconfig:${project.complete_config_version}")
//modImplementation ("maven.modrinth:exordium:${project.exordium_version}")
modCompileOnlyApi ("maven.modrinth:lambdynamiclights:${project.ldl_version}")
modCompileOnlyApi ("maven.modrinth:lambdabettergrass:${project.lbg_version}")
modCompileOnlyApi "dev.lambdaurora:spruceui:${project.spruceui_version}"
}
}
processResources {
inputs.property "version", project.version
allprojects {
apply plugin: "java"
apply plugin: "architectury-plugin"
apply plugin: "maven-publish"
filesMatching("fabric.mod.json") {
expand "version": project.version
archivesBaseName = rootProject.archives_base_name
version = rootProject.mod_version
group = rootProject.maven_group
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
options.release = 21
}
ext {
releaseChangelog = {
def changes = new StringBuilder()
changes << "## Puzzle v$project.version for $project.minecraft_version\n[View the changelog](https://www.github.com/PuzzleMC/Puzzle/commits/)"
def proc = "git log --max-count=1 --pretty=format:%s".execute()
proc.in.eachLine { line ->
def processedLine = line.toString()
if (!processedLine.contains("New translations") && !processedLine.contains("Merge") && !processedLine.contains("branch")) {
changes << "\n- ${processedLine.capitalize()}"
}
}
proc.waitFor()
return changes.toString()
}
}
// ensure that the encoding is set to UTF-8, no matter what the system default is
// this fixes some edge cases with special characters not displaying correctly
// see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
tasks.withType(JavaCompile).configureEach {
it.options.encoding = "UTF-8"
it.options.release = 17
processResources {
// Minify json resources
doLast {
fileTree(dir: outputs.files.asPath, include: "**/*.json").each {
File file -> file.text = JsonOutput.toJson(new JsonSlurper().parse(file))
}
}
}
java {
// Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
// if it is present.
// If you remove this line, sources will not be generated.
withSourcesJar()
}
jar {
}
afterEvaluate {
artifacts {
dev file: file("${project.buildDir}/libs/$archivesBaseName-${version}-dev.jar"), type: "jar", builtBy: sourcesJar
}
}
}
subprojects {
version = rootProject.version
}
subprojects.each { remapJar.dependsOn("${it.path}:remapJar") }
repositories {
maven {
name = "JitPack"
url = "https://jitpack.io"
}
maven {
name = "TerraformersMC"
url = "https://maven.terraformersmc.com/releases"
}
maven {
name = 'AperLambda'
url = 'https://aperlambda.github.io/maven'
}
mavenCentral()
maven {
name 'Gegy'
url 'https://maven.gegy.dev'
}
maven {
url = "https://api.modrinth.com/maven"
}
maven {
url "https://www.cursemaven.com"
content {
includeGroup "curse.maven"
}
}
maven {
name = 'JitPack'
url 'https://jitpack.io'
}
maven {
url "https://maven.shedaniel.me/"
}
}
dependencies {
modImplementation ("net.fabricmc.fabric-api:fabric-api:${project.fabric_version}")
modImplementation ("com.terraformersmc:modmenu:${project.mod_menu_version}") {
exclude group: "net.fabricmc.fabric-api"
}
modImplementation ("maven.modrinth:cull-leaves:${project.cull_leaves_version}")
modImplementation ("maven.modrinth:lambdynamiclights:${project.ldl_version}")
modImplementation ("maven.modrinth:lambdabettergrass:${project.lbg_version}")
modImplementation ("maven.modrinth:iris:${project.iris_version}")
modCompileOnly ("maven.modrinth:cit-resewn:${project.cit_resewn_version}")
modImplementation ("maven.modrinth:continuity:${project.continuity_version}")
modImplementation ("maven.modrinth:animatica:${project.animatica_version}")
modImplementation ("maven.modrinth:colormatic:${project.colormatic_version}")
modImplementation ("maven.modrinth:borderless-mining:${project.borderless_mining_version}")
modImplementation ("maven.modrinth:dynamic-fps:${project.dynamic_fps_version}")
modImplementation("com.moandjiezana.toml:toml4j:${project.toml4j_version}")
modImplementation ("maven.modrinth:entitytexturefeatures:${project.entitytexturefeatures_version}")
modImplementation ("maven.modrinth:cem:${project.cem_version}")
modImplementation "com.gitlab.Lortseam:completeconfig:${project.complete_config_version}"
modImplementation("org.aperlambda:lambdajcommon:1.8.1") {
exclude group: 'com.google.code.gson'
exclude group: 'com.google.guava'
}
modImplementation "dev.lambdaurora:spruceui:${project.spruceui_version}"
modImplementation "maven.modrinth:midnightlib:${project.midnightlib_version}"
include "maven.modrinth:midnightlib:${project.midnightlib_version}"
subprojects.each {
api project(path: ":${it.name}", configuration: "dev")
include project(":${it.name}")
}
}
publishing {
publications {
mavenJava(MavenPublication) {
artifact(file("${project.buildDir}/libs/${archivesBaseName}-${version}.jar")) {
builtBy(remapJar)
}
pom.withXml {
subprojects.each {
depNode.appendNode("groupId", it.group)
depNode.appendNode("artifactId", it.name)
depNode.appendNode("version", it.version)
depNode.appendNode("scope", "compile")
}
}
}
}
}

34
common/build.gradle Normal file
View File

@@ -0,0 +1,34 @@
architectury {
common(rootProject.enabled_platforms.split(","))
}
loom {
accessWidenerPath = file("src/main/resources/puzzle-models.accesswidener")
}
dependencies {
// We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies
// Do NOT use other classes from fabric loader
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
modCompileOnly "maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric"
modCompileOnly "org.quiltmc:quilt-loader:${rootProject.quilt_loader_version}"
modCompileOnlyApi "org.quiltmc.quilted-fabric-api:quilted-fabric-api:${rootProject.quilt_fabric_api_version}"
modCompileOnlyApi ("org.aperlambda:lambdajcommon:1.8.1") {
exclude group: 'com.google.code.gson'
exclude group: 'com.google.guava'
}
}
publishing {
publications {
mavenCommon(MavenPublication) {
artifactId = rootProject.archives_base_name
from components.java
}
}
// See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing.
repositories {
// Add repositories to publish to here.
}
}

View File

@@ -0,0 +1,18 @@
package net.puzzlemc.core;
import net.puzzlemc.core.config.PuzzleConfig;
import net.puzzlemc.gui.PuzzleGui;
import net.puzzlemc.splashscreen.PuzzleSplashScreen;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PuzzleCore {
public final static String MOD_ID = "puzzle";
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
public static void initModules() {
PuzzleConfig.init(MOD_ID, PuzzleConfig.class);
PuzzleGui.init();
PuzzleSplashScreen.init();
}
}

View File

@@ -0,0 +1,28 @@
package net.puzzlemc.core.config;
import eu.midnightdust.lib.config.MidnightConfig;
import java.util.ArrayList;
import java.util.List;
public class PuzzleConfig extends MidnightConfig {
private static final String GUI = "gui";
private static final String INTERNAL = "internal";
private static final String FEATURES = "features";
@Entry(category = GUI, name = "Disabled integrations") public static List<String> disabledIntegrations = new ArrayList<>();
@Entry(category = GUI, name = "Enable Puzzle button") public static boolean enablePuzzleButton = true;
@Entry(category = FEATURES, name = "puzzle.option.resourcepack_splash_screen") public static boolean resourcepackSplashScreen = true;
@Entry(category = FEATURES, name = "puzzle.option.unlimited_model_rotations") public static boolean unlimitedRotations = true;
@Entry(category = FEATURES, name = "puzzle.option.bigger_custom_models") public static boolean biggerModels = true;
@Entry(category = INTERNAL, name = "Enable debug messages") public static boolean debugMessages = false;
@Entry(category = INTERNAL, name = "Has custom splash screen") public static boolean hasCustomSplashScreen = false;
@Entry(category = INTERNAL, name = "Splash Background Color") public static int backgroundColor = 15675965;
@Entry(category = INTERNAL, name = "Splash Progress Bar Color") public static int progressBarColor = 16777215;
@Entry(category = INTERNAL, name = "Splash Progress Bar Background Color") public static int progressBarBackgroundColor = 15675965;
@Entry(category = INTERNAL, name = "Splash Progress Bar Frame Color") public static int progressFrameColor = 16777215;
@Entry(category = INTERNAL, name = "puzzle.option.better_splash_screen_blend") public static boolean disableBlend = false;
@Entry(category = INTERNAL, name = "Custom Blend Function") public static List<String> customBlendFunction = new ArrayList<>();
}

View File

@@ -2,15 +2,13 @@ package net.puzzlemc.gui;
import net.puzzlemc.core.config.PuzzleConfig;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.util.ArrayList;
import java.util.List;
public class PuzzleApi {
private static Logger LOGGER = LogManager.getLogger("puzzle-gui");
import static net.puzzlemc.core.PuzzleCore.LOGGER;
public class PuzzleApi {
public static List<PuzzleWidget> GRAPHICS_OPTIONS = new ArrayList<>();
public static List<PuzzleWidget> MISC_OPTIONS = new ArrayList<>();
public static List<PuzzleWidget> PERFORMANCE_OPTIONS = new ArrayList<>();
@@ -18,18 +16,22 @@ public class PuzzleApi {
public static void addToGraphicsOptions(PuzzleWidget button) {
GRAPHICS_OPTIONS.add(button);
if (PuzzleConfig.debugMessages) LOGGER.info(button.descriptionText.getContent().toString() + " -> Graphics Options");
if (PuzzleConfig.debugMessages)
LOGGER.info("{} -> Graphics Options", button.descriptionText.getContent().toString());
}
public static void addToMiscOptions(PuzzleWidget button) {
MISC_OPTIONS.add(button);
if (PuzzleConfig.debugMessages) LOGGER.info(button.descriptionText.getContent().toString() + " -> Misc Options");
if (PuzzleConfig.debugMessages)
LOGGER.info("{} -> Misc Options", button.descriptionText.getContent().toString());
}
public static void addToPerformanceOptions(PuzzleWidget button) {
PERFORMANCE_OPTIONS.add(button);
if (PuzzleConfig.debugMessages) LOGGER.info(button.descriptionText.getContent().toString() + "- > Performance Options");
if (PuzzleConfig.debugMessages)
LOGGER.info("{}- > Performance Options", button.descriptionText.getContent().toString());
}
public static void addToResourceOptions(PuzzleWidget button) {
RESOURCE_OPTIONS.add(button);
if (PuzzleConfig.debugMessages) LOGGER.info(button.descriptionText.getContent().toString() + " -> Resource Options");
if (PuzzleConfig.debugMessages)
LOGGER.info("{} -> Resource Options", button.descriptionText.getContent().toString());
}
}

View File

@@ -0,0 +1,68 @@
package net.puzzlemc.gui;
import eu.midnightdust.core.MidnightLib;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.minecraft.util.Identifier;
import net.puzzlemc.core.config.PuzzleConfig;
import net.puzzlemc.gui.compat.*;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.puzzlemc.splashscreen.PuzzleSplashScreen;
import static net.puzzlemc.core.PuzzleCore.LOGGER;
public class PuzzleGui {
public final static String id = "puzzle";
public static final Text YES = Text.translatable("gui.yes").formatted(Formatting.GREEN);
public static final Text NO = Text.translatable("gui.no").formatted(Formatting.RED);
public static final Identifier PUZZLE_BUTTON = Identifier.of(id, "icon/button");
public static void init() {
MidnightLib.hiddenMods.add("puzzle");
MinecraftClient client = MinecraftClient.getInstance();
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.of("Puzzle")));
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.translatable("puzzle.midnightconfig.title"), (button) -> button.setMessage(Text.of("OPEN")), (button) -> {
client.setScreen(PuzzleConfig.getScreen(client.currentScreen, "puzzle"));
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("Puzzle")));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("puzzle.option.resourcepack_splash_screen"), (button) -> button.setMessage(PuzzleConfig.resourcepackSplashScreen ? YES : NO), (button) -> {
PuzzleConfig.resourcepackSplashScreen = !PuzzleConfig.resourcepackSplashScreen;
PuzzleSplashScreen.resetColors();
PuzzleConfig.write(id);
MinecraftClient.getInstance().getTextureManager().registerTexture(PuzzleSplashScreen.LOGO, new PuzzleSplashScreen.LogoTexture(PuzzleSplashScreen.LOGO));
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("puzzle.option.unlimited_model_rotations"), (button) -> button.setMessage(PuzzleConfig.unlimitedRotations ? YES : NO), (button) -> {
PuzzleConfig.unlimitedRotations = !PuzzleConfig.unlimitedRotations;
PuzzleConfig.write(id);
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("puzzle.option.bigger_custom_models"), (button) -> button.setMessage(PuzzleConfig.biggerModels ? YES : NO), (button) -> {
PuzzleConfig.biggerModels = !PuzzleConfig.biggerModels;
PuzzleConfig.write(id);
}));
if (isActive("cullleaves")) CullLeavesCompat.init();
if (isActive("colormatic")) ColormaticCompat.init();
if (isActive("borderlessmining")) BorderlessMiningCompat.init();
if (isActive("iris")) IrisCompat.init();
}
public static boolean lateInitDone = false;
public static void lateInit() { // Some mods are initialized after Puzzle, so we can't access them in our ClientModInitializer
if (isActive("lambdynlights")) LDLCompat.init();
if (isActive("citresewn")) CITRCompat.init();
if (isActive("lambdabettergrass")) LBGCompat.init();
if (isActive("continuity")) ContinuityCompat.init();
try {
if (isActive("entity_texture_features")) ETFCompat.init();
if (isActive("entity_model_features")) EMFCompat.init();
} catch (Exception e) {
LOGGER.error("ETF/EMF config structure changed. Again...", e);
}
lateInitDone = true;
}
public static boolean isActive(String modid) {
return PlatformFunctions.isModLoaded(modid) && !PuzzleConfig.disabledIntegrations.contains(modid);
}
}

View File

@@ -0,0 +1,28 @@
package net.puzzlemc.gui.compat;
import link.infra.borderlessmining.config.ConfigHandler;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import static net.puzzlemc.gui.PuzzleGui.NO;
import static net.puzzlemc.gui.PuzzleGui.YES;
public class BorderlessMiningCompat {
public static void init() {
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.of("Borderless Mining")));
ConfigHandler bmConfig = ConfigHandler.getInstance();
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.translatable("config.borderlessmining.general.enabled"), (button) -> button.setMessage(bmConfig.isEnabledOrPending() ? YES : NO), (button) -> {
bmConfig.setEnabledPending(!bmConfig.isEnabledOrPending());
bmConfig.save();
}));
if (MinecraftClient.IS_SYSTEM_MAC) {
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.translatable("config.borderlessmining.general.enabledmac"), (button) -> button.setMessage(bmConfig.enableMacOS ? YES : NO), (button) -> {
bmConfig.enableMacOS = !bmConfig.enableMacOS;
bmConfig.setEnabledPending(bmConfig.isEnabled());
bmConfig.save();
}));
}
}
}

View File

@@ -0,0 +1,60 @@
package net.puzzlemc.gui.compat;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.puzzlemc.gui.PuzzleApi;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import shcm.shsupercm.fabric.citresewn.config.CITResewnConfig;
import static net.minecraft.screen.ScreenTexts.NO;
import static net.minecraft.screen.ScreenTexts.YES;
public class CITRCompat {
public static void init() {
if (CITResewnConfig.INSTANCE != null) {
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("CIT Resewn")));
CITResewnConfig citConfig = CITResewnConfig.INSTANCE;
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.citresewn.enabled.title"), (button) -> button.setMessage(citConfig.enabled ? YES : NO), (button) -> {
citConfig.enabled = !citConfig.enabled;
citConfig.write();
MinecraftClient.getInstance().reloadResources();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.citresewn.mute_errors.title"), (button) -> button.setMessage(citConfig.mute_errors ? YES : NO), (button) -> {
citConfig.mute_errors = !citConfig.mute_errors;
citConfig.write();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.citresewn.mute_warns.title"), (button) -> button.setMessage(citConfig.mute_warns ? YES : NO), (button) -> {
citConfig.mute_warns = !citConfig.mute_warns;
citConfig.write();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.citresewn.broken_paths.title"), (button) -> button.setMessage(citConfig.broken_paths ? YES : NO), (button) -> {
citConfig.broken_paths = !citConfig.broken_paths;
citConfig.write();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(0, 100, Text.translatable("config.citresewn.cache_ms.title"), () -> citConfig.cache_ms,
(button) -> button.setMessage(message(citConfig)),
(slider) -> {
try {
citConfig.cache_ms = slider.getInt();
} catch (NumberFormatException ignored) {
}
citConfig.write();
}));
}
}
public static Text message(CITResewnConfig config) {
int ticks = config.cache_ms;
if (ticks <= 1) {
return (Text.translatable("config.citresewn.cache_ms.ticks." + ticks)).formatted(Formatting.AQUA);
} else {
Formatting color = Formatting.DARK_RED;
if (ticks <= 40) color = Formatting.RED;
if (ticks <= 20) color = Formatting.GOLD;
if (ticks <= 10) color = Formatting.DARK_GREEN;
if (ticks <= 5) color = Formatting.GREEN;
return (Text.translatable("config.citresewn.cache_ms.ticks.any", ticks)).formatted(color);
}
}
}

View File

@@ -0,0 +1,46 @@
package net.puzzlemc.gui.compat;
import io.github.kvverti.colormatic.Colormatic;
import io.github.kvverti.colormatic.ColormaticConfig;
import io.github.kvverti.colormatic.ColormaticConfigController;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import static net.puzzlemc.gui.PuzzleGui.NO;
import static net.puzzlemc.gui.PuzzleGui.YES;
public class ColormaticCompat {
public static void init() {
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("Colormatic")));
ColormaticConfig colormaticConfig = Colormatic.config();
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("colormatic.config.option.clearSky"), (button) -> button.setMessage(colormaticConfig.clearSky ? YES : NO), (button) -> {
colormaticConfig.clearSky = !colormaticConfig.clearSky;
ColormaticConfigController.persist(colormaticConfig);
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("colormatic.config.option.clearVoid"), (button) -> button.setMessage(colormaticConfig.clearVoid ? YES : NO), (button) -> {
colormaticConfig.clearVoid = !colormaticConfig.clearVoid;
ColormaticConfigController.persist(colormaticConfig);
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("colormatic.config.option.blendSkyLight"), (button) -> button.setMessage(colormaticConfig.blendSkyLight ? YES : NO), (button) -> {
colormaticConfig.blendSkyLight = !colormaticConfig.blendSkyLight;
ColormaticConfigController.persist(colormaticConfig);
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("colormatic.config.option.flickerBlockLight"), (button) -> button.setMessage(colormaticConfig.flickerBlockLight ? YES : NO), (button) -> {
colormaticConfig.flickerBlockLight = !colormaticConfig.flickerBlockLight;
ColormaticConfigController.persist(colormaticConfig);
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(0, 100, Text.translatable("colormatic.config.option.relativeBlockLightIntensity"),
() -> (int) (100*(1.0 - colormaticConfig.relativeBlockLightIntensityExponent / -16.0)),
(button) -> button.setMessage(Text.translatable("colormatic.config.option.relativeBlockLightIntensity")
.append(": ")
.append(Text.literal(String.valueOf((int)(100 * Math.exp(ColormaticConfig.scaled(colormaticConfig.relativeBlockLightIntensityExponent))))).append("%"))),
(slider) -> {
try {
colormaticConfig.relativeBlockLightIntensityExponent = ((1.00 - ((slider.getInt())/100f)) * -16.0);
ColormaticConfigController.persist(colormaticConfig);
}
catch (NumberFormatException ignored) {}
}));
}
}

View File

@@ -0,0 +1,27 @@
package net.puzzlemc.gui.compat;
import me.pepperbell.continuity.client.config.ContinuityConfig;
import me.pepperbell.continuity.client.config.Option;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import static net.puzzlemc.gui.PuzzleGui.NO;
import static net.puzzlemc.gui.PuzzleGui.YES;
public class ContinuityCompat {
public static void init() {
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("Continuity")));
ContinuityConfig contConfig = ContinuityConfig.INSTANCE;
contConfig.getOptionMapView().forEach((s, option) -> {
if (s.equals("use_manual_culling")) return;
try {
Option.BooleanOption booleanOption = ((Option.BooleanOption)option);
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("options.continuity."+s), (button) -> button.setMessage(booleanOption.get() ? YES : NO), (button) -> {
booleanOption.set(!booleanOption.get());
contConfig.save();
}));
} catch (Exception ignored) {}
});
}
}

View File

@@ -0,0 +1,21 @@
package net.puzzlemc.gui.compat;
import eu.midnightdust.cullleaves.config.CullLeavesConfig;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import static net.puzzlemc.gui.PuzzleGui.NO;
import static net.puzzlemc.gui.PuzzleGui.YES;
public class CullLeavesCompat {
public static void init() {
PuzzleApi.addToPerformanceOptions(new PuzzleWidget(Text.of("CullLeaves")));
PuzzleApi.addToPerformanceOptions(new PuzzleWidget(Text.translatable("cullleaves.puzzle.option.enabled"), (button) -> button.setMessage(CullLeavesConfig.enabled ? YES : NO), (button) -> {
CullLeavesConfig.enabled = !CullLeavesConfig.enabled;
CullLeavesConfig.write("cullleaves");
MinecraftClient.getInstance().worldRenderer.reload();
}));
}
}

View File

@@ -0,0 +1,39 @@
package net.puzzlemc.gui.compat;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import traben.entity_model_features.EMF;
import traben.entity_model_features.config.EMFConfig;
import java.util.EnumSet;
import java.util.NavigableSet;
import java.util.Objects;
import java.util.TreeSet;
import static net.puzzlemc.gui.PuzzleGui.NO;
import static net.puzzlemc.gui.PuzzleGui.YES;
public class EMFCompat {
public static void init() {
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("entity_model_features.title")));
EMFConfig emfConfig = EMF.config().getConfig();
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("entity_model_features.config.force_models"), (button) -> button.setMessage(emfConfig.attemptRevertingEntityModelsAlteredByAnotherMod ? YES : NO), (button) -> {
emfConfig.attemptRevertingEntityModelsAlteredByAnotherMod = !emfConfig.attemptRevertingEntityModelsAlteredByAnotherMod;
EMF.config().saveToFile();
}));
if (PlatformFunctions.isModLoaded("physicsmod")) {
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("entity_model_features.config.physics"), (button) -> button.setMessage(emfConfig.attemptPhysicsModPatch_2 != EMFConfig.PhysicsModCompatChoice.OFF ?
Text.translatable("entity_model_features.config." + (emfConfig.attemptPhysicsModPatch_2 == EMFConfig.PhysicsModCompatChoice.VANILLA ? "physics.1" : "physics.2")) : ScreenTexts.OFF), (button) -> {
final NavigableSet<EMFConfig.PhysicsModCompatChoice> set =
new TreeSet<>(EnumSet.allOf(EMFConfig.PhysicsModCompatChoice.class));
emfConfig.attemptPhysicsModPatch_2 = Objects.requireNonNullElseGet(
set.higher(emfConfig.attemptPhysicsModPatch_2), set::first);
EMF.config().saveToFile();
}));
}
}
}

View File

@@ -0,0 +1,47 @@
package net.puzzlemc.gui.compat;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import traben.entity_texture_features.ETFApi;
import traben.entity_texture_features.config.ETFConfig;
import java.util.EnumSet;
import java.util.NavigableSet;
import java.util.Objects;
import java.util.TreeSet;
import static net.puzzlemc.gui.PuzzleGui.NO;
import static net.puzzlemc.gui.PuzzleGui.YES;
public class ETFCompat {
public static void init() {
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.title")));
ETFConfig etfConfig = ETFApi.getETFConfigObject();
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.enable_custom_textures.title"), (button) -> button.setMessage(etfConfig.enableCustomTextures ? YES : NO), (button) -> {
etfConfig.enableCustomTextures = !etfConfig.enableCustomTextures;
ETFApi.saveETFConfigChangesAndResetETF();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.enable_emissive_textures.title"), (button) -> button.setMessage(etfConfig.enableEmissiveTextures ? YES : NO), (button) -> {
etfConfig.enableEmissiveTextures = !etfConfig.enableEmissiveTextures;
ETFApi.saveETFConfigChangesAndResetETF();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.emissive_mode.title"), (button) -> button.setMessage(
Text.literal(etfConfig.emissiveRenderMode.toString())), (button) -> {
final NavigableSet<ETFConfig.EmissiveRenderModes> set =
new TreeSet<>(EnumSet.allOf(ETFConfig.EmissiveRenderModes.class));
etfConfig.emissiveRenderMode = Objects.requireNonNullElseGet(
set.higher(etfConfig.emissiveRenderMode), set::first);
ETFApi.saveETFConfigChangesAndResetETF();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.blinking_mob_settings.title"), (button) -> button.setMessage(etfConfig.enableBlinking ? YES : NO), (button) -> {
etfConfig.enableBlinking = !etfConfig.enableBlinking;
ETFApi.saveETFConfigChangesAndResetETF();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.player_skin_features.title"), (button) -> button.setMessage(etfConfig.skinFeaturesEnabled ? YES : NO), (button) -> {
etfConfig.skinFeaturesEnabled = !etfConfig.skinFeaturesEnabled;
ETFApi.saveETFConfigChangesAndResetETF();
}));
}
}

View File

@@ -0,0 +1,25 @@
package net.puzzlemc.gui.compat;
import net.irisshaders.iris.api.v0.IrisApi;
import net.irisshaders.iris.api.v0.IrisApiConfig;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.puzzlemc.gui.PuzzleApi;
import net.puzzlemc.gui.PuzzleGui;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
public class IrisCompat {
public static void init() {
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.of("Iris")));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("iris.puzzle.option.enableShaders"), (button) -> button.setMessage(IrisApi.getInstance().getConfig().areShadersEnabled() ? PuzzleGui.YES : PuzzleGui.NO), (button) -> {
IrisApiConfig irisConfig = IrisApi.getInstance().getConfig();
irisConfig.setShadersEnabledAndApply(!irisConfig.areShadersEnabled());
}));
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) -> {
MinecraftClient client = MinecraftClient.getInstance();
client.setScreen((Screen) IrisApi.getInstance().openMainIrisScreenObj(client.currentScreen));
}));
}
}

View File

@@ -0,0 +1,19 @@
package net.puzzlemc.gui.compat;
import dev.lambdaurora.lambdabettergrass.LBGConfig;
import dev.lambdaurora.lambdabettergrass.LambdaBetterGrass;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import static net.puzzlemc.gui.PuzzleGui.NO;
import static net.puzzlemc.gui.PuzzleGui.YES;
public class LBGCompat {
public static void init() {
LBGConfig lbgConfig = LambdaBetterGrass.get().config;
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.of("LambdaBetterGrass")));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("lambdabettergrass.option.mode"), (button) -> button.setMessage(lbgConfig.getMode().getTranslatedText()), (button) -> lbgConfig.setMode(lbgConfig.getMode().next())));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("lambdabettergrass.option.better_snow"), (button) -> button.setMessage(lbgConfig.hasBetterLayer() ? YES : NO), (button) -> lbgConfig.setBetterLayer(!lbgConfig.hasBetterLayer())));
}
}

View File

@@ -0,0 +1,24 @@
package net.puzzlemc.gui.compat;
import dev.lambdaurora.lambdynlights.DynamicLightsConfig;
import dev.lambdaurora.lambdynlights.LambDynLights;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import static net.puzzlemc.gui.PuzzleGui.NO;
import static net.puzzlemc.gui.PuzzleGui.YES;
public class LDLCompat {
public static void init() {
DynamicLightsConfig ldlConfig = LambDynLights.get().config;
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.of("LambDynamicLights")));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("lambdynlights.option.mode"), (button) -> button.setMessage(ldlConfig.getDynamicLightsMode().getTranslatedText()), (button) -> ldlConfig.setDynamicLightsMode(ldlConfig.getDynamicLightsMode().next())));
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())));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.empty().append("DynLights: ").append(Text.translatable("lambdynlights.option.light_sources.block_entities")), (button) -> button.setMessage(ldlConfig.getBlockEntitiesLightSource().get() ? YES : NO), (button) -> ldlConfig.getBlockEntitiesLightSource().set(!ldlConfig.getBlockEntitiesLightSource().get())));
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())));
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())));
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())));
}
}

View File

@@ -0,0 +1,52 @@
package net.puzzlemc.gui.mixin;
import eu.midnightdust.core.config.MidnightLibConfig;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.minecraft.client.gui.widget.TextIconButtonWidget;
import net.minecraft.client.gui.widget.ThreePartsLayoutWidget;
import net.puzzlemc.core.config.PuzzleConfig;
import net.puzzlemc.gui.PuzzleGui;
import net.puzzlemc.gui.screen.PuzzleOptionsScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.option.OptionsScreen;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Objects;
@Mixin(OptionsScreen.class)
public abstract class MixinOptionsScreen extends Screen {
@Shadow @Final private ThreePartsLayoutWidget layout;
@Unique TextIconButtonWidget puzzle$button = TextIconButtonWidget.builder(Text.translatable("puzzle.screen.title"), (buttonWidget) ->
(Objects.requireNonNull(this.client)).setScreen(new PuzzleOptionsScreen(this)), true)
.dimension(20, 20).texture(PuzzleGui.PUZZLE_BUTTON, 20, 20).build();
private MixinOptionsScreen(Text title) {super(title);}
@Inject(at = @At("HEAD"), method = "init")
public void puzzle$onInit(CallbackInfo ci) {
if (PuzzleConfig.enablePuzzleButton) {
this.puzzle$setButtonPos();
this.addDrawableChild(puzzle$button);
}
}
@Inject(at = @At("TAIL"), method = "refreshWidgetPositions")
public void puzzle$onResize(CallbackInfo ci) {
if (PuzzleConfig.enablePuzzleButton) this.puzzle$setButtonPos();
}
@Unique
public void puzzle$setButtonPos() {
int i = 0;
if (PlatformFunctions.isModLoaded("lod")) i = i + 358;
if (MidnightLibConfig.config_screen_list.equals(MidnightLibConfig.ConfigButton.FALSE)) i = i - 25;
puzzle$button.setPosition(this.width / 2 - 178 + i, layout.getY() + layout.getFooterHeight() - 4);
}
}

View File

@@ -0,0 +1,92 @@
package net.puzzlemc.gui.screen;
import com.google.common.collect.Lists;
import net.minecraft.client.gui.tab.GridScreenTab;
import net.minecraft.client.gui.tab.Tab;
import net.minecraft.client.gui.tab.TabManager;
import net.minecraft.client.gui.widget.TabNavigationWidget;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.puzzlemc.gui.PuzzleGui;
import net.puzzlemc.gui.screen.widget.*;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import java.util.List;
import java.util.Objects;
public class PuzzleOptionsScreen extends Screen {
public PuzzleOptionListWidget list;
public List<Text> tooltip = null;
public TabManager tabManager = new TabManager(a -> {}, a -> {});
public Tab prevTab;
public TabNavigationWidget tabNavigation;
public static Text graphicsTab = Text.translatable("puzzle.page.graphics");
public static Text miscTab = Text.translatable("puzzle.page.misc");
public static Text performanceTab = Text.translatable("puzzle.page.performance");
public static Text resourcesTab = Text.translatable("puzzle.page.resources");
public PuzzleOptionsScreen(Screen parent) {
super(Text.translatable("puzzle.screen.title"));
this.parent = parent;
}
private final Screen parent;
@Override
protected void init() {
if (!PuzzleGui.lateInitDone) PuzzleGui.lateInit();
List<Tab> tabs = Lists.newArrayList();
if (!PuzzleApi.GRAPHICS_OPTIONS.isEmpty()) tabs.add(new GridScreenTab(graphicsTab));
if (!PuzzleApi.RESOURCE_OPTIONS.isEmpty()) tabs.add(new GridScreenTab(resourcesTab));
if (!PuzzleApi.PERFORMANCE_OPTIONS.isEmpty()) tabs.add(new GridScreenTab(performanceTab));
if (!PuzzleApi.MISC_OPTIONS.isEmpty()) tabs.add(new GridScreenTab(miscTab));
tabNavigation = TabNavigationWidget.builder(tabManager, this.width).tabs(tabs.toArray(new Tab[0])).build();
tabNavigation.selectTab(0, false);
tabNavigation.init();
prevTab = tabManager.getCurrentTab();
this.list = new PuzzleOptionListWidget(this.client, this.width, this.height - 57, 24, 25);
fillList();
if (tabs.size() > 1) {
this.addDrawableChild(tabNavigation);
list.renderHeaderSeparator = false;
}
this.addDrawableChild(list);
super.init();
this.addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, (button) -> Objects.requireNonNull(client).setScreen(parent)).dimensions(this.width / 2 - 100, this.height - 26, 200, 20).build());
}
private void fillList() {
List<PuzzleWidget> options = List.of();
if (tabManager.getCurrentTab() == null) return;
else {
Text title = tabManager.getCurrentTab().getTitle();
if (title.equals(graphicsTab)) options = PuzzleApi.GRAPHICS_OPTIONS;
else if (title.equals(miscTab)) options = PuzzleApi.MISC_OPTIONS;
else if (title.equals(performanceTab))
options = PuzzleApi.PERFORMANCE_OPTIONS;
else if (title.equals(resourcesTab)) options = PuzzleApi.RESOURCE_OPTIONS;
}
list.addAll(options);
}
@Override
public boolean keyPressed(int keyCode, int scanCode, int modifiers) {
if (this.tabNavigation.trySwitchTabsWithKey(keyCode)) return true;
return super.keyPressed(keyCode, scanCode, modifiers);
}
@Override
public void tick() {
super.tick();
if (prevTab != null && prevTab != tabManager.getCurrentTab()) {
prevTab = tabManager.getCurrentTab();
this.list.clear();
fillList();
list.setScrollAmount(0);
}
}
}

View File

@@ -0,0 +1,22 @@
package net.puzzlemc.gui.screen.widget;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.text.Text;
import java.util.function.Supplier;
public class PuzzleButtonWidget extends ButtonWidget {
private final PuzzleWidget.TextAction title;
public PuzzleButtonWidget(int x, int y, int width, int height, PuzzleWidget.TextAction title, PressAction onPress) {
super(x, y, width, height, Text.of(""), onPress, Supplier::get);
this.title = title;
}
@Override
public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
try { title.setTitle(this);
} catch (Exception e) {e.fillInStackTrace(); this.visible = false;}
super.renderWidget(context, mouseX, mouseY, delta);
}
}

View File

@@ -0,0 +1,83 @@
package net.puzzlemc.gui.screen.widget;
import eu.midnightdust.lib.config.MidnightConfig;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableTextContent;
import net.minecraft.util.Formatting;
import net.puzzlemc.gui.screen.PuzzleOptionsScreen;
import java.util.ArrayList;
import java.util.List;
import static net.puzzlemc.core.PuzzleCore.LOGGER;
@Environment(EnvType.CLIENT)
public class PuzzleOptionListWidget extends MidnightConfig.MidnightConfigListWidget {
TextRenderer textRenderer;
public PuzzleOptionListWidget(MinecraftClient minecraftClient, int i, int j, int k, int l) {
super(minecraftClient, i, j, k, l);
this.centerListVertically = false;
textRenderer = minecraftClient.textRenderer;
}
public void addAll(List<PuzzleWidget> buttons) {
int buttonX = this.width - 160;
for (PuzzleWidget button : buttons) {
if (button.buttonType == ButtonType.TEXT)
this.addButton(List.of(), Text.literal(" ").append(button.descriptionText).formatted(Formatting.BOLD));
else if (button.buttonType == ButtonType.BUTTON)
this.addButton(List.of(new PuzzleButtonWidget(buttonX, 0, 150, 20, button.buttonTextAction, button.onPress)), button.descriptionText);
else if (button.buttonType == ButtonType.SLIDER)
this.addButton(List.of(new PuzzleSliderWidget(button.min, button.max, buttonX, 0, 150, 20, button.defaultSliderValue.getAsInt(), button.buttonTextAction, button.changeSliderValue)), button.descriptionText);
else if (button.buttonType == ButtonType.TEXT_FIELD)
this.addButton(List.of(new PuzzleTextFieldWidget(textRenderer, buttonX, 0, 150, 20, button.setTextValue, button.changeTextValue)), button.descriptionText);
else
LOGGER.warn("Button {} is missing the buttonType variable. This shouldn't happen!", button);
}
}
public void addButton(List<ClickableWidget> buttons, Text text) {
var entry = new MidnightConfig.ButtonEntry(buttons, text, new MidnightConfig.EntryInfo());
entry.centered = buttons.isEmpty();
this.addEntry(entry);
}
public void renderWidget(DrawContext context, int mouseX, int mouseY, float delta) {
super.renderWidget(context, mouseX, mouseY, delta);
MidnightConfig.ButtonEntry e = this.getHoveredEntry();
if (client.currentScreen instanceof PuzzleOptionsScreen page && e != null && !e.buttons.isEmpty() &&
e.text.getContent() instanceof TranslatableTextContent content) {
ClickableWidget button = e.buttons.getFirst();
String key = null;
if (I18n.hasTranslation(content.getKey() + ".tooltip")) key = content.getKey() + ".tooltip";
else if (I18n.hasTranslation(content.getKey() + ".desc")) key = content.getKey() + ".desc";
if (key == null && content.getKey().endsWith(".title")) {
String strippedContent = content.getKey().substring(0, content.getKey().length()-6);
if (I18n.hasTranslation(strippedContent + ".tooltip")) key = strippedContent + ".tooltip";
else if (I18n.hasTranslation(strippedContent + ".desc")) key = strippedContent + ".desc";
}
if (key != null) {
List<Text> list = new ArrayList<>();
for (String str : I18n.translate(key).split("\n"))
list.add(Text.literal(str));
page.tooltip = list;
if (!button.isMouseOver(mouseX, mouseY)) {
context.drawTooltip(textRenderer, list, button.getX(), button.getY() + (button.getHeight() * 2));
}
else context.drawTooltip(textRenderer, list, mouseX, mouseY);
}
}
}
@Override
public MidnightConfig.ButtonEntry getHoveredEntry() {
return super.getHoveredEntry();
}
}

View File

@@ -17,7 +17,9 @@ public class PuzzleSliderWidget extends SliderWidget {
this.setTextAction = setTextAction;
this.changeAction = changeAction;
this.updateMessage();
try {
this.updateMessage();
} catch (Exception e) {e.fillInStackTrace(); this.visible = false;}
}
public int getInt() {
int difference = max - min;

View File

@@ -12,7 +12,9 @@ public class PuzzleTextFieldWidget extends TextFieldWidget {
super(textRenderer, x, y, width, height, Text.of(""));
this.setValueAction = setValue;
this.change = change;
setValueAction.setTextValue(this);
try {
setValueAction.setTextValue(this);
} catch (Exception e) {e.fillInStackTrace(); this.setVisible(false);}
}
@Override
public void write(String text) {

View File

@@ -1,7 +1,5 @@
package net.puzzlemc.gui.screen.widget;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
@@ -65,19 +63,15 @@ public class PuzzleWidget {
this.setTextValue = setValue;
this.changeTextValue = changeAction;
}
@Environment(EnvType.CLIENT)
public interface ChangeTextValueAction {
void onChange(TextFieldWidget textField);
}
@Environment(EnvType.CLIENT)
public interface ChangeSliderValueAction {
void onChange(PuzzleSliderWidget slider);
}
@Environment(EnvType.CLIENT)
public interface SetTextValueAction {
void setTextValue(TextFieldWidget textField);
}
@Environment(EnvType.CLIENT)
public interface TextAction {
void setTitle(ClickableWidget button);
}

View File

@@ -4,8 +4,8 @@ import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import net.minecraft.client.render.model.json.ModelElement;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.math.Vec3f;
import net.puzzlemc.core.config.PuzzleConfig;
import org.joml.Vector3f;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@@ -14,7 +14,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ModelElement.Deserializer.class)
public abstract class MixinModelElementDeserializer {
@Shadow protected abstract Vec3f deserializeVec3f(JsonObject object, String name);
@Shadow protected abstract Vector3f deserializeVec3f(JsonObject object, String name);
@Inject(at = @At("HEAD"),method = "deserializeRotationAngle", cancellable = true)
private void puzzle$deserializeRotationAngle(JsonObject object, CallbackInfoReturnable<Float> cir) {
@@ -24,10 +24,10 @@ public abstract class MixinModelElementDeserializer {
}
}
@Inject(at = @At("HEAD"),method = "deserializeTo", cancellable = true)
private void puzzle$deserializeTo(JsonObject object, CallbackInfoReturnable<Vec3f> cir) {
private void puzzle$deserializeTo(JsonObject object, CallbackInfoReturnable<Vector3f> cir) {
if (PuzzleConfig.biggerModels) {
Vec3f vec3f = this.deserializeVec3f(object, "to");
if (!(vec3f.getX() < -32.0F) && !(vec3f.getY() < -32.0F) && !(vec3f.getZ() < -32.0F) && !(vec3f.getX() > 48.0F) && !(vec3f.getY() > 48.0F) && !(vec3f.getZ() > 48.0F)) {
Vector3f vec3f = this.deserializeVec3f(object, "to");
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)) {
cir.setReturnValue(vec3f);
} else {
throw new JsonParseException("'to' specifier exceeds the allowed boundaries: " + vec3f);
@@ -35,10 +35,10 @@ public abstract class MixinModelElementDeserializer {
}
}
@Inject(at = @At("HEAD"),method = "deserializeFrom", cancellable = true)
private void puzzle$deserializeFrom(JsonObject object, CallbackInfoReturnable<Vec3f> cir) {
private void puzzle$deserializeFrom(JsonObject object, CallbackInfoReturnable<Vector3f> cir) {
if (PuzzleConfig.biggerModels) {
Vec3f vec3f = this.deserializeVec3f(object, "from");
if (!(vec3f.getX() < -32.0F) && !(vec3f.getY() < -32.0F) && !(vec3f.getZ() < -32.0F) && !(vec3f.getX() > 48.0F) && !(vec3f.getY() > 48.0F) && !(vec3f.getZ() > 48.0F)) {
Vector3f vec3f = this.deserializeVec3f(object, "from");
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)) {
cir.setReturnValue(vec3f);
} else {
throw new JsonParseException("'from' specifier exceeds the allowed boundaries: " + vec3f);

View File

@@ -0,0 +1,174 @@
package net.puzzlemc.splashscreen;
import eu.midnightdust.lib.util.MidnightColorUtil;
import eu.midnightdust.lib.util.PlatformFunctions;
import net.minecraft.client.texture.NativeImageBackedTexture;
import net.minecraft.resource.*;
import net.minecraft.util.Util;
import net.puzzlemc.core.config.PuzzleConfig;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.resource.metadata.TextureResourceMetadata;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.ResourceTexture;
import net.minecraft.util.Identifier;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import static net.puzzlemc.core.PuzzleCore.LOGGER;
import static net.puzzlemc.core.PuzzleCore.MOD_ID;
public class PuzzleSplashScreen {
public static final Identifier LOGO = Identifier.of("textures/gui/title/mojangstudios.png");
public static final Identifier BACKGROUND = Identifier.of("puzzle/splash_background.png");
public static File CONFIG_PATH = new File(String.valueOf(PlatformFunctions.getConfigDirectory().resolve(".puzzle_cache")));
public static Path LOGO_TEXTURE = Paths.get(CONFIG_PATH + "/mojangstudios.png");
public static Path BACKGROUND_TEXTURE = Paths.get(CONFIG_PATH + "/splash_background.png");
private static final MinecraftClient client = MinecraftClient.getInstance();
private static boolean keepBackground = false;
public static void init() {
if (!CONFIG_PATH.exists()) { // Run when config directory is nonexistent //
if (CONFIG_PATH.mkdir()) { // Create our custom config directory //
if (Util.getOperatingSystem().equals(Util.OperatingSystem.WINDOWS)) {
try { Files.setAttribute(CONFIG_PATH.toPath(), "dos:hidden", true);
} catch (IOException ignored) {}
}
}
}
}
public static class ReloadListener implements SynchronousResourceReloader {
public static final ReloadListener INSTANCE = new ReloadListener();
private ReloadListener() {}
@Override
public void reload(ResourceManager manager) {
if (PuzzleConfig.resourcepackSplashScreen) {
PuzzleSplashScreen.resetColors();
client.getTextureManager().registerTexture(LOGO, new LogoTexture(LOGO));
client.getTextureManager().registerTexture(BACKGROUND, new LogoTexture(BACKGROUND));
manager.findResources("optifine", path -> path.getPath().contains("color.properties")).forEach((id, resource) -> {
try (InputStream stream = resource.getInputStream()) {
Properties properties = new Properties();
properties.load(stream);
if (properties.get("screen.loading") != null) {
PuzzleConfig.backgroundColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading").toString()).getRGB();
PuzzleConfig.hasCustomSplashScreen = true;
}
if (properties.get("screen.loading.bar") != null) {
PuzzleConfig.progressBarBackgroundColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.bar").toString()).getRGB();
PuzzleConfig.hasCustomSplashScreen = true;
}
if (properties.get("screen.loading.progress") != null) {
PuzzleConfig.progressBarColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.progress").toString()).getRGB();
PuzzleConfig.hasCustomSplashScreen = true;
}
if (properties.get("screen.loading.outline") != null) {
PuzzleConfig.progressFrameColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.outline").toString()).getRGB();
PuzzleConfig.hasCustomSplashScreen = true;
}
if (properties.get("screen.loading.blend") != null) {
// Recommended blend: SRC_ALPHA ONE_MINUS_SRC_ALPHA ONE ZERO
PuzzleConfig.disableBlend = properties.get("screen.loading.blend").toString().equals("off");
PuzzleConfig.customBlendFunction = new ArrayList<>(Arrays.stream(properties.get("screen.loading.blend").toString().split(" ")).toList());
PuzzleConfig.hasCustomSplashScreen = true;
}
} catch (Exception e) {
LOGGER.error("Error occurred while loading color.properties {}", id.toString(), e);
}
});
AtomicInteger logoCount = new AtomicInteger();
manager.findResources("textures", path -> path.getPath().contains("mojangstudios.png")).forEach((id, resource) -> {
try (InputStream stream = resource.getInputStream()) {
Files.copy(stream, LOGO_TEXTURE, StandardCopyOption.REPLACE_EXISTING);
client.getTextureManager().registerTexture(LOGO, new DynamicLogoTexture());
if (logoCount.get() > 0) PuzzleConfig.hasCustomSplashScreen = true;
logoCount.getAndIncrement();
} catch (Exception e) {
LOGGER.error("Error occurred while loading custom minecraft logo {}", id.toString(), e);
}
});
manager.findResources(MOD_ID, path -> path.getPath().contains("splash_background.png")).forEach((id, resource) -> {
try (InputStream stream = resource.getInputStream()) {
Files.copy(stream, BACKGROUND_TEXTURE, StandardCopyOption.REPLACE_EXISTING);
InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.BACKGROUND_TEXTURE));
client.getTextureManager().registerTexture(BACKGROUND, new NativeImageBackedTexture(NativeImage.read(input)));
keepBackground = true;
PuzzleConfig.hasCustomSplashScreen = true;
} catch (Exception e) {
LOGGER.error("Error occurred while loading custom splash background {}", id.toString(), e);
}
});
if (!keepBackground) {
try {
Files.delete(BACKGROUND_TEXTURE);
} catch (Exception ignored) {}
}
keepBackground = false;
PuzzleConfig.write(MOD_ID);
}
}
}
public static void resetColors() {
PuzzleConfig.backgroundColor = 15675965;
PuzzleConfig.progressBarColor = 16777215;
PuzzleConfig.progressBarBackgroundColor = 15675965;
PuzzleConfig.progressFrameColor = 16777215;
PuzzleConfig.disableBlend = false;
PuzzleConfig.customBlendFunction = new ArrayList<>();
PuzzleConfig.hasCustomSplashScreen = false;
}
public static class LogoTexture extends ResourceTexture {
public LogoTexture(Identifier logo) { super(logo); }
protected TextureData loadTextureData(ResourceManager resourceManager) {
MinecraftClient minecraftClient = MinecraftClient.getInstance();
DefaultResourcePack defaultResourcePack = minecraftClient.getDefaultResourcePack();
try {
InputStream inputStream = Objects.requireNonNull(defaultResourcePack.open(ResourceType.CLIENT_RESOURCES, LOGO)).get();
TextureData var6;
try {
var6 = new TextureData(new TextureResourceMetadata(true, true), NativeImage.read(inputStream));
} finally {
if (inputStream != null) {
inputStream.close();
}
}
return var6;
} catch (IOException var18) {
return new TextureData(var18);
}
}
}
public static class DynamicLogoTexture extends ResourceTexture {
public DynamicLogoTexture() {
super(LOGO);
}
protected TextureData loadTextureData(ResourceManager resourceManager) {
try {
InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.LOGO_TEXTURE));
return new TextureData(new TextureResourceMetadata(true, true), NativeImage.read(input));
} catch (IOException e) {
LOGGER.error("Encountered an error during logo loading: ", e);
return TextureData.load(resourceManager, LOGO);
}
}
}
}

View File

@@ -1,15 +1,17 @@
package net.puzzlemc.splashscreen.mixin;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Overlay;
import net.minecraft.client.gui.screen.SplashOverlay;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.*;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.NativeImageBackedTexture;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import net.minecraft.util.math.ColorHelper;
import net.minecraft.util.math.MathHelper;
import net.puzzlemc.core.config.PuzzleConfig;
import net.puzzlemc.splashscreen.PuzzleSplashScreen;
@@ -25,90 +27,93 @@ import java.io.InputStream;
import java.nio.file.Files;
import java.util.function.IntSupplier;
import static net.puzzlemc.core.PuzzleCore.LOGGER;
import static net.puzzlemc.splashscreen.PuzzleSplashScreen.BACKGROUND;
@Mixin(value = SplashOverlay.class, priority = 2000)
public abstract class MixinSplashScreen extends Overlay {
@Shadow @Final static Identifier LOGO;
@Shadow @Final public static Identifier LOGO;
@Shadow private long reloadCompleteTime;
@Shadow @Final private MinecraftClient client;
@Shadow @Final private boolean reloading;
@Shadow private long reloadStartTime;
@Shadow
private static int withAlpha(int color, int alpha) {
return 0;
}
@Shadow @Final private MinecraftClient client;
@Shadow @Final private boolean reloading;
@Shadow private long reloadStartTime;
@Inject(method = "init(Lnet/minecraft/client/MinecraftClient;)V", at = @At("TAIL"))
private static void puzzle$initSplashscreen(MinecraftClient client, CallbackInfo ci) { // Load our custom textures at game start //
if (PuzzleConfig.resourcepackSplashScreen) {
if (PuzzleSplashScreen.LOGO_TEXTURE.toFile().exists()) {
try {
InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.LOGO_TEXTURE));
client.getTextureManager().registerTexture(LOGO, new NativeImageBackedTexture(NativeImage.read(input)));
} catch (IOException ignored) {
}
client.getTextureManager().registerTexture(LOGO, new PuzzleSplashScreen.DynamicLogoTexture());
}
if (PuzzleSplashScreen.BACKGROUND_TEXTURE.toFile().exists()) {
try {
InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.BACKGROUND_TEXTURE));
client.getTextureManager().registerTexture(PuzzleSplashScreen.BACKGROUND, new NativeImageBackedTexture(NativeImage.read(input)));
} catch (IOException ignored) {
}
client.getTextureManager().registerTexture(BACKGROUND, new NativeImageBackedTexture(NativeImage.read(input)));
} catch (IOException ignored) {}
}
}
}
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Ljava/util/function/IntSupplier;getAsInt()I"))
private int puzzle$modifyBackground(IntSupplier instance) { // Set the Progress Bar Frame Color to our configured value //
return (!PuzzleConfig.resourcepackSplashScreen || PuzzleConfig.progressBarBackgroundColor == 15675965) ? instance.getAsInt() : PuzzleConfig.backgroundColor | 255 << 24;
}
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/systems/RenderSystem;blendFunc(II)V", shift = At.Shift.AFTER), remap = false)
private void puzzle$betterBlend(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (PuzzleConfig.disableBlend) RenderSystem.defaultBlendFunc();
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/ColorHelper;getWhite(F)I", shift = At.Shift.AFTER))
private void puzzle$betterBlend(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (PuzzleConfig.resourcepackSplashScreen) {
if (PuzzleConfig.disableBlend) RenderSystem.disableBlend();
else if (PuzzleConfig.customBlendFunction.size() == 4) {
try {
RenderSystem.blendFuncSeparate(
GlStateManager.SrcFactor.valueOf(PuzzleConfig.customBlendFunction.get(0)),
GlStateManager.DstFactor.valueOf(PuzzleConfig.customBlendFunction.get(1)),
GlStateManager.SrcFactor.valueOf(PuzzleConfig.customBlendFunction.get(2)),
GlStateManager.DstFactor.valueOf(PuzzleConfig.customBlendFunction.get(3)));
} catch (Exception e) {
LOGGER.error("Incorrect blend function defined in color.properties: {}{}", PuzzleConfig.customBlendFunction, e.getMessage());
}
}
}
}
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/util/Window;getScaledWidth()I", shift = At.Shift.BEFORE))
private void puzzle$renderSplashBackground(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (Files.exists(PuzzleSplashScreen.BACKGROUND_TEXTURE)) {
@Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;getScaledWindowWidth()I", ordinal = 2))
private void puzzle$renderSplashBackground(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (Files.exists(PuzzleSplashScreen.BACKGROUND_TEXTURE) && PuzzleConfig.resourcepackSplashScreen) {
int width = client.getWindow().getScaledWidth();
int height = client.getWindow().getScaledHeight();
long l = Util.getMeasuringTimeMs();
float f = this.reloadCompleteTime > -1L ? (float)(l - this.reloadCompleteTime) / 1000.0F : -1.0F;
float g = this.reloadStartTime> -1L ? (float)(l - this.reloadStartTime) / 500.0F : -1.0F;
float s;
if (f >= 1.0F)
s = 1.0F - MathHelper.clamp(f - 1.0F, 0.0F, 1.0F);
else if (reloading)
s = MathHelper.clamp(g, 0.0F, 1.0F);
else
s = 1.0F;
RenderSystem.setShaderTexture(0, PuzzleSplashScreen.BACKGROUND);
if (f >= 1.0F) s = 1.0F - MathHelper.clamp(f - 1.0F, 0.0F, 1.0F);
else if (reloading) s = MathHelper.clamp(g, 0.0F, 1.0F);
else s = 1.0F;
RenderSystem.enableBlend();
RenderSystem.blendEquation(32774);
RenderSystem.defaultBlendFunc();
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, s);
drawTexture(matrices, 0, 0, 0, 0, 0, width, height, width, height);
context.drawTexture(RenderLayer::getGuiTextured, BACKGROUND, 0, 0, 0, 0, width, height, width, height, ColorHelper.getWhite(s));
RenderSystem.defaultBlendFunc();
RenderSystem.disableBlend();
}
}
@Inject(method = "renderProgressBar", at = @At("HEAD"))
private void puzzle$addProgressBarBackground(MatrixStack matrices, int minX, int minY, int maxX, int maxY, float opacity, CallbackInfo ci) {
RenderSystem.disableBlend();
private void puzzle$addProgressBarBackground(DrawContext context, int minX, int minY, int maxX, int maxY, float opacity, CallbackInfo ci) {
context.getMatrices().translate(0, 0, 1f);
if (!PuzzleConfig.resourcepackSplashScreen || PuzzleConfig.progressBarBackgroundColor == 15675965) return;
long l = Util.getMeasuringTimeMs();
float f = this.reloadCompleteTime > -1L ? (float)(l - this.reloadCompleteTime) / 1000.0F : -1.0F;
int m = MathHelper.ceil((1.0F - MathHelper.clamp(f - 1.0F, 0.0F, 1.0F)) * 255.0F);
fill(matrices, minX, minY, maxX, maxY, withAlpha(PuzzleConfig.progressBarBackgroundColor, m));
RenderSystem.disableBlend();
context.fill(minX, minY, maxX, maxY, withAlpha(PuzzleConfig.progressBarBackgroundColor, m));
}
@ModifyArg(method = "renderProgressBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/SplashOverlay;fill(Lnet/minecraft/client/util/math/MatrixStack;IIIII)V"), index = 5)
@ModifyArg(method = "renderProgressBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;fill(IIIII)V"), index = 4)
private int puzzle$modifyProgressFrame(int color) { // Set the Progress Bar Frame Color to our configured value //
return (!PuzzleConfig.resourcepackSplashScreen || PuzzleConfig.progressFrameColor == 16777215) ? color : PuzzleConfig.progressFrameColor | 255 << 24;
}
@ModifyArg(method = "renderProgressBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/screen/SplashOverlay;fill(Lnet/minecraft/client/util/math/MatrixStack;IIIII)V", ordinal = 0), index = 5)
@ModifyArg(method = "renderProgressBar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;fill(IIIII)V", ordinal = 0), index = 4)
private int puzzle$modifyProgressColor(int color) { // Set the Progress Bar Color to our configured value //
return (!PuzzleConfig.resourcepackSplashScreen || PuzzleConfig.progressBarColor == 16777215) ? color : PuzzleConfig.progressBarColor | 255 << 24;
}

View File

@@ -0,0 +1,3 @@
{
"accessWidener": "puzzle-models.accesswidener"
}

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,42 @@
{
"puzzle.text.update_available":"Даступна абнаўленне!",
"puzzle.screen.title":"Налады Puzzle",
"puzzle.page.graphics":"Графіка",
"puzzle.page.resources":"Рэсурсы",
"puzzle.page.performance":"Прадукцыйнасць",
"puzzle.page.misc":"Рознае",
"puzzle.option.check_for_updates":"Праверыць абнаўленні",
"puzzle.option.check_for_updates.tooltip":"Уключае ўбудаваны правершчык абнаўленняў",
"puzzle.option.show_version_info":"Паказваць версію Puzzle",
"puzzle.option.show_version_info.tooltip":"Паказваць інфармацыю пра бягучую\nверсію Puzzle и наяўнасць абнаўленняў на\nтытульным экране і меню F3",
"puzzle.option.resourcepack_splash_screen":"Выкарыстанне пакетаў рэсурсаў для сплэшэй",
"puzzle.option.resourcepack_splash_screen.tooltip":"Уключае пакеты рэсурсаў, якія змяняюць\nзагрузачныя экраны/сплэшы\nMinecraft, якія выкарыстоўваюць фармат OptiFine",
"puzzle.option.better_splash_screen_blend":"Палепшанае спалучэнне сплэшэй і лагатыпу",
"puzzle.option.better_splash_screen_blend.tooltip":"Змяняе тып спалучэння\nлагатыпу і сплэшэй\nкаб палепшыць працу з лагатыпамі карыстальніцкіх колераў",
"puzzle.option.unlimited_model_rotations":"Неабмежаванае вярчэнне мадэлі",
"puzzle.option.unlimited_model_rotations.tooltip":"Дазваляе вярчэнне на 360° на карыстальніцкіх мадэляў блокаў/прадметаў",
"puzzle.option.bigger_custom_models":"Павялічаныя карыстальніцкія мадэлі",
"puzzle.option.bigger_custom_models.tooltip":"Павялічвае ліміт памеру\nкарыстальніцкіх мадэляў блокаў/прадметаў\nз 3x3x3 да 5x5x5",
"puzzle.midnightconfig.title":"Пашыраныя налады Puzzle",
"puzzle.midnightconfig.category.gui":"GUI",
"puzzle.midnightconfig.category.features":"Асаблівасці",
"puzzle.midnightconfig.category.debug":"Debug",
"puzzle.midnightconfig.tooltip":"Налады толькі для вопытных карыстальнікаў",
"cullleaves.puzzle.option.enabled": "Адбракоўваць лісце",
"cullleaves.puzzle.option.enabled.tooltip": "Уключыць адбракоўванне лісця, каб павялічыць прадукцыйнасць",
"iris.puzzle.option.enableShaders": "Уключыць шэйдэры",
"iris.puzzle.option.enableShaders.tooltip": "Дазваляе уключаць ці выключаць шэйдэры",
"iris.puzzle.option.open": "АДКРЫЦЬ",
"options.iris.shaderPackSelection.tooltip": "Адкрывае экран выбару\nшэйдэраў і іх налад",
"lambdabettergrass.option.mode.tooltip": "Робіць бакі\nзямлі з дзёрнам злучанымі з\nверхам гэтага блоку",
"lambdabettergrass.option.better_snow.tooltip": "Дадае крыху бачны слой снег/імху\nна непоўныя блокі, якія\nакружаны снегам/імхом",
"config.dynamicfps.reduce_when_unfocused.tooltip": "Зніжае FPS у Minecraft калі ён не актыўны\n(то бок калі іншая прагракма адчынена ці гульня згорнута)\nкаб захаваць рэсурсы сістэмы",
"config.dynamicfps.unfocused_fps.tooltip": "Колькасць кадраў у секунду, калі\nMinecraft згорнуты",
"config.dynamicfps.restore_when_hovered.tooltip": "Дазваляе скасаваць ці не\nабмежаванне FPS, калі Minecraft актыны\n(то бок актыўны ці наведзены курсорам з панелі задач)",
"config.dynamicfps.run_gc_on_unfocus.tooltip": "Запусціць збіральнік смецця калі\nMinecraft неактыўны,\n каб ачысціць крыху АЗУ",
"config.dynamicfps.unfocused_volume.tooltip": "Гучнасць прайгравальных гукаў\nкалі гульня не актыўна\n(то бок іншае акно абрана)",
"config.dynamicfps.hidden_volume.tooltip": "Гучнасць прайгравальных гукаў\nкали гульня не бачна\n(то бок згорнута, знаходзіцца пад іншымі вокнамі\nці на ішай віртуальнай машыне)",
"entity_texture_features.puzzle.emissive_type.brighter": "§eЯрчэй",
"entity_texture_features.puzzle.emissive_type.default": "§6Стандартна"
}

View File

@@ -1,10 +1,10 @@
{
"puzzle.text.update_available":"Ein Update ist verfügbar!",
"puzzle.screen.title":"Puzzle Einstellungen",
"puzzle.page.graphics":"Grafik Einstellungen",
"puzzle.page.resources":"Resourcen Einstellungen",
"puzzle.page.performance":"Performance Einstellungen",
"puzzle.page.misc":"Sonstige Einstellungen",
"puzzle.page.graphics":"Grafik",
"puzzle.page.resources":"Resourcen",
"puzzle.page.performance":"Performance",
"puzzle.page.misc":"Sonstiges",
"puzzle.option.check_for_updates":"Auf Updates überprüfen",
"puzzle.option.show_version_info":"Zeige Informationen über Puzzle's Version",
"puzzle.option.resourcepack_splash_screen":"Nutze Resourcepack-Ladebildschirm",

View File

@@ -1,10 +1,10 @@
{
"puzzle.text.update_available":"Μια καινούρια έκδοση είναι διαθέσιμη!",
"puzzle.screen.title":"Ρυθμίσεις του Puzzle",
"puzzle.page.graphics":"Ρυθμίσεις Γραφικών",
"puzzle.page.resources":"Ρυθμίσεις Πόρων",
"puzzle.page.performance":"Ρυθμίσεις Απόδοσης",
"puzzle.page.misc":"Διάφορες Ρυθμίσεις",
"puzzle.page.graphics":"Γραφικών",
"puzzle.page.resources":"Πόρων",
"puzzle.page.performance":"Απόδοσης",
"puzzle.page.misc":"Διάφορες",
"puzzle.option.check_for_updates":"Έλεγχος για αναβαθμίσεις",
"puzzle.option.show_version_info":"Εμφάνηση έκδοσης του Puzzle",
"puzzle.option.resourcepack_splash_screen":"Οθόνη φόρτωσης πακέτου πόρων",

View File

@@ -1,10 +1,10 @@
{
"puzzle.text.update_available":"An update is available!",
"puzzle.screen.title":"Puzzle Settings",
"puzzle.page.graphics":"Graphics Settings",
"puzzle.page.resources":"Resource Settings",
"puzzle.page.performance":"Performance Settings",
"puzzle.page.misc":"Miscellaneous Settings",
"puzzle.page.graphics":"Graphics",
"puzzle.page.resources":"Resource",
"puzzle.page.performance":"Performance",
"puzzle.page.misc":"Miscellaneous",
"puzzle.option.check_for_updates":"Check for Updates",
"puzzle.option.check_for_updates.tooltip":"Enables Puzzle's built-in update checker",
"puzzle.option.show_version_info":"Show Puzzle version info",
@@ -18,6 +18,9 @@
"puzzle.option.bigger_custom_models":"Bigger Custom Models",
"puzzle.option.bigger_custom_models.tooltip":"Increases the limit of\ncustom block/item model sizes\nfrom 3x3x3 to 5x5x5",
"puzzle.midnightconfig.title":"Puzzle Advanced Config",
"puzzle.midnightconfig.category.gui":"GUI",
"puzzle.midnightconfig.category.features":"Features",
"puzzle.midnightconfig.category.internal":"Internal",
"puzzle.midnightconfig.tooltip":"Options for advanced users only",
"cullleaves.puzzle.option.enabled": "Cull Leaves",

View File

@@ -0,0 +1,42 @@
{
"puzzle.text.update_available":"¡Hay una actualización disponible!",
"puzzle.screen.title":"Configuración de Puzzle",
"puzzle.page.graphics":"Gráficos",
"puzzle.page.resources":"Recursos",
"puzzle.page.performance":"Rendimiento",
"puzzle.page.misc":"Variado",
"puzzle.option.check_for_updates":"Comprobar Actualizaciones",
"puzzle.option.check_for_updates.tooltip":"Activa el comprobador de actualizaciones integrado de Puzzle.",
"puzzle.option.show_version_info":"Mostrar información de la versión Puzzle",
"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.",
"puzzle.option.resourcepack_splash_screen":"Usar la Pantalla de Carga del Paquete de Recursos [*]",
"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.",
"puzzle.option.better_splash_screen_blend":"Mejor Mezcla del Logo de la Pantalla de Carga",
"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.",
"puzzle.option.unlimited_model_rotations":"Rotaciones Ilimitadas de Modelos",
"puzzle.option.unlimited_model_rotations.tooltip":"Desbloquea la rotación completa de 360° en los modelos de bloques/objetos personalizados.",
"puzzle.option.bigger_custom_models":"Modelos Personalizados más Grandes",
"puzzle.option.bigger_custom_models.tooltip":"Aumenta el límite de tamaños\nde los modelos de bloques/objetos personalizados\nde 3x3x3 a 5x5x5.",
"puzzle.midnightconfig.title":"Acceder a las Opciones adicionales de Puzzle para Expertos",
"puzzle.midnightconfig.category.gui":"Interfaz",
"puzzle.midnightconfig.category.features":"Características",
"puzzle.midnightconfig.category.debug":"Depuración",
"puzzle.midnightconfig.tooltip":"Ajustes para usuarios experimentados.",
"cullleaves.puzzle.option.enabled": "Reducir Cantidad de Hojas",
"cullleaves.puzzle.option.enabled.tooltip": "Permitir reducir la cantidad de hojas para mejorar el rendimiento.",
"iris.puzzle.option.enableShaders": "Activar Sombreadores",
"iris.puzzle.option.enableShaders.tooltip": "Activar o no los paquetes de sombreadores.",
"iris.puzzle.option.open": "ABRIR",
"options.iris.shaderPackSelection.tooltip": "Abre la pantalla de selección\nde los paquetes de sombreadores.",
"lambdabettergrass.option.mode.tooltip": "Hace que los lados de los bloques de\ncésped se conecten con los bloques de\ncésped adyacentes.",
"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.",
"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.",
"config.dynamicfps.unfocused_fps.tooltip": "La cantidad de fotogramas por segundo que\nMinecraft puede renderizar mientras se\nencuentra en segundo plano.",
"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).",
"config.dynamicfps.run_gc_on_unfocus.tooltip": "Ejecutar un recolector de basura mientras\nMinecraft se encuentra en segundo plano\npara liberar algo de RAM.",
"config.dynamicfps.unfocused_volume.tooltip": "El volumen del sonido del juego cuando permanece\nen segundo plano (es decir, cuando hay otra\nventana seleccionada).",
"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).",
"entity_texture_features.puzzle.emissive_type.brighter": "§eResplandeciente",
"entity_texture_features.puzzle.emissive_type.default": "§6Predeterminado"
}

View File

@@ -1,10 +1,10 @@
{
"puzzle.text.update_available":"Uuendus on saadaval!",
"puzzle.screen.title":"Puzzle sätted",
"puzzle.page.graphics":"Graafikasätted",
"puzzle.page.resources":"Ressursisätted",
"puzzle.page.performance":"Jõudlussätted",
"puzzle.page.misc":"Muud sätted",
"puzzle.page.graphics":"Graafika",
"puzzle.page.resources":"Ressursi",
"puzzle.page.performance":"Jõudlus",
"puzzle.page.misc":"Muud",
"puzzle.option.check_for_updates":"Uuenduste kontroll",
"puzzle.option.show_version_info":"Kuva Puzzle versiooniteavet",
"puzzle.option.resourcepack_splash_screen":"Kasuta ressursipaki laadimiskuva",

View File

@@ -1,10 +1,10 @@
{
"puzzle.text.update_available":"업데이트가 가능합니다!",
"puzzle.screen.title":"Puzzle 설정",
"puzzle.page.graphics":"그래픽 설정",
"puzzle.page.resources":"리소스 설정",
"puzzle.page.performance":"성능 설정",
"puzzle.page.misc":"기타 설정",
"puzzle.page.graphics":"그래픽",
"puzzle.page.resources":"리소스",
"puzzle.page.performance":"성능",
"puzzle.page.misc":"기타",
"puzzle.option.check_for_updates":"업데이트 확인",
"puzzle.option.show_version_info":"Puzzle 버전 정보 보기",
"puzzle.option.resourcepack_splash_screen":"스플래시 화면에서 리소스팩 사용",

View File

@@ -1,10 +1,10 @@
{
"puzzle.text.update_available":"Aktualizacja jest dostępna!",
"puzzle.screen.title":"Ustawienia Puzzle",
"puzzle.page.graphics":"Ustawienia grafiki",
"puzzle.page.resources":"Ustawienia zasobów",
"puzzle.page.performance":"Ustawienia wydajności",
"puzzle.page.misc":"Różne ustawienia",
"puzzle.page.graphics":"Grafiki",
"puzzle.page.resources":"Zasobów",
"puzzle.page.performance":"Wydajności",
"puzzle.page.misc":"Ustawienia",
"puzzle.option.check_for_updates":"Sprawdź aktualizacje",
"puzzle.option.show_version_info":"Pokaż informacje o wersji Puzzle",
"puzzle.option.resourcepack_splash_screen":"Użyj ekranu powitalnego paczek zasobów",

View File

@@ -0,0 +1,39 @@
{
"puzzle.text.update_available":"Uma atualização está disponível!",
"puzzle.screen.title":"Puzzle Definições",
"puzzle.page.graphics":"Gráficas",
"puzzle.page.resources":"Recursos",
"puzzle.page.performance":"Desempenho",
"puzzle.page.misc":"Diversas",
"puzzle.option.check_for_updates":"Verifique se há atualizações",
"puzzle.option.check_for_updates.tooltip":"Ativa o verificador de atualização integrado do Puzzle",
"puzzle.option.show_version_info":"Mostrar informações da versão do Puzzle",
"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",
"puzzle.option.resourcepack_splash_screen":"Use a tela inicial do pacote de recursos",
"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",
"puzzle.option.better_splash_screen_blend":"Melhor combinação do logotipo da tela inicial",
"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",
"puzzle.option.unlimited_model_rotations":"Rotações de modelo ilimitadas",
"puzzle.option.unlimited_model_rotations.tooltip":"Desbloqueia rotação total de 360° em modelos de itens/blocos personalizados",
"puzzle.option.bigger_custom_models":"Modelos personalizados maiores",
"puzzle.option.bigger_custom_models.tooltip":"Aumenta o limite de\ntamanhos de modelo de bloco/item personalizados\nde 3x3x3 a 5x5x5",
"puzzle.midnightconfig.title":"Configuração avançada do Puzzle",
"puzzle.midnightconfig.tooltip":"Opções apenas para usuários avançados",
"cullleaves.puzzle.option.enabled": "Abate de Folhas",
"cullleaves.puzzle.option.enabled.tooltip": "Ative o abate de folhas para melhorar o desempenho",
"iris.puzzle.option.enableShaders": "Ativar sombreadores",
"iris.puzzle.option.enableShaders.tooltip": "Habilitar ou não shaderpacks",
"iris.puzzle.option.open": "ABRIR",
"options.iris.shaderPackSelection.tooltip": "Abra uma tela para selecionar\nshaderpacks e configurá-los",
"lambdabettergrass.option.mode.tooltip": "Faz os lados de\nblocos de grama se conectam a\nblocos de grama adjacentes",
"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",
"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",
"config.dynamicfps.unfocused_fps.tooltip": "A quantidade de quadros por segundo\nMinecraft é permitido\nrenderizar enquanto estiver fora de foco",
"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)",
"config.dynamicfps.run_gc_on_unfocus.tooltip": "Execute um coletor de lixo enquanto\nMinecraft não está focado em\nliberar um pouco de RAM",
"config.dynamicfps.unfocused_volume.tooltip": "O volume que o jogo deve reproduzir\nsom enquanto desfocado\n(ou seja, outra janela é selecionada)",
"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)",
"entity_texture_features.puzzle.emissive_type.brighter": "§eMais brilhante",
"entity_texture_features.puzzle.emissive_type.default": "§6Padrão"
}

View File

@@ -0,0 +1,48 @@
{
"puzzle.text.update_available":"Доступно обновление!",
"puzzle.screen.title":"Настройки Puzzle",
"puzzle.page.graphics":"Графика",
"puzzle.page.resources":"Ресурсы",
"puzzle.page.performance":"Оптимизация",
"puzzle.page.misc":"Прочие",
"puzzle.option.check_for_updates":"Проверять обновления",
"puzzle.option.check_for_updates.tooltip":"Включить встроенную в Puzzle проверку обновлений",
"puzzle.option.show_version_info":"Показывать информацию о версии",
"puzzle.option.show_version_info.tooltip":"Отображать информацию о текущей версии\nPuzzle и наличии обновлений\nна главном экране и экране отладки",
"puzzle.option.resourcepack_splash_screen":"Пользовательский экран загрузки",
"puzzle.option.resourcepack_splash_screen.tooltip":"Разрешить наборам ресурсов изменять\nвнешний вид экрана загрузки Minecraft,\nиспользуя формат OptiFine",
"puzzle.option.better_splash_screen_blend":"Улучшенное смешивание логотипа",
"puzzle.option.better_splash_screen_blend.tooltip":"Изменить метод смешивания, используемый\nдля логотипа на экране загрузки,\nчтобы улучшить вид с изменёнными цветами",
"puzzle.option.unlimited_model_rotations":"Неограниченные повороты моделей",
"puzzle.option.unlimited_model_rotations.tooltip":"Разрешить поворот частей\nпользовательских моделей\nблоков/предметов на 360°",
"puzzle.option.bigger_custom_models":"Увеличенный размер моделей",
"puzzle.option.bigger_custom_models.tooltip":"Увеличить предельный размер\nпользовательских моделей блоков\nи предметов с 3×3×3 до 5×5×5",
"puzzle.midnightconfig.title":"Расширенные настройки Puzzle",
"puzzle.midnightconfig.category.gui":"Интерфейс",
"puzzle.midnightconfig.category.features":"Функционал",
"puzzle.midnightconfig.category.debug":"Отладка",
"puzzle.midnightconfig.tooltip":"Только для продвинутых пользователей!",
"cullleaves.puzzle.option.enabled": "Отбраковка листьев",
"cullleaves.puzzle.option.enabled.tooltip": "Включить отбраковку блоков листьев\nдля улучшения производительности",
"iris.puzzle.option.enableShaders": "Шейдеры",
"iris.puzzle.option.enableShaders.tooltip": "Включить выбранный набор шейдеров",
"iris.puzzle.option.open": "Выбрать ",
"options.iris.shaderPackSelection.tooltip": "Открыть экран переключения\nи настройки наборов шейдеров",
"lambdabettergrass.option.mode.tooltip": "Включить соединение текстуры\nтравы у соседних блоков дёрна",
"lambdabettergrass.option.better_snow.tooltip": "Добавить имитацию наличия слоя снега\nили мха для неполных блоков, имеющих\nсоответствующее окружение",
"config.dynamicfps.reduce_when_unfocused.tooltip": "Уменьшать FPS в Minecraft при переходе в фон\nдля экономии энергии и системных ресурсов\n(когда игра свёрнута или активно другое окно)",
"config.dynamicfps.unfocused_fps.tooltip": "Фактическое количество\nкадров в секунду, которое\nMinecraft сможет выводить\nв фоновом режиме",
"config.dynamicfps.restore_when_hovered.tooltip": "Отключать ограничение FPS,\nкогда на окно с Minecraft\nнаведён курсор мыши",
"config.dynamicfps.run_gc_on_unfocus.tooltip": "Запускать сборщик мусора при\nпереходе игры в фон, чтобы\nосвободить пространство в ОЗУ\n(уменьшает число просадок FPS)",
"config.dynamicfps.unfocused_volume.tooltip": "Громкость звука игры в состоянии фона\n(когда активно другое окно)",
"config.dynamicfps.hidden_volume.tooltip": "Громкость звука игры в скрытом состоянии\n(когда окно свёрнуто, закрыто другим окном\nили находится на другом рабочем столе)",
"entity_texture_features.puzzle.emissive_type.brighter": "§eЯркие",
"entity_texture_features.puzzle.emissive_type.default": "§6Обычные",
"modmenu.descriptionTranslation.puzzle": "Функции улучшения внешнего вида и производительности.",
"modmenu.descriptionTranslation.puzzle-base": "Общий код всех модулей Puzzle.",
"modmenu.descriptionTranslation.puzzle-gui": "Альтернативы Optifine, объединённые в едином меню.",
"modmenu.descriptionTranslation.puzzle-models": "Больше свободы моделям блоков и предметов!",
"modmenu.descriptionTranslation.puzzle-splashscreen": "Свой экран загрузки при помощи наборов ресурсов."
}

View File

@@ -0,0 +1,42 @@
{
"puzzle.text.update_available":"Đã có bản cập nhật!",
"puzzle.screen.title":"Cài đặt Puzzle",
"puzzle.page.graphics":"Đồ họa",
"puzzle.page.resources":"Tài nguyên",
"puzzle.page.performance":"Hiệu năng",
"puzzle.page.misc":"Khác",
"puzzle.option.check_for_updates":"Kiểm tra cập nhật",
"puzzle.option.check_for_updates.tooltip":"Bật trình kiểm tra cập nhật tích hợp của Puzzle",
"puzzle.option.show_version_info":"Hiển thị thông tin phiên bản Puzzle",
"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",
"puzzle.option.resourcepack_splash_screen":"Sử dụng màn hình đốm gói tài nguyên",
"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",
"puzzle.option.better_splash_screen_blend":"Logo màn hình đốm tốt hơn",
"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",
"puzzle.option.unlimited_model_rotations":"Xoay mô hình không giới hạn",
"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",
"puzzle.option.bigger_custom_models":"Mô hình tùy chỉnh lớn hơn",
"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",
"puzzle.midnightconfig.title":"Cấu hình Puzzle nâng cao",
"puzzle.midnightconfig.category.gui":"GUI",
"puzzle.midnightconfig.category.features":"Tính năng",
"puzzle.midnightconfig.category.debug":"Gỡ lỗi",
"puzzle.midnightconfig.tooltip":"Tùy chọn chỉ dành cho người dùng nâng cao",
"cullleaves.puzzle.option.enabled": "Loại bỏ Lá",
"cullleaves.puzzle.option.enabled.tooltip": "Bật tính năng loại bỏ lá để nâng cao hiệu suất",
"iris.puzzle.option.enableShaders": "Bật Shader",
"iris.puzzle.option.enableShaders.tooltip": "Bật shaderpack",
"iris.puzzle.option.open": "MỞ",
"options.iris.shaderPackSelection.tooltip": "Mở một màn hình để chọn\nshaderpack và định cấu hình chúng",
"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ề",
"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",
"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",
"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",
"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ụ)",
"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",
"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)",
"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)",
"entity_texture_features.puzzle.emissive_type.brighter": "§eSáng hơn",
"entity_texture_features.puzzle.emissive_type.default": "§6Mặc định"
}

View File

@@ -0,0 +1,39 @@
{
"puzzle.text.update_available": "有新版本可供升級!",
"puzzle.screen.title": "Puzzle 設定",
"puzzle.page.graphics": "顯示設定",
"puzzle.page.resources": "資源設定",
"puzzle.page.performance": "效能設定",
"puzzle.page.misc": "其他設定",
"puzzle.option.check_for_updates": "檢查更新",
"puzzle.option.check_for_updates.tooltip": "開啟 Puzzle 內建的更新檢查",
"puzzle.option.show_version_info": "顯示 Puzzle 版本信息",
"puzzle.option.show_version_info.tooltip": "在標題畫面和 F3 選單上\n顯示有關目前 Puzzle 版本和更新狀態的資訊",
"puzzle.option.resourcepack_splash_screen": "使用資源包載入畫面",
"puzzle.option.resourcepack_splash_screen.tooltip": "使資源包可以使用 OptiFine 格式\n更改 Minecraft 的載入畫面",
"puzzle.option.better_splash_screen_blend": "更好的載入畫面圖示混和",
"puzzle.option.better_splash_screen_blend.tooltip": "更改激活畫面上標誌的混合方式\n以便更好地與自訂顏色的標誌配合使用",
"puzzle.option.unlimited_model_rotations": "無限模型旋轉",
"puzzle.option.unlimited_model_rotations.tooltip": "在自訂方塊/物品模型上解鎖完整 360° 旋轉",
"puzzle.option.bigger_custom_models": "更大的自訂模型",
"puzzle.option.bigger_custom_models.tooltip": "增加將自訂方塊/物品模型大小\n從 3x3x3 增加到 5x5x5",
"puzzle.midnightconfig.title": "Puzzle 進階設定",
"puzzle.midnightconfig.tooltip": "給予進階使用者使用的選項",
"cullleaves.puzzle.option.enabled": "樹葉剔除",
"cullleaves.puzzle.option.enabled.tooltip": "開啟樹葉剔除以提升效能。",
"iris.puzzle.option.enableShaders": "開啟光影",
"iris.puzzle.option.enableShaders.tooltip": "開啟或關閉光影包",
"iris.puzzle.option.open": "開",
"options.iris.shaderPackSelection.tooltip": "開啟選擇畫面光影包和設定",
"lambdabettergrass.option.mode.tooltip": "讓草的側面連接相鄰的草塊",
"lambdabettergrass.option.better_snow.tooltip": "對雪塊/苔蘚方塊被包圍的不完整方塊\n增加視覺效果",
"config.dynamicfps.reduce_when_unfocused.tooltip": "當 Minecraft 失去焦點時限制 FPS\n如切換到其他視窗或是遊戲被隱藏\n以節省電源和系統資源",
"config.dynamicfps.unfocused_fps.tooltip": "當 Minecraft 失去焦點時允許的最大 FPS",
"config.dynamicfps.restore_when_hovered.tooltip": "開啟或關閉預覽 Mineceraft 時是否停止 FPS 限制\n如停留在工作列或 Dock",
"config.dynamicfps.run_gc_on_unfocus.tooltip": "當 Minecraft 失去焦點時執行垃圾清理\n以減少一些記憶體",
"config.dynamicfps.unfocused_volume.tooltip": "當 Minecraft 失去焦點時撥放的音量\n如選擇了另一個視窗",
"config.dynamicfps.hidden_volume.tooltip": "遊戲在不可見時應該播放的音量\n如最小化、被其他視窗覆蓋或在另一個虛擬桌面上",
"entity_texture_features.puzzle.emissive_type.brighter": "§e更亮",
"entity_texture_features.puzzle.emissive_type.default": "§6預設"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 B

View File

@@ -3,8 +3,7 @@
"package": "net.puzzlemc.gui.mixin",
"compatibilityLevel": "JAVA_17",
"client": [
"MixinOptionsScreen",
"CemConfigAccessor"
"MixinOptionsScreen"
],
"injectors": {
"defaultRequire": 1

107
fabric/build.gradle Normal file
View File

@@ -0,0 +1,107 @@
plugins {
id 'com.github.johnrengelman.shadow'
id "me.shedaniel.unified-publishing"
}
repositories {
maven { url "https://maven.terraformersmc.com/releases" }
}
architectury {
platformSetupLoomIde()
fabric()
}
configurations {
common
shadowCommon // Don't use shadow from the shadow plugin since it *excludes* files.
compileClasspath.extendsFrom common
runtimeClasspath.extendsFrom common
developmentFabric.extendsFrom common
archivesBaseName = rootProject.archives_base_name + "-fabric"
version = rootProject.mod_version + "+" + rootProject.minecraft_version
}
dependencies {
modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}"
modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}"
modImplementation include ("maven.modrinth:midnightlib:${rootProject.midnightlib_version}-fabric")
modImplementation ("com.terraformersmc:modmenu:${project.modmenu_version}") {
exclude(group: "net.fabricmc.fabric-api")
}
common(project(path: ":common", configuration: "namedElements")) { transitive false }
shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false }
}
processResources {
inputs.property "version", rootProject.version
filesMatching("fabric.mod.json") {
expand "version": rootProject.version
}
}
shadowJar {
exclude "architectury.common.json"
configurations = [project.configurations.shadowCommon]
archiveClassifier = "dev-shadow"
}
remapJar {
input.set shadowJar.archiveFile
dependsOn shadowJar
}
sourcesJar {
def commonSources = project(":common").sourcesJar
dependsOn commonSources
from commonSources.archiveFile.map { zipTree(it) }
}
components.java {
withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) {
skip()
}
}
unifiedPublishing {
project {
displayName = "Puzzle $rootProject.version - Fabric $project.minecraft_version"
releaseType = "$project.release_type"
changelog = releaseChangelog()
gameVersions = []
gameLoaders = ["fabric","quilt"]
mainPublication remapJar
relations {
depends {
curseforge = "fabric-api"
modrinth = "fabric-api"
}
includes {
curseforge = "midnightlib"
modrinth = "midnightlib"
}
}
var CURSEFORGE_TOKEN = project.findProperty("CURSEFORGE_TOKEN") ?: System.getenv("CURSEFORGE_TOKEN")
if (CURSEFORGE_TOKEN != null) {
curseforge {
token = CURSEFORGE_TOKEN
id = rootProject.curseforge_id
gameVersions.addAll "Java 21", project.minecraft_version, project.supported_versions
}
}
var MODRINTH_TOKEN = project.findProperty("MODRINTH_TOKEN") ?: System.getenv("MODRINTH_TOKEN")
if (MODRINTH_TOKEN != null) {
modrinth {
token = MODRINTH_TOKEN
id = rootProject.modrinth_id
version = "$rootProject.version-$project.name"
gameVersions.addAll project.minecraft_version, project.supported_versions
}
}
}
}

View File

@@ -0,0 +1,28 @@
package net.puzzlemc.fabric;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;
import net.puzzlemc.core.PuzzleCore;
import net.puzzlemc.splashscreen.PuzzleSplashScreen;
public class PuzzleFabric implements ClientModInitializer {
@Override
public void onInitializeClient() {
PuzzleCore.initModules();
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() {
@Override
public Identifier getFabricId() {
return Identifier.of("puzzle", "splash_screen");
}
@Override
public void reload(ResourceManager manager) {
PuzzleSplashScreen.ReloadListener.INSTANCE.reload(manager);
}
});
}
}

View File

@@ -0,0 +1,12 @@
package net.puzzlemc.fabric.modmenu;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import net.puzzlemc.gui.screen.PuzzleOptionsScreen;
public class ModMenuIntegration implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return PuzzleOptionsScreen::new;
}
}

View File

@@ -1,9 +1,9 @@
{
"schemaVersion": 1,
"id": "puzzle-gui",
"id": "puzzle",
"version": "${version}",
"name": "Puzzle GUI",
"name": "Puzzle",
"description": "Unites optifine replacement mods in a clean & vanilla-style gui",
"authors": [
"PuzzleMC",
@@ -19,30 +19,24 @@
"icon": "assets/puzzle/icon.png",
"environment": "client",
"entrypoints": {
"client": [
"net.puzzlemc.gui.PuzzleClient"
"net.puzzlemc.fabric.PuzzleFabric"
],
"modmenu": [
"net.puzzlemc.gui.config.ModMenuIntegration"
"net.puzzlemc.fabric.modmenu.ModMenuIntegration"
]
},
"custom": {
"modmenu": {
"parent": "puzzle"
}
},
"mixins": [
"puzzle-gui.mixins.json"
"puzzle-gui.mixins.json",
"puzzle-models.mixins.json",
"puzzle-splashscreen.mixins.json"
],
"depends": {
"fabric": "*",
"midnightlib": "*"
},
"breaks": {
"citresewn": "<=1.0.0+1.18.2",
"entity_texture_features": "<3.0.0"
"minecraft": ">=1.21"
}
}

View File

@@ -1,35 +1,47 @@
# Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx4G
org.gradle.jvmargs=-Xmx2G
# Fabric Properties
# check these on https://fabricmc.net/use
minecraft_version=1.19
yarn_mappings=1.19+build.4
loader_version=0.14.8
minecraft_version=1.21.3
supported_versions=1.21.2
yarn_mappings=1.21.3+build.2
enabled_platforms=fabric,neoforge
# Mod Properties
mod_version = 1.4.0-1.19
maven_group = net.puzzlemc
archives_base_name = puzzle
mod_version = 2.0.3
maven_group = net.puzzlemc
archives_base_name = puzzle
release_type=release
curseforge_id=563977
modrinth_id=3IuO68q1
# Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_version=0.57.0+1.19
mod_menu_version = 4.0.0
cull_leaves_version = 2.3.3
ldl_version = 2.1.2+1.19
lbg_version = 1.3.0+1.19
iris_version = 1.19.x-v1.2.5
continuity_version = 2.0.0+1.19
animatica_version = 0.5+1.19
colormatic_version = 3.1.2
borderless_mining_version = 1.1.5+1.19
dynamic_fps_version = 2.2.0
toml4j_version = 0.7.2
cit_resewn_version = 1.1.1+1.19
cem_version = 0.7.1-1.19
complete_config_version = 1.0.0
spruceui_version=4.0.0+1.19
midnightlib_version=0.5.2
entitytexturefeatures_version=4.0.1.fabric
# Modloaders
fabric_loader_version=0.16.9
fabric_api_version=0.107.0+1.21.3
neoforge_version=21.3.11-beta
yarn_mappings_patch_neoforge_version = 1.21+build.4
# Libraries
midnightlib_version = 1.6.4
modmenu_version = 12.0.0-beta.1
# Mod Integrations
cull_leaves_version = 3.0.2-fabric
ldl_version = 2.3.2+1.20.1
lbg_version = 1.5.2+1.20.1
iris_version = 1.8.0-beta.3+1.21-fabric
continuity_version = 3.0.0-beta.5+1.21
animatica_version = 0.6.1+1.21
colormatic_version = 3.1.2
borderless_mining_version = 1.1.8+1.20.1
dynamic_fps_version = 3.6.3
toml4j_version = 0.7.2
cit_resewn_version = 1.1.3+1.20
complete_config_version = 2.3.0
spruceui_version=5.0.0+1.20
emf_version=2.2.3
etf_version=6.2.2
exordium_version=1.2.1-1.20.2
# Required for LBG
quilt_loader_version=0.19.0-beta.18
quilt_fabric_api_version=7.0.1+0.83.0-1.20

View File

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

113
neoforge/build.gradle Normal file
View File

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

View File

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

View File

@@ -0,0 +1,30 @@
package net.puzzlemc.neoforge;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.ModList;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent;
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
import net.puzzlemc.core.PuzzleCore;
import net.puzzlemc.gui.screen.PuzzleOptionsScreen;
import net.puzzlemc.splashscreen.PuzzleSplashScreen;
import static net.puzzlemc.core.PuzzleCore.MOD_ID;
@Mod(value = MOD_ID, dist = Dist.CLIENT)
public class PuzzleNeoForge {
public PuzzleNeoForge() {
PuzzleCore.initModules();
ModList.get().getModContainerById(MOD_ID).orElseThrow().registerExtensionPoint(IConfigScreenFactory.class, (client, parent) -> new PuzzleOptionsScreen(parent));
}
@EventBusSubscriber(modid = MOD_ID, bus = EventBusSubscriber.Bus.MOD, value = Dist.CLIENT)
public static class MidnightLibBusEvents {
@SubscribeEvent
public static void onResourceReload(RegisterClientReloadListenersEvent event) {
event.registerReloadListener(PuzzleSplashScreen.ReloadListener.INSTANCE);
}
}
}

View File

@@ -0,0 +1,30 @@
package net.puzzlemc.neoforge.mixin.splashscreen;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.SplashOverlay;
import net.minecraft.resource.ResourceReload;
import net.neoforged.neoforge.client.loading.NeoForgeLoadingOverlay;
import net.puzzlemc.core.config.PuzzleConfig;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Optional;
import java.util.function.Consumer;
@Mixin(NeoForgeLoadingOverlay.class)
public class MixinNeoForgeLoadingOverlay extends SplashOverlay {
public MixinNeoForgeLoadingOverlay(MinecraftClient client, ResourceReload monitor, Consumer<Optional<Throwable>> exceptionHandler, boolean reloading) {
super(client, monitor, exceptionHandler, reloading);
}
@Inject(method = "render", at = @At("HEAD"), cancellable = true) // Replaces the NeoForge loading screen in later stages with the (customized) vanilla version
private void redirectNeoForgeLoading(DrawContext context, int mouseX, int mouseY, float tickDelta, CallbackInfo ci) {
if (PuzzleConfig.resourcepackSplashScreen && PuzzleConfig.hasCustomSplashScreen) {
super.render(context, mouseX, mouseY, tickDelta);
ci.cancel();
}
}
}

View File

@@ -0,0 +1,37 @@
modLoader = "javafml"
loaderVersion = "[2,)"
#issueTrackerURL = ""
license = "MIT License"
[[mods]]
modId = "puzzle"
version = "${version}"
displayName = "Puzzle"
logoFile = "puzzle.png"
authors = "PuzzleMC, Motschen"
description = '''
Unites optifine replacement mods in a clean & vanilla-style gui
'''
[[mixins]]
config = "puzzle-gui.mixins.json"
[[mixins]]
config = "puzzle-models.mixins.json"
[[mixins]]
config = "puzzle-splashscreen.mixins.json"
[[mixins]]
config = "puzzle-splashscreen_neoforge.mixins.json"
[[dependencies.puzzle]]
modId = "neoforge"
mandatory = true
versionRange = "[21.0,)"
ordering = "NONE"
side = "CLIENT"
[[dependencies.puzzle]]
modId = "minecraft"
mandatory = true
versionRange = "[1.21,)"
ordering = "NONE"
side = "CLIENT"

View File

@@ -1,10 +1,9 @@
{
"required": true,
"package": "net.puzzlemc.core.mixin",
"package": "net.puzzlemc.neoforge.mixin",
"compatibilityLevel": "JAVA_17",
"client": [
"MixinTitleScreen",
"MixinDebugHud"
"splashscreen.MixinNeoForgeLoadingOverlay"
],
"injectors": {
"defaultRequire": 1

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,9 +0,0 @@
archivesBaseName = "puzzle-base"
repositories {
maven {
url = "https://api.modrinth.com/maven"
}
}
dependencies {
modImplementation "maven.modrinth:midnightlib:${project.midnightlib_version}"
}

View File

@@ -1,23 +0,0 @@
package net.puzzlemc.core;
import net.fabricmc.loader.api.FabricLoader;
import net.puzzlemc.core.config.PuzzleConfig;
import net.puzzlemc.core.util.UpdateChecker;
import net.fabricmc.api.ClientModInitializer;
public class PuzzleCore implements ClientModInitializer {
public final static String version = "Puzzle "+ (FabricLoader.getInstance().getModContainer("puzzle").isPresent() ? FabricLoader.getInstance().getModContainer("puzzle").get().getMetadata().getVersion() : "Test");
public final static String name = "Puzzle";
public final static String id = "puzzle";
public final static String website = "https://github.com/PuzzleMC/Puzzle";
public final static String updateURL = "https://modrinth.com/mod/puzzle";
public final static String UPDATE_CHECKER_URL = "https://raw.githubusercontent.com/PuzzleMC/Puzzle-Versions/main/puzzle_versions.json";
@Override
public void onInitializeClient() {
PuzzleConfig.init(id, PuzzleConfig.class);
if (PuzzleConfig.checkUpdates) UpdateChecker.init();
}
}

View File

@@ -1,24 +0,0 @@
package net.puzzlemc.core.config;
import eu.midnightdust.lib.config.MidnightConfig;
import java.util.ArrayList;
import java.util.List;
public class PuzzleConfig extends MidnightConfig {
@Entry public static List<String> disabledIntegrations = new ArrayList<>();
@Entry public static boolean enablePuzzleButton = true;
@Entry public static boolean debugMessages = false;
@Entry public static boolean checkUpdates = true;
@Entry public static boolean showPuzzleInfo = true;
@Entry public static boolean resourcepackSplashScreen = true;
@Entry public static boolean unlimitedRotations = true;
@Entry public static boolean biggerModels = true;
@Entry public static int backgroundColor = 15675965;
@Entry public static int progressBarColor = 16777215;
@Entry public static int progressBarBackgroundColor = 15675965;
@Entry public static int progressFrameColor = 16777215;
@Entry public static boolean disableBlend = false;
}

View File

@@ -1,38 +0,0 @@
package net.puzzlemc.core.mixin;
import com.mojang.blaze3d.platform.GlDebugInfo;
import net.puzzlemc.core.PuzzleCore;
import net.puzzlemc.core.config.PuzzleConfig;
import net.puzzlemc.core.util.UpdateChecker;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.hud.DebugHud;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.List;
@Mixin(DebugHud.class)
public abstract class MixinDebugHud extends DrawableHelper {
@Inject(at = @At("RETURN"), method = "getRightText")
private void puzzle$getRightText(CallbackInfoReturnable<List<String>> cir) {
if (PuzzleConfig.showPuzzleInfo) {
List<String> entries = cir.getReturnValue();
String message;
if (UpdateChecker.isUpToDate) {
message = "Puzzle is up to date (" + PuzzleCore.version + ")";
} else {
message = "Puzzle is outdated (" + PuzzleCore.version + " -> " + UpdateChecker.latestVersion + ")";
}
for (int i = 0; i < entries.size(); i++) {
String str = entries.get(i);
if (str.startsWith(GlDebugInfo.getVersion())) {
entries.add(i + 1, message);
break;
}
}
}
}
}

View File

@@ -1,78 +0,0 @@
package net.puzzlemc.core.mixin;
import net.fabricmc.loader.api.FabricLoader;
import net.puzzlemc.core.PuzzleCore;
import net.puzzlemc.core.config.PuzzleConfig;
import net.puzzlemc.core.util.UpdateChecker;
import net.minecraft.client.gui.screen.*;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
import net.minecraft.util.Util;
import net.minecraft.util.math.MathHelper;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import java.util.Objects;
@Mixin(TitleScreen.class)
public abstract class MixinTitleScreen extends Screen {
@Shadow @Final private boolean doBackgroundFade;
@Shadow private long backgroundFadeStart;
private Text puzzleText;
private int puzzleTextWidth;
private int yOffset;
protected MixinTitleScreen(Text title) {
super(title);
}
@Inject(at = @At("TAIL"), method = "init")
private void puzzle$init(CallbackInfo ci) {
yOffset = 20;
if (FabricLoader.getInstance().isModLoaded("dashloader")) yOffset = yOffset + 10;
if (UpdateChecker.isUpToDate) {
puzzleText = Text.of(PuzzleCore.version);
}
else {
puzzleText = Text.translatable("").append(Text.of(PuzzleCore.version + " | ")).append(Text.translatable("puzzle.text.update_available"));
this.puzzleTextWidth = this.textRenderer.getWidth(puzzleText);
}
}
@Inject(at = @At("TAIL"), method = "render")
private void puzzle$render(MatrixStack matrices, int mouseX, int mouseY, float delta, CallbackInfo ci) {
if (PuzzleConfig.showPuzzleInfo) {
float f = this.doBackgroundFade ? (float) (Util.getMeasuringTimeMs() - this.backgroundFadeStart) / 1000.0F : 1.0F;
float g = this.doBackgroundFade ? MathHelper.clamp(f - 1.0F, 0.0F, 1.0F) : 1.0F;
int l = MathHelper.ceil(g * 255.0F) << 24;
textRenderer.drawWithShadow(matrices, puzzleText,2,this.height - yOffset, 16777215 | l);
if (mouseX > 2 && mouseX < 2 + this.puzzleTextWidth && mouseY > this.height - yOffset && mouseY < this.height - yOffset + 10) {
fill(matrices, 2, this.height - yOffset + 9, 2 + this.puzzleTextWidth, this.height - yOffset + 10, 16777215 | l);
}
}
}
private void confirmLink(boolean open) {
if (open) {
Util.getOperatingSystem().open(PuzzleCore.updateURL);
}
Objects.requireNonNull(this.client).setScreen(this);
}
@Inject(at = @At("HEAD"), method = "mouseClicked",cancellable = true)
private void puzzle$mouseClicked(double mouseX, double mouseY, int button, CallbackInfoReturnable<Boolean> cir) {
if (mouseX > 2 && mouseX < (double)(2 + this.puzzleTextWidth) && mouseY > (double)(this.height - yOffset) && mouseY < (double)this.height - yOffset + 10) {
if (Objects.requireNonNull(this.client).options.getChatLinksPrompt().getValue()) {
this.client.setScreen(new ConfirmChatLinkScreen(this::confirmLink, PuzzleCore.updateURL, true));
} else {
Util.getOperatingSystem().open(PuzzleCore.updateURL);
}
cir.setReturnValue(false);
}
}
}

View File

@@ -1,54 +0,0 @@
package net.puzzlemc.core.util;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import net.puzzlemc.core.PuzzleCore;
import net.minecraft.client.MinecraftClient;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.concurrent.CompletableFuture;
public class UpdateChecker {
private static final Gson GSON = new Gson();
private static final String minecraftVersion = MinecraftClient.getInstance().getGame().getVersion().getId();
public static final Logger logger = LogManager.getLogger(PuzzleCore.name);
public static final Type UPDATE_TYPE_TOKEN = new TypeToken<Map<String, String>>(){}.getType();
public static String latestVersion;
public static boolean isUpToDate = true;
public static void init() {
CompletableFuture.supplyAsync(() -> {
try (Reader reader = new InputStreamReader(new URL(PuzzleCore.UPDATE_CHECKER_URL).openStream())) {
return GSON.<Map<String, String>>fromJson(reader, UPDATE_TYPE_TOKEN);
} catch (MalformedURLException error) {
logger.log(Level.ERROR, "Unable to check for updates because of connection problems: " + error.getMessage());
} catch (IOException error) {
logger.log(Level.ERROR, "Unable to check for updates because of an I/O Exception: " + error.getMessage());
}
return null;
}).thenAcceptAsync(versionMap -> {
if (versionMap != null && versionMap.containsKey(minecraftVersion)) {
latestVersion = versionMap.get(minecraftVersion);
if (!latestVersion.equals(PuzzleCore.version)) {
isUpToDate = false;
logger.log(Level.INFO, "There is a newer version of "+ PuzzleCore.name +" available: " + latestVersion);
logger.log(Level.INFO, "Please update immediately!");
}
} else {
logger.log(Level.WARN, "A problem with the database occurred, could not check for updates.");
}
}, MinecraftClient.getInstance());
}
}

View File

@@ -1,40 +0,0 @@
{
"schemaVersion": 1,
"id": "puzzle-base",
"version": "${version}",
"name": "Puzzle Base",
"description": "Shared code between all Puzzle modules",
"authors": [
"PuzzleMC",
"Motschen"
],
"contact": {
"homepage": "https://www.midnightdust.eu/",
"sources": "https://github.com/TeamMidnightDust/Puzzle",
"issues": "https://github.com/TeamMidnightDust/Puzzle/issues"
},
"license": "MIT",
"icon": "assets/puzzle/icon.png",
"environment": "client",
"entrypoints": {
"client": [
"net.puzzlemc.core.PuzzleCore"
]
},
"custom": {
"modmenu": {
"parent": "puzzle"
}
},
"mixins": [
"puzzle-base.mixins.json"
],
"depends": {
"fabric": "*"
}
}

View File

@@ -1,59 +0,0 @@
archivesBaseName = "puzzle-gui"
repositories {
maven { url "https://maven.terraformersmc.com/releases" }
maven {
name = 'AperLambda'
url = 'https://aperlambda.github.io/maven'
}
mavenCentral()
maven {
name 'Gegy'
url 'https://maven.gegy.dev'
}
maven {
url = "https://api.modrinth.com/maven"
}
maven {
url "https://www.cursemaven.com"
content {
includeGroup "curse.maven"
}
}
maven {
name = 'JitPack'
url 'https://jitpack.io'
}
maven {
url "https://maven.shedaniel.me/"
}
}
dependencies {
api project(":puzzle-base")
api project(":puzzle-splashscreen")
modImplementation "dev.lambdaurora:spruceui:${project.spruceui_version}"
modImplementation "maven.modrinth:midnightlib:${project.midnightlib_version}"
modImplementation ("com.terraformersmc:modmenu:${project.mod_menu_version}")
modImplementation ("maven.modrinth:cull-leaves:${project.cull_leaves_version}")
modImplementation ("maven.modrinth:lambdynamiclights:${project.ldl_version}")
modImplementation ("maven.modrinth:lambdabettergrass:${project.lbg_version}")
modImplementation ("maven.modrinth:iris:${project.iris_version}")
modImplementation ("maven.modrinth:cit-resewn:${project.cit_resewn_version}")
modImplementation ("maven.modrinth:colormatic:${project.colormatic_version}")
modImplementation ("maven.modrinth:borderless-mining:${project.borderless_mining_version}")
modImplementation ("maven.modrinth:dynamic-fps:${project.dynamic_fps_version}")
modImplementation ("maven.modrinth:entitytexturefeatures:${project.entitytexturefeatures_version}")
modImplementation ("maven.modrinth:cem:${project.cem_version}")
modImplementation "com.gitlab.Lortseam:completeconfig:${project.complete_config_version}"
modImplementation("org.aperlambda:lambdajcommon:1.8.1") {
exclude group: 'com.google.code.gson'
exclude group: 'com.google.guava'
}
modImplementation ("maven.modrinth:continuity:${project.continuity_version}") {
exclude module: "modmenu"
}
}

View File

@@ -1,27 +0,0 @@
package net.puzzlemc.gui;
import eu.midnightdust.lib.util.MidnightColorUtil;
import net.fabricmc.loader.api.FabricLoader;
import net.irisshaders.iris.api.v0.IrisApi;
import net.irisshaders.iris.api.v0.IrisApiConfig;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Style;
import net.minecraft.text.Text;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
public class IrisCompat {
public static void init() {
if (FabricLoader.getInstance().isModLoaded("iris")) {
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.of("Iris")));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("iris.puzzle.option.enableShaders"), (button) -> button.setMessage(IrisApi.getInstance().getConfig().areShadersEnabled() ? PuzzleClient.YES : PuzzleClient.NO), (button) -> {
IrisApiConfig irisConfig = IrisApi.getInstance().getConfig();
irisConfig.setShadersEnabledAndApply(!irisConfig.areShadersEnabled());
}));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("options.iris.shaderPackSelection.title"), (button) -> button.setMessage(Text.literal("").append(Text.translatable("iris.puzzle.option.open").setStyle(Style.EMPTY.withColor(MidnightColorUtil.radialRainbow(0.5f, 1).getRGB())))), (button) -> {
MinecraftClient client = MinecraftClient.getInstance();
client.setScreen((Screen) IrisApi.getInstance().openMainIrisScreenObj(client.currentScreen));
}));
}
}
}

View File

@@ -1,309 +0,0 @@
package net.puzzlemc.gui;
import dev.lambdaurora.lambdabettergrass.LBGConfig;
import dev.lambdaurora.lambdabettergrass.LambdaBetterGrass;
import dev.lambdaurora.lambdynlights.DynamicLightsConfig;
import dev.lambdaurora.lambdynlights.LambDynLights;
import dynamicfps.DynamicFPSConfig;
import dynamicfps.DynamicFPSMod;
import eu.midnightdust.core.MidnightLibClient;
import eu.midnightdust.cullleaves.config.CullLeavesConfig;
import io.github.kvverti.colormatic.Colormatic;
import io.github.kvverti.colormatic.ColormaticConfigController;
import link.infra.borderlessmining.config.ConfigHandler;
import me.pepperbell.continuity.client.config.ContinuityConfig;
import me.pepperbell.continuity.client.config.Option;
import net.dorianpb.cem.internal.config.CemConfig;
import net.dorianpb.cem.internal.config.CemConfigFairy;
import net.dorianpb.cem.internal.config.CemOptions;
import net.puzzlemc.core.config.PuzzleConfig;
import net.puzzlemc.gui.mixin.CemConfigAccessor;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.puzzlemc.splashscreen.PuzzleSplashScreen;
import shcm.shsupercm.fabric.citresewn.config.CITResewnConfig;
import traben.entity_texture_features.ETFApi;
import traben.entity_texture_features.config.ETFConfig;
import io.github.kvverti.colormatic.ColormaticConfig;
public class PuzzleClient implements ClientModInitializer {
public final static String id = "puzzle";
public static final Text YES = Text.translatable("gui.yes").formatted(Formatting.GREEN);
public static final Text NO = Text.translatable("gui.no").formatted(Formatting.RED);
@Override
public void onInitializeClient() {
MidnightLibClient.hiddenMods.add("puzzle");
MinecraftClient client = MinecraftClient.getInstance();
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.of("Puzzle")));
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.translatable("puzzle.option.check_for_updates"), (button) -> button.setMessage(PuzzleConfig.checkUpdates ? YES : NO), (button) -> {
PuzzleConfig.checkUpdates = !PuzzleConfig.checkUpdates;
PuzzleConfig.write(id);
}));
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.translatable("puzzle.option.show_version_info"), (button) -> button.setMessage(PuzzleConfig.showPuzzleInfo ? YES : NO), (button) -> {
PuzzleConfig.showPuzzleInfo = !PuzzleConfig.showPuzzleInfo;
PuzzleConfig.write(id);
}));
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.translatable("puzzle.midnightconfig.title"), (button) -> button.setMessage(Text.of("OPEN")), (button) -> {
client.setScreen(PuzzleConfig.getScreen(client.currentScreen, "puzzle"));
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("Puzzle")));
if (FabricLoader.getInstance().isModLoaded("puzzle-splashscreen") && !PuzzleConfig.disabledIntegrations.contains("puzzle-splashscreen")) {
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("puzzle.option.resourcepack_splash_screen"), (button) -> button.setMessage(PuzzleConfig.resourcepackSplashScreen ? YES : NO), (button) -> {
PuzzleConfig.resourcepackSplashScreen = !PuzzleConfig.resourcepackSplashScreen;
PuzzleConfig.write(id);
PuzzleSplashScreen.resetColors();
MinecraftClient.getInstance().getTextureManager().registerTexture(PuzzleSplashScreen.LOGO, new PuzzleSplashScreen.LogoTexture(PuzzleSplashScreen.LOGO));
}));
}
if (FabricLoader.getInstance().isModLoaded("puzzle-models") && !PuzzleConfig.disabledIntegrations.contains("puzzle-models")) {
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("puzzle.option.unlimited_model_rotations"), (button) -> button.setMessage(PuzzleConfig.unlimitedRotations ? YES : NO), (button) -> {
PuzzleConfig.unlimitedRotations = !PuzzleConfig.unlimitedRotations;
PuzzleConfig.write(id);
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("puzzle.option.bigger_custom_models"), (button) -> button.setMessage(PuzzleConfig.biggerModels ? YES : NO), (button) -> {
PuzzleConfig.biggerModels = !PuzzleConfig.biggerModels;
PuzzleConfig.write(id);
}));
}
if (FabricLoader.getInstance().isModLoaded("cullleaves") && !PuzzleConfig.disabledIntegrations.contains("cullleaves")) {
PuzzleApi.addToPerformanceOptions(new PuzzleWidget(Text.of("CullLeaves")));
PuzzleApi.addToPerformanceOptions(new PuzzleWidget(Text.translatable("cullleaves.puzzle.option.enabled"), (button) -> button.setMessage(CullLeavesConfig.enabled ? YES : NO), (button) -> {
CullLeavesConfig.enabled = !CullLeavesConfig.enabled;
CullLeavesConfig.write("cullleaves");
MinecraftClient.getInstance().worldRenderer.reload();
}));
}
if (FabricLoader.getInstance().isModLoaded("colormatic") && !PuzzleConfig.disabledIntegrations.contains("colormatic")) {
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("Colormatic")));
ColormaticConfig colormaticConfig = Colormatic.config();
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("colormatic.config.option.clearSky"), (button) -> button.setMessage(colormaticConfig.clearSky ? YES : NO), (button) -> {
colormaticConfig.clearSky = !colormaticConfig.clearSky;
ColormaticConfigController.persist(colormaticConfig);
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("colormatic.config.option.clearVoid"), (button) -> button.setMessage(colormaticConfig.clearVoid ? YES : NO), (button) -> {
colormaticConfig.clearVoid = !colormaticConfig.clearVoid;
ColormaticConfigController.persist(colormaticConfig);
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("colormatic.config.option.blendSkyLight"), (button) -> button.setMessage(colormaticConfig.blendSkyLight ? YES : NO), (button) -> {
colormaticConfig.blendSkyLight = !colormaticConfig.blendSkyLight;
ColormaticConfigController.persist(colormaticConfig);
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("colormatic.config.option.flickerBlockLight"), (button) -> button.setMessage(colormaticConfig.flickerBlockLight ? YES : NO), (button) -> {
colormaticConfig.flickerBlockLight = !colormaticConfig.flickerBlockLight;
ColormaticConfigController.persist(colormaticConfig);
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(0, 100, Text.translatable("colormatic.config.option.relativeBlockLightIntensity"),
() -> (int) (100*(1.0 - colormaticConfig.relativeBlockLightIntensityExponent / -16.0)),
(button) -> button.setMessage(Text.translatable("colormatic.config.option.relativeBlockLightIntensity")
.append(": ")
.append(Text.literal(String.valueOf((int)(100 * Math.exp(ColormaticConfig.scaled(colormaticConfig.relativeBlockLightIntensityExponent))))).append("%"))),
(slider) -> {
try {
colormaticConfig.relativeBlockLightIntensityExponent = ((1.00 - ((slider.getInt())/100f)) * -16.0);
ColormaticConfigController.persist(colormaticConfig);
}
catch (NumberFormatException ignored) {}
}));
}
if (FabricLoader.getInstance().isModLoaded("dynamicfps") && !PuzzleConfig.disabledIntegrations.contains("dynamicfps")) {
PuzzleApi.addToPerformanceOptions(new PuzzleWidget(Text.of("Dynamic FPS")));
DynamicFPSConfig fpsConfig = DynamicFPSMod.config;
PuzzleApi.addToPerformanceOptions(new PuzzleWidget(Text.translatable("config.dynamicfps.reduce_when_unfocused"), (button) -> button.setMessage(fpsConfig.reduceFPSWhenUnfocused ? YES : NO), (button) -> {
fpsConfig.reduceFPSWhenUnfocused = !fpsConfig.reduceFPSWhenUnfocused;
fpsConfig.save();
}));
PuzzleApi.addToPerformanceOptions(new PuzzleWidget(0, 60,Text.translatable("config.dynamicfps.unfocused_fps"), () -> fpsConfig.unfocusedFPS,
(button) -> button.setMessage(Text.of(fpsConfig.unfocusedFPS + " FPS")),
(slider) -> {
try {
fpsConfig.unfocusedFPS = slider.getInt();
}
catch (NumberFormatException ignored) {}
finally {fpsConfig.save();}
}));
PuzzleApi.addToPerformanceOptions(new PuzzleWidget(Text.translatable("config.dynamicfps.restore_when_hovered"), (button) -> button.setMessage(fpsConfig.restoreFPSWhenHovered ? YES : NO), (button) -> {
fpsConfig.restoreFPSWhenHovered = !fpsConfig.restoreFPSWhenHovered;
fpsConfig.save();
}));
PuzzleApi.addToPerformanceOptions(new PuzzleWidget(Text.translatable("config.dynamicfps.run_gc_on_unfocus"), (button) -> button.setMessage(fpsConfig.runGCOnUnfocus ? YES : NO), (button) -> {
fpsConfig.runGCOnUnfocus = !fpsConfig.runGCOnUnfocus;
fpsConfig.save();
}));
PuzzleApi.addToPerformanceOptions(new PuzzleWidget(0, 100,Text.translatable("config.dynamicfps.unfocused_volume"), () -> ((Number)(fpsConfig.unfocusedVolumeMultiplier * 100)).intValue(),
(button) -> button.setMessage(Text.of(((Number)(fpsConfig.unfocusedVolumeMultiplier * 100)).intValue() + "%")),
(slider) -> {
try {
fpsConfig.unfocusedVolumeMultiplier = ((Number)slider.getInt()).floatValue() / 100;
}
catch (NumberFormatException ignored) {}
finally {fpsConfig.save();}
}));
PuzzleApi.addToPerformanceOptions(new PuzzleWidget(0, 100,Text.translatable("config.dynamicfps.hidden_volume"), () -> ((Number)(fpsConfig.hiddenVolumeMultiplier * 100)).intValue(),
(button) -> button.setMessage(Text.of(((Number)(fpsConfig.hiddenVolumeMultiplier * 100)).intValue() + "%")),
(slider) -> {
try {
fpsConfig.hiddenVolumeMultiplier = ((Number)slider.getInt()).floatValue() / 100;
}
catch (NumberFormatException ignored) {}
finally {fpsConfig.save();}
}));
}
if (FabricLoader.getInstance().isModLoaded("borderlessmining") && !PuzzleConfig.disabledIntegrations.contains("borderlessmining")) {
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.of("Borderless Mining")));
ConfigHandler bmConfig = ConfigHandler.getInstance();
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.translatable("config.borderlessmining.general.enabled"), (button) -> button.setMessage(bmConfig.isEnabledOrPending() ? YES : NO), (button) -> {
bmConfig.setEnabledPending(!bmConfig.isEnabledOrPending());
bmConfig.save();
}));
if (MinecraftClient.IS_SYSTEM_MAC) {
PuzzleApi.addToMiscOptions(new PuzzleWidget(Text.translatable("config.borderlessmining.general.enabledmac"), (button) -> button.setMessage(bmConfig.enableMacOS ? YES : NO), (button) -> {
bmConfig.enableMacOS = !bmConfig.enableMacOS;
bmConfig.setEnabledPending(bmConfig.isEnabled());
bmConfig.save();
}));
}
}
if (FabricLoader.getInstance().isModLoaded("iris") && !PuzzleConfig.disabledIntegrations.contains("iris")) {
IrisCompat.init();
}
}
public static boolean lateInitDone = false;
public static void lateInit() { // Some mods are initialized after Puzzle, so we can't access them in our ClientModInitializer
if (FabricLoader.getInstance().isModLoaded("lambdynlights") && !PuzzleConfig.disabledIntegrations.contains("lambdynlights")) {
DynamicLightsConfig ldlConfig = LambDynLights.get().config;
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.of("LambDynamicLights")));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("lambdynlights.option.mode"), (button) -> button.setMessage(ldlConfig.getDynamicLightsMode().getTranslatedText()), (button) -> ldlConfig.setDynamicLightsMode(ldlConfig.getDynamicLightsMode().next())));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("").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())));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("").append("DynLights: ").append(Text.translatable("lambdynlights.option.light_sources.block_entities")), (button) -> button.setMessage(ldlConfig.getBlockEntitiesLightSource().get() ? YES : NO), (button) -> ldlConfig.getBlockEntitiesLightSource().set(!ldlConfig.getBlockEntitiesLightSource().get())));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("").append("DynLights: ").append(Text.translatable("entity.minecraft.creeper")), (button) -> button.setMessage(ldlConfig.getCreeperLightingMode().getTranslatedText()), (button) -> ldlConfig.setCreeperLightingMode(ldlConfig.getCreeperLightingMode().next())));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("").append("DynLights: ").append(Text.translatable("block.minecraft.tnt")), (button) -> button.setMessage(ldlConfig.getTntLightingMode().getTranslatedText()), (button) -> ldlConfig.setTntLightingMode(ldlConfig.getTntLightingMode().next())));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("").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())));
}
if (FabricLoader.getInstance().isModLoaded("citresewn") && !PuzzleConfig.disabledIntegrations.contains("citresewn") && CITResewnConfig.INSTANCE != null) {
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("CIT Resewn")));
CITResewnConfig citConfig = CITResewnConfig.INSTANCE;
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.citresewn.enabled.title"), (button) -> button.setMessage(citConfig.enabled ? YES : NO), (button) -> {
citConfig.enabled = !citConfig.enabled;
citConfig.write();
MinecraftClient.getInstance().reloadResources();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.citresewn.mute_errors.title"), (button) -> button.setMessage(citConfig.mute_errors ? YES : NO), (button) -> {
citConfig.mute_errors = !citConfig.mute_errors;
citConfig.write();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.citresewn.mute_warns.title"), (button) -> button.setMessage(citConfig.mute_warns ? YES : NO), (button) -> {
citConfig.mute_warns = !citConfig.mute_warns;
citConfig.write();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.citresewn.broken_paths.title"), (button) -> button.setMessage(citConfig.broken_paths ? YES : NO), (button) -> {
citConfig.broken_paths = !citConfig.broken_paths;
citConfig.write();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(0, 100,Text.translatable("config.citresewn.cache_ms.title"), () -> citConfig.cache_ms,
(button) -> button.setMessage(message(citConfig)),
(slider) -> {
try {
citConfig.cache_ms = slider.getInt();
}
catch (NumberFormatException ignored) {}
citConfig.write();
}));
}
if (FabricLoader.getInstance().isModLoaded("lambdabettergrass") && !PuzzleConfig.disabledIntegrations.contains("lambdabettergrass")) {
LBGConfig lbgConfig = LambdaBetterGrass.get().config;
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.of("LambdaBetterGrass")));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("lambdabettergrass.option.mode"), (button) -> button.setMessage(lbgConfig.getMode().getTranslatedText()), (button) -> lbgConfig.setMode(lbgConfig.getMode().next())));
PuzzleApi.addToGraphicsOptions(new PuzzleWidget(Text.translatable("lambdabettergrass.option.better_snow"), (button) -> button.setMessage(lbgConfig.hasBetterLayer() ? YES : NO), (button) -> lbgConfig.setBetterLayer(!lbgConfig.hasBetterLayer())));
}
if (FabricLoader.getInstance().isModLoaded("cem") && FabricLoader.getInstance().isModLoaded("completeconfig") && !PuzzleConfig.disabledIntegrations.contains("cem")) {
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("Custom Entity Models")));
CemConfig cemConfig = (CemConfig) CemConfigFairy.getConfig();
CemOptions cemOptions = CemConfigFairy.getConfig();
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.cem.use_optifine_folder"), (button) -> button.setMessage(cemConfig.useOptifineFolder() ? YES : NO), (button) -> {
((CemConfigAccessor)cemOptions).setUseOptifineFolder(!cemConfig.useOptifineFolder());
cemConfig.save();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.cem.use_new_model_creation_fix"), (button) -> button.setMessage(cemConfig.useTransparentParts() ? YES : NO), (button) -> {
((CemConfigAccessor)cemOptions).setUseModelCreationFix(!cemConfig.useTransparentParts());
cemConfig.save();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.cem.use_old_animations"), (button) -> button.setMessage(cemConfig.useOldAnimations() ? YES : NO), (button) -> {
((CemConfigAccessor)cemOptions).setUseOldAnimations(!cemConfig.useOldAnimations());
cemConfig.save();
}));
}
if (FabricLoader.getInstance().isModLoaded("continuity") && !PuzzleConfig.disabledIntegrations.contains("continuity")) {
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.of("Continuity")));
ContinuityConfig contConfig = ContinuityConfig.INSTANCE;
contConfig.getOptionMapView().forEach((s, option) -> {
if (s.equals("use_manual_culling")) return;
try {
Option.BooleanOption booleanOption = ((Option.BooleanOption)option);
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("options.continuity."+s), (button) -> button.setMessage(booleanOption.get() ? YES : NO), (button) -> {
booleanOption.set(!booleanOption.get());
contConfig.onChange();
contConfig.save();
}));
} catch (Exception ignored) {}
});
}
if (FabricLoader.getInstance().isModLoaded("entity_texture_features") && !PuzzleConfig.disabledIntegrations.contains("entity_texture_features")) {
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.title")));
ETFConfig etfConfig = ETFApi.getETFConfigObject;
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.enable_custom_textures.title"), (button) -> button.setMessage(etfConfig.enableCustomTextures ? YES : NO), (button) -> {
etfConfig.enableCustomTextures = !etfConfig.enableCustomTextures;
ETFApi.saveETFConfigChangesAndResetETF();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.enable_emissive_textures.title"), (button) -> button.setMessage(etfConfig.enableEmissiveTextures ? YES : NO), (button) -> {
etfConfig.enableEmissiveTextures = !etfConfig.enableEmissiveTextures;
ETFApi.saveETFConfigChangesAndResetETF();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.full_bright_emissives.title"), (button) -> button.setMessage(
etfConfig.fullBrightEmissives ? Text.translatable("entity_texture_features.puzzle.emissive_type.brighter") : Text.translatable("entity_texture_features.puzzle.emissive_type.default")), (button) -> {
etfConfig.fullBrightEmissives = !etfConfig.fullBrightEmissives ;
ETFApi.saveETFConfigChangesAndResetETF();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.blinking_mob_settings.title"), (button) -> button.setMessage(etfConfig.enableBlinking ? YES : NO), (button) -> {
etfConfig.enableBlinking = !etfConfig.enableBlinking;
ETFApi.saveETFConfigChangesAndResetETF();
}));
PuzzleApi.addToResourceOptions(new PuzzleWidget(Text.translatable("config.entity_texture_features.player_skin_features.title"), (button) -> button.setMessage(etfConfig.skinFeaturesEnabled ? YES : NO), (button) -> {
etfConfig.skinFeaturesEnabled = !etfConfig.skinFeaturesEnabled;
ETFApi.saveETFConfigChangesAndResetETF();
}));
}
lateInitDone = true;
}
public static Text message(CITResewnConfig config) {
int ticks = config.cache_ms;
if (ticks <= 1) {
return (Text.translatable("config.citresewn.cache_ms.ticks." + ticks)).formatted(Formatting.AQUA);
} else {
Formatting color = Formatting.DARK_RED;
if (ticks <= 40) {
color = Formatting.RED;
}
if (ticks <= 20) {
color = Formatting.GOLD;
}
if (ticks <= 10) {
color = Formatting.DARK_GREEN;
}
if (ticks <= 5) {
color = Formatting.GREEN;
}
return (Text.translatable("config.citresewn.cache_ms.ticks.any", ticks)).formatted(color);
}
}
}

View File

@@ -1,31 +0,0 @@
package net.puzzlemc.gui.config;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
import net.puzzlemc.gui.screen.PuzzleOptionsScreen;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import java.util.HashMap;
import java.util.Map;
@Environment(EnvType.CLIENT)
public class ModMenuIntegration implements ModMenuApi {
@Override
public ConfigScreenFactory<?> getModConfigScreenFactory() {
return PuzzleOptionsScreen::new;
}
//Used to set the config screen for all modules //
@Override
public Map<String, ConfigScreenFactory<?>> getProvidedConfigScreenFactories() {
Map<String, ConfigScreenFactory<?>> map = new HashMap<>();
map.put("puzzle-gui",PuzzleOptionsScreen::new);
map.put("puzzle-blocks",PuzzleOptionsScreen::new);
map.put("puzzle-base",PuzzleOptionsScreen::new);
map.put("puzzle-models",PuzzleOptionsScreen::new);
map.put("puzzle-splashscreen",PuzzleOptionsScreen::new);
map.put("puzzle",PuzzleOptionsScreen::new);
return map;
}
}

View File

@@ -1,17 +0,0 @@
package net.puzzlemc.gui.mixin;
import net.dorianpb.cem.internal.config.CemConfig;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(value = CemConfig.class, remap = false)
public interface CemConfigAccessor {
@Accessor("use_optifine_folder")
void setUseOptifineFolder(boolean value);
@Accessor("use_new_model_creation_fix")
void setUseModelCreationFix(boolean value);
@Accessor("use_old_animations")
void setUseOldAnimations(boolean value);
}

View File

@@ -1,37 +0,0 @@
package net.puzzlemc.gui.mixin;
import eu.midnightdust.core.config.MidnightLibConfig;
import eu.midnightdust.lib.util.screen.TexturedOverlayButtonWidget;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.util.Identifier;
import net.puzzlemc.core.config.PuzzleConfig;
import net.puzzlemc.gui.PuzzleClient;
import net.puzzlemc.gui.screen.PuzzleOptionsScreen;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.option.OptionsScreen;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Objects;
@Mixin(OptionsScreen.class)
public abstract class MixinOptionsScreen extends Screen {
private static final Identifier PUZZLE_ICON_TEXTURE = new Identifier(PuzzleClient.id, "textures/gui/puzzle_button.png");
protected MixinOptionsScreen(Text title) {
super(title);
}
@Inject(at = @At("HEAD"), method = "init")
private void puzzle$init(CallbackInfo ci) {
if (PuzzleConfig.enablePuzzleButton) {
int i = 0;
if (FabricLoader.getInstance().isModLoaded("lod")) i = i + 358;
if (MidnightLibConfig.config_screen_list.equals(MidnightLibConfig.ConfigButton.FALSE)) i = i - 25;
this.addDrawableChild(new TexturedOverlayButtonWidget(this.width / 2 - 178 + i, this.height / 6 - 12, 20, 20, 0, 0, 20, PUZZLE_ICON_TEXTURE, 32, 64, (buttonWidget) -> (Objects.requireNonNull(this.client)).setScreen(new PuzzleOptionsScreen(this)), Text.translatable("midnightlib.overview.title")));
}
}
}

View File

@@ -1,48 +0,0 @@
package net.puzzlemc.gui.screen;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.puzzlemc.gui.PuzzleClient;
import net.puzzlemc.gui.screen.page.GraphicsPage;
import net.puzzlemc.gui.screen.page.MiscPage;
import net.puzzlemc.gui.screen.page.PerformancePage;
import net.puzzlemc.gui.screen.page.ResourcesPage;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.util.math.MatrixStack;
import java.util.Objects;
public class PuzzleOptionsScreen extends Screen {
public PuzzleOptionsScreen(Screen parent) {
super(Text.translatable("puzzle.screen.title"));
this.parent = parent;
}
private final Screen parent;
@Override
protected void init() {
super.init();
if (!PuzzleClient.lateInitDone) PuzzleClient.lateInit();
GraphicsPage graphicsPage = new GraphicsPage(this);
MiscPage miscPage = new MiscPage(this);
PerformancePage performancePage = new PerformancePage(this);
ResourcesPage resourcesPage = new ResourcesPage(this);
if (!PuzzleApi.GRAPHICS_OPTIONS.isEmpty()) this.addDrawableChild(new ButtonWidget(this.width / 2 - 155, this.height / 6 + 48 - 6, 150, 20, graphicsPage.getTitle().copy().append("..."), (button) -> Objects.requireNonNull(client).setScreen(graphicsPage)));
if (!PuzzleApi.RESOURCE_OPTIONS.isEmpty()) this.addDrawableChild(new ButtonWidget(this.width / 2 + 5, this.height / 6 + 48 - 6, 150, 20, resourcesPage.getTitle().copy().append("..."), (button) -> Objects.requireNonNull(client).setScreen(resourcesPage)));
if (!PuzzleApi.PERFORMANCE_OPTIONS.isEmpty()) this.addDrawableChild(new ButtonWidget(this.width / 2 - 155, this.height / 6 + 72 - 6, 150, 20, performancePage.getTitle().copy().append("..."), (button) -> Objects.requireNonNull(client).setScreen(performancePage)));
if (!PuzzleApi.MISC_OPTIONS.isEmpty()) this.addDrawableChild(new ButtonWidget(this.width / 2 + 5, this.height / 6 + 72 - 6, 150, 20, miscPage.getTitle().copy().append("..."), (button) -> Objects.requireNonNull(client).setScreen(miscPage)));
this.addDrawableChild(new ButtonWidget(this.width / 2 - 100, this.height / 6 + 168, 200, 20, ScreenTexts.DONE, (button) -> Objects.requireNonNull(client).setScreen(parent)));
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
this.renderBackground(matrices);
super.render(matrices, mouseX, mouseY, delta);
drawCenteredText(matrices, textRenderer, title, width/2, 15, 0xFFFFFF);
}
}

View File

@@ -1,53 +0,0 @@
package net.puzzlemc.gui.screen.page;
import net.minecraft.screen.ScreenTexts;
import net.minecraft.text.Text;
import net.puzzlemc.gui.screen.widget.PuzzleOptionListWidget;
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.util.math.MatrixStack;
import java.util.List;
import java.util.Objects;
public abstract class AbstractPuzzleOptionsPage extends Screen {
public PuzzleOptionListWidget list;
private final List<PuzzleWidget> options;
public List<Text> tooltip = null;
public AbstractPuzzleOptionsPage(Screen parent, Text title, List<PuzzleWidget> options) {
super(title);
this.parent = parent;
this.options = options;
}
private final Screen parent;
@Override
protected void init() {
this.list = new PuzzleOptionListWidget(this.client, this.width, this.height, 32, this.height - 32, 25);
list.addAll(options);
this.addSelectableChild(this.list);
super.init();
this.addDrawableChild(new ButtonWidget(this.width / 2 - 100, this.height - 28, 200, 20, ScreenTexts.DONE, (button) -> Objects.requireNonNull(client).setScreen(parent)));
}
@Override
public void render(MatrixStack matrices, int mouseX, int mouseY, float delta) {
this.renderBackground(matrices);
if (client != null && client.world != null) this.list.setRenderBackground(false);
this.list.render(matrices, mouseX, mouseY, delta);
drawCenteredText(matrices, textRenderer, title, width/2, 15, 0xFFFFFF);
super.render(matrices, mouseX, mouseY, delta);
if (tooltip != null) {
if (this.list.getFocused() != null && (this.list.getHoveredEntry() == null || this.list.getHoveredEntry().button == null || !this.list.getHoveredEntry().button.isMouseOver(mouseX, mouseY))) {
renderTooltip(matrices, tooltip, this.list.getFocused().getX() + this.list.getFocused().getWidth(), this.list.getFocused().getY() + (this.list.getFocused().getHeight() * 2));
}
else renderTooltip(matrices, tooltip, mouseX, mouseY);
}
tooltip = null;
}
}

View File

@@ -1,12 +0,0 @@
package net.puzzlemc.gui.screen.page;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.minecraft.client.gui.screen.Screen;
public class GraphicsPage extends AbstractPuzzleOptionsPage {
public GraphicsPage(Screen parent) {
super(parent, Text.translatable("puzzle.page.graphics"), PuzzleApi.GRAPHICS_OPTIONS);
}
}

View File

@@ -1,12 +0,0 @@
package net.puzzlemc.gui.screen.page;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.minecraft.client.gui.screen.Screen;
public class MiscPage extends AbstractPuzzleOptionsPage {
public MiscPage(Screen parent) {
super(parent, Text.translatable("puzzle.page.misc"), PuzzleApi.MISC_OPTIONS);
}
}

View File

@@ -1,12 +0,0 @@
package net.puzzlemc.gui.screen.page;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.minecraft.client.gui.screen.Screen;
public class PerformancePage extends AbstractPuzzleOptionsPage {
public PerformancePage(Screen parent) {
super(parent, Text.translatable("puzzle.page.performance"), PuzzleApi.PERFORMANCE_OPTIONS);
}
}

View File

@@ -1,12 +0,0 @@
package net.puzzlemc.gui.screen.page;
import net.minecraft.text.Text;
import net.puzzlemc.gui.PuzzleApi;
import net.minecraft.client.gui.screen.Screen;
public class ResourcesPage extends AbstractPuzzleOptionsPage {
public ResourcesPage(Screen parent) {
super(parent, Text.translatable("puzzle.page.resources"), PuzzleApi.RESOURCE_OPTIONS);
}
}

View File

@@ -1,19 +0,0 @@
package net.puzzlemc.gui.screen.widget;
import net.minecraft.client.gui.widget.ButtonWidget;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
public class PuzzleButtonWidget extends ButtonWidget {
private final PuzzleWidget.TextAction title;
public PuzzleButtonWidget(int x, int y, int width, int height, PuzzleWidget.TextAction title, PressAction onPress) {
super(x, y, width, height, Text.of(""), onPress);
this.title = title;
}
@Override
public void renderButton(MatrixStack matrices, int mouseX, int mouseY, float delta) {
title.setTitle(this);
super.renderButton(matrices, mouseX, mouseY, delta);
}
}

View File

@@ -1,129 +0,0 @@
package net.puzzlemc.gui.screen.widget;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.Selectable;
import net.minecraft.client.gui.widget.ClickableWidget;
import net.minecraft.client.gui.widget.ElementListWidget;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableTextContent;
import net.puzzlemc.gui.screen.page.AbstractPuzzleOptionsPage;
import org.apache.logging.log4j.LogManager;
import java.util.*;
@Environment(EnvType.CLIENT)
public class PuzzleOptionListWidget extends ElementListWidget<PuzzleOptionListWidget.ButtonEntry> {
TextRenderer textRenderer;
public PuzzleOptionListWidget(MinecraftClient minecraftClient, int i, int j, int k, int l, int m) {
super(minecraftClient, i, j, k, l, m);
this.centerListVertically = false;
textRenderer = minecraftClient.textRenderer;
}
public void addButton(ClickableWidget button, Text text) {
this.addEntry(ButtonEntry.create(button, text));
}
public void addAll(List<PuzzleWidget> buttons) {
for (PuzzleWidget button : buttons) {
if (button.buttonType == ButtonType.TEXT) {
this.addButton(null, button.descriptionText);
} else if (button.buttonType == ButtonType.BUTTON) {
this.addButton(new PuzzleButtonWidget(this.width / 2 + 25, 0, 150, 20, button.buttonTextAction, button.onPress), button.descriptionText);
} else if (button.buttonType == ButtonType.SLIDER) {
this.addButton(new PuzzleSliderWidget(button.min, button.max, this.width / 2 + 25, 0, 150, 20, button.defaultSliderValue.getAsInt(), button.buttonTextAction, button.changeSliderValue), button.descriptionText);
} else if (button.buttonType == ButtonType.TEXT_FIELD) {
this.addButton(new PuzzleTextFieldWidget(textRenderer, this.width / 2 + 25, 0, 150, 20, button.setTextValue, button.changeTextValue), button.descriptionText);
} else
LogManager.getLogger("Puzzle").warn("Button " + button + " is missing the buttonType variable. This shouldn't happen!");
}
}
public int getRowWidth() {
return 400;
}
protected int getScrollbarPositionX() {
return super.getScrollbarPositionX() + 60;
}
@Override
public ButtonEntry getHoveredEntry() {
return super.getHoveredEntry();
}
public static class ButtonEntry extends ElementListWidget.Entry<ButtonEntry> {
private static final TextRenderer textRenderer = MinecraftClient.getInstance().textRenderer;
private List<ClickableWidget> buttons = new ArrayList<>();
public final ClickableWidget button;
public final Text text;
private MinecraftClient client = MinecraftClient.getInstance();
private ButtonEntry(ClickableWidget button, Text text) {
if (button != null)
this.buttons.add(button);
this.button = button;
this.text = text;
}
public static ButtonEntry create(ClickableWidget button, Text text) {
return new ButtonEntry(button, text);
}
public void render(MatrixStack matrices, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
if (button != null) {
button.y = y;
button.render(matrices, mouseX, mouseY, tickDelta);
}
if (button == null) drawCenteredText(matrices,textRenderer, Text.literal(" ").append(text).append(" "),x + 200,y+5,0xFFFFFF);
else drawTextWithShadow(matrices,textRenderer, text,x+15,y+5,0xFFFFFF);
if (!(client.currentScreen instanceof AbstractPuzzleOptionsPage page)) return;
if (button != null && (button.isMouseOver(mouseX, mouseY) || ((page.list.getHoveredEntry() == null || page.list.getHoveredEntry().button == null || !page.list.getHoveredEntry().button.isMouseOver(mouseX, mouseY)) && button.isFocused())) && text.getContent() instanceof TranslatableTextContent content) {
String key = null;
if (I18n.hasTranslation(content.getKey() + ".tooltip")) key = content.getKey() + ".tooltip";
else if (I18n.hasTranslation(content.getKey() + ".desc")) key = content.getKey() + ".desc";
if (key == null && content.getKey().endsWith(".title")) {
String strippedContent = content.getKey().substring(0, content.getKey().length()-6);
if (I18n.hasTranslation(strippedContent + ".tooltip")) key = strippedContent + ".tooltip";
else if (I18n.hasTranslation(strippedContent + ".desc")) key = strippedContent + ".desc";
}
if (key != null) {
List<Text> list = new ArrayList<>();
for (String str : I18n.translate(key).split("\n"))
list.add(Text.literal(str));
page.tooltip = list;
}
}
}
public int getY() {
return button.y;
}
public int getX() {
return button.x;
}
public int getHeight() {
return button.getHeight();
}
public int getWidth() {
return button.getWidth();
}
public List<? extends Element> children() {
return buttons;
}
@Override
public List<? extends Selectable> selectableChildren() {
return buttons;
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 179 B

View File

@@ -1,14 +0,0 @@
archivesBaseName = "puzzle-models"
loom {
accessWidenerPath = file("src/main/resources/puzzle-models.accesswidener")
}
repositories {
maven {
url = "https://api.modrinth.com/maven"
}
}
dependencies {
api project(":puzzle-base")
modImplementation "maven.modrinth:midnightlib:${project.midnightlib_version}"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,35 +0,0 @@
{
"schemaVersion": 1,
"id": "puzzle-models",
"version": "${version}",
"name": "Puzzle Models",
"description": "Provides more freedom for item and block models!",
"authors": [
"PuzzleMC",
"Motschen"
],
"contact": {
"homepage": "https://www.midnightdust.eu/",
"sources": "https://github.com/TeamMidnightDust/Puzzle",
"issues": "https://github.com/TeamMidnightDust/Puzzle/issues"
},
"custom": {
"modmenu": {
"parent": "puzzle"
}
},
"license": "MIT",
"icon": "assets/puzzle/icon.png",
"environment": "client",
"accessWidener" : "puzzle-models.accesswidener",
"mixins": [
"puzzle-models.mixins.json"
],
"depends": {
"fabric": "*"
}
}

View File

@@ -1,10 +0,0 @@
archivesBaseName = "puzzle-splashscreen"
repositories {
maven {
url = "https://api.modrinth.com/maven"
}
}
dependencies {
api project(":puzzle-base")
modImplementation "maven.modrinth:midnightlib:${project.midnightlib_version}"
}

View File

@@ -1,158 +0,0 @@
package net.puzzlemc.splashscreen;
import eu.midnightdust.lib.util.MidnightColorUtil;
import net.fabricmc.api.ClientModInitializer;
import net.minecraft.client.texture.NativeImageBackedTexture;
import net.minecraft.util.Util;
import net.minecraft.util.math.ColorHelper;
import net.puzzlemc.core.config.PuzzleConfig;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.resource.metadata.TextureResourceMetadata;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.ResourceTexture;
import net.minecraft.resource.DefaultResourcePack;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;
import org.apache.logging.log4j.LogManager;
import java.awt.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Properties;
public class PuzzleSplashScreen implements ClientModInitializer {
public static final Identifier LOGO = new Identifier("textures/gui/title/mojangstudios.png");
public static final Identifier BACKGROUND = new Identifier("optifine/splash_background.png");
public static File CONFIG_PATH = new File(String.valueOf(FabricLoader.getInstance().getConfigDir().resolve(".puzzle_cache")));
public static Path LOGO_TEXTURE = Paths.get(CONFIG_PATH + "/mojangstudios.png");
public static Path BACKGROUND_TEXTURE = Paths.get(CONFIG_PATH + "/splash_background.png");
private static final MinecraftClient client = MinecraftClient.getInstance();
private static boolean keepBackground = true;
public static void resetColors() {
PuzzleConfig.backgroundColor = 15675965;
PuzzleConfig.progressBarColor = 16777215;
PuzzleConfig.progressBarBackgroundColor = 15675965;
PuzzleConfig.progressFrameColor = 16777215;
PuzzleConfig.disableBlend = false;
PuzzleConfig.write("puzzle");
}
public void onInitializeClient() {
if (!CONFIG_PATH.exists()) { // Run when config directory is nonexistent //
if (CONFIG_PATH.mkdir()) { // Create our custom config directory //
if (Util.getOperatingSystem().equals(Util.OperatingSystem.WINDOWS)) {
try {
Files.setAttribute(CONFIG_PATH.toPath(), "dos:hidden", true);
} catch (IOException ignored) {
}
}
}
}
ResourceManagerHelper.get(ResourceType.CLIENT_RESOURCES).registerReloadListener(new SimpleSynchronousResourceReloadListener() {
@Override
public Identifier getFabricId() {
return new Identifier("puzzle", "splash_screen");
}
public void method_14491(ResourceManager manager) {
reload(manager);
}
@Override
public void reload(ResourceManager manager) {
if (PuzzleConfig.resourcepackSplashScreen) {
PuzzleSplashScreen.resetColors();
client.getTextureManager().registerTexture(LOGO, new LogoTexture(LOGO));
client.getTextureManager().registerTexture(BACKGROUND, new LogoTexture(BACKGROUND));
manager.findResources("optifine", path -> path.getPath().contains("color.properties")).forEach((id, resource) -> {
try (InputStream stream = manager.getResource(id).get().getInputStream()) {
Properties properties = new Properties();
properties.load(stream);
if (properties.get("screen.loading") != null) {
PuzzleConfig.backgroundColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading").toString()).getRGB();
}
if (properties.get("screen.loading.bar") != null) {
PuzzleConfig.progressBarBackgroundColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.bar").toString()).getRGB();
}
if (properties.get("screen.loading.progress") != null) {
PuzzleConfig.progressBarColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.progress").toString()).getRGB();
}
if (properties.get("screen.loading.outline") != null) {
PuzzleConfig.progressFrameColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.outline").toString()).getRGB();
}
if (properties.get("screen.loading.blend") != null) {
PuzzleConfig.disableBlend = properties.get("screen.loading.blend").toString().equals("off");
PuzzleConfig.progressFrameColor = MidnightColorUtil.hex2Rgb(properties.get("screen.loading.outline").toString()).getRGB();
}
PuzzleConfig.write("puzzle");
} catch (Exception e) {
LogManager.getLogger("Puzzle").error("Error occurred while loading color.properties " + id.toString(), e);
}
});
manager.findResources("textures", path -> path.getPath().contains("mojangstudios.png")).forEach((id, resource) -> {
try (InputStream stream = manager.getResource(id).get().getInputStream()) {
Files.copy(stream, LOGO_TEXTURE, StandardCopyOption.REPLACE_EXISTING);
InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.LOGO_TEXTURE));
client.getTextureManager().registerTexture(LOGO, new NativeImageBackedTexture(NativeImage.read(input)));
} catch (Exception e) {
LogManager.getLogger("Puzzle").error("Error occurred while loading custom minecraft logo " + id.toString(), e);
}
});
manager.findResources("puzzle", path -> path.getPath().contains("splash_background.png")).forEach((id, resource) -> {
try (InputStream stream = manager.getResource(id).get().getInputStream()) {
Files.copy(stream, BACKGROUND_TEXTURE, StandardCopyOption.REPLACE_EXISTING);
InputStream input = new FileInputStream(String.valueOf(PuzzleSplashScreen.BACKGROUND_TEXTURE));
client.getTextureManager().registerTexture(BACKGROUND, new NativeImageBackedTexture(NativeImage.read(input)));
keepBackground = true;
} catch (Exception e) {
LogManager.getLogger("Puzzle").error("Error occurred while loading custom splash background " + id.toString(), e);
}
});
if (!keepBackground) {
try {
Files.delete(BACKGROUND_TEXTURE);
} catch (Exception ignored) {}
}
keepBackground = false;
}
}
});
}
@Environment(EnvType.CLIENT)
public static class LogoTexture extends ResourceTexture {
public LogoTexture(Identifier logo) { super(logo); }
protected TextureData loadTextureData(ResourceManager resourceManager) {
MinecraftClient minecraftClient = MinecraftClient.getInstance();
DefaultResourcePack defaultResourcePack = minecraftClient.getResourcePackProvider().getPack();
try {
InputStream inputStream = defaultResourcePack.open(ResourceType.CLIENT_RESOURCES, LOGO);
TextureData var6;
try {
var6 = new TextureData(new TextureResourceMetadata(true, true), NativeImage.read(inputStream));
} finally {
if (inputStream != null) {
inputStream.close();
}
}
return var6;
} catch (IOException var18) {
return new TextureData(var18);
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -1,40 +0,0 @@
{
"schemaVersion": 1,
"id": "puzzle-splashscreen",
"version": "${version}",
"name": "Puzzle Splash Screen",
"description": "Allows resourcepacks to define a custom splash screen",
"authors": [
"PuzzleMC",
"Motschen"
],
"contact": {
"homepage": "https://www.midnightdust.eu/",
"sources": "https://github.com/TeamMidnightDust/Puzzle",
"issues": "https://github.com/TeamMidnightDust/Puzzle/issues"
},
"license": "MIT",
"icon": "assets/puzzle/icon.png",
"environment": "client",
"entrypoints": {
"client": [
"net.puzzlemc.splashscreen.PuzzleSplashScreen"
]
},
"custom": {
"modmenu": {
"parent": "puzzle"
}
},
"mixins": [
"puzzle-splashscreen.mixins.json"
],
"depends": {
"fabric": "*"
}
}

Binary file not shown.

View File

@@ -1,14 +1,15 @@
pluginManagement {
repositories {
maven {
name = 'Fabric'
url = 'https://maven.fabricmc.net/'
}
maven { url "https://maven.fabricmc.net/" }
maven { url "https://maven.architectury.dev/" }
maven { url "https://maven.neoforged.net/releases" }
gradlePluginPortal()
}
}
include 'puzzle-base'
include 'puzzle-splashscreen'
include 'puzzle-models'
include 'puzzle-gui'
include("common")
include("fabric")
include("neoforge")
//include("quilt")
rootProject.name = "puzzle"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,17 +0,0 @@
{
"puzzle.text.update_available":"Доступно обновление!",
"puzzle.screen.title":"Настройки Puzzle",
"puzzle.page.graphics":"Настройки графики",
"puzzle.page.resources":"Настройки ресурсов",
"puzzle.page.performance":"Производительность",
"puzzle.page.misc":"Прочие настройки",
"puzzle.option.check_for_updates":"Проверять обновления",
"puzzle.option.show_version_info":"Показывать информацию о версии",
"puzzle.option.resourcepack_splash_screen":"Пользовательский экран загрузки",
"puzzle.option.better_splash_screen_blend":"Улучшенное смешивание логотипа",
"puzzle.option.emissive_textures":"Светящиеся текстуры",
"puzzle.option.unlimited_model_rotations":"Неограниченные повороты моделей",
"puzzle.option.bigger_custom_models":"Увеличенный размер моделей",
"puzzle.option.render_layer_overrides":"Пользовательские слои отрисовки",
"puzzle.midnightconfig.title":"Расширенные настройки Puzzle"
}

View File

@@ -1,17 +0,0 @@
{
"puzzle.text.update_available":"有新版本可供升級!",
"puzzle.screen.title":"拼圖設置",
"puzzle.page.graphics":"顯示設置",
"puzzle.page.resources":"資源設置",
"puzzle.page.performance":"性能設置",
"puzzle.page.misc":"其他設置",
"puzzle.option.check_for_updates":"檢查更新",
"puzzle.option.show_version_info":"顯示拼圖版本信息",
"puzzle.option.resourcepack_splash_screen":"使用資源包的加載界面",
"puzzle.option.disable_splash_screen_blend":"禁止加載界面徽標渲染",
"puzzle.option.emissive_textures":"發光貼圖",
"puzzle.option.unlimited_model_rotations":"無限模型旋轉",
"puzzle.option.bigger_custom_models":"更大的自定義模型",
"puzzle.option.render_layer_overrides":"覆蓋渲染層",
"puzzle.midnightconfig.title":"拼圖高級設置"
}

View File

@@ -1,26 +0,0 @@
{
"schemaVersion": 1,
"id": "puzzle",
"version": "${version}",
"name": "Puzzle",
"description": "Fancy and performance-improving features.",
"authors": [
"PuzzleMC",
"Motschen"
],
"contact": {
"homepage": "https://www.midnightdust.eu/",
"sources": "https://github.com/TeamMidnightDust/Puzzle",
"issues": "https://github.com/TeamMidnightDust/Puzzle/issues"
},
"license": "MIT",
"icon": "assets/puzzle/icon.png",
"environment": "client",
"depends": {
"fabric": "*"
}
}