mirror of
https://github.com/PuzzleMC/Puzzle.git
synced 2025-12-16 20:05:09 +01:00
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
This commit is contained in:
18
common/src/main/java/net/puzzlemc/core/PuzzleCore.java
Executable file
18
common/src/main/java/net/puzzlemc/core/PuzzleCore.java
Executable 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();
|
||||
}
|
||||
}
|
||||
28
common/src/main/java/net/puzzlemc/core/config/PuzzleConfig.java
Executable file
28
common/src/main/java/net/puzzlemc/core/config/PuzzleConfig.java
Executable 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<>();
|
||||
}
|
||||
37
common/src/main/java/net/puzzlemc/gui/PuzzleApi.java
Executable file
37
common/src/main/java/net/puzzlemc/gui/PuzzleApi.java
Executable file
@@ -0,0 +1,37 @@
|
||||
package net.puzzlemc.gui;
|
||||
|
||||
import net.puzzlemc.core.config.PuzzleConfig;
|
||||
import net.puzzlemc.gui.screen.widget.PuzzleWidget;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
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<>();
|
||||
public static List<PuzzleWidget> RESOURCE_OPTIONS = new ArrayList<>();
|
||||
|
||||
public static void addToGraphicsOptions(PuzzleWidget button) {
|
||||
GRAPHICS_OPTIONS.add(button);
|
||||
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("{} -> Misc Options", button.descriptionText.getContent().toString());
|
||||
}
|
||||
public static void addToPerformanceOptions(PuzzleWidget button) {
|
||||
PERFORMANCE_OPTIONS.add(button);
|
||||
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("{} -> Resource Options", button.descriptionText.getContent().toString());
|
||||
}
|
||||
}
|
||||
68
common/src/main/java/net/puzzlemc/gui/PuzzleGui.java
Executable file
68
common/src/main/java/net/puzzlemc/gui/PuzzleGui.java
Executable 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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
60
common/src/main/java/net/puzzlemc/gui/compat/CITRCompat.java
Normal file
60
common/src/main/java/net/puzzlemc/gui/compat/CITRCompat.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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) {}
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -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) {}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}));
|
||||
}
|
||||
}
|
||||
39
common/src/main/java/net/puzzlemc/gui/compat/EMFCompat.java
Normal file
39
common/src/main/java/net/puzzlemc/gui/compat/EMFCompat.java
Normal 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();
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
47
common/src/main/java/net/puzzlemc/gui/compat/ETFCompat.java
Normal file
47
common/src/main/java/net/puzzlemc/gui/compat/ETFCompat.java
Normal 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();
|
||||
}));
|
||||
}
|
||||
}
|
||||
25
common/src/main/java/net/puzzlemc/gui/compat/IrisCompat.java
Normal file
25
common/src/main/java/net/puzzlemc/gui/compat/IrisCompat.java
Normal 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));
|
||||
}));
|
||||
}
|
||||
}
|
||||
19
common/src/main/java/net/puzzlemc/gui/compat/LBGCompat.java
Normal file
19
common/src/main/java/net/puzzlemc/gui/compat/LBGCompat.java
Normal 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())));
|
||||
}
|
||||
}
|
||||
24
common/src/main/java/net/puzzlemc/gui/compat/LDLCompat.java
Normal file
24
common/src/main/java/net/puzzlemc/gui/compat/LDLCompat.java
Normal 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())));
|
||||
}
|
||||
}
|
||||
52
common/src/main/java/net/puzzlemc/gui/mixin/MixinOptionsScreen.java
Executable file
52
common/src/main/java/net/puzzlemc/gui/mixin/MixinOptionsScreen.java
Executable 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 = "initTabNavigation")
|
||||
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);
|
||||
}
|
||||
}
|
||||
92
common/src/main/java/net/puzzlemc/gui/screen/PuzzleOptionsScreen.java
Executable file
92
common/src/main/java/net/puzzlemc/gui/screen/PuzzleOptionsScreen.java
Executable 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
5
common/src/main/java/net/puzzlemc/gui/screen/widget/ButtonType.java
Executable file
5
common/src/main/java/net/puzzlemc/gui/screen/widget/ButtonType.java
Executable file
@@ -0,0 +1,5 @@
|
||||
package net.puzzlemc.gui.screen.widget;
|
||||
|
||||
public enum ButtonType {
|
||||
TEXT, BUTTON, SLIDER, TEXT_FIELD
|
||||
}
|
||||
22
common/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleButtonWidget.java
Executable file
22
common/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleButtonWidget.java
Executable 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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
42
common/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleSliderWidget.java
Executable file
42
common/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleSliderWidget.java
Executable file
@@ -0,0 +1,42 @@
|
||||
package net.puzzlemc.gui.screen.widget;
|
||||
|
||||
import net.minecraft.client.gui.widget.SliderWidget;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public class PuzzleSliderWidget extends SliderWidget {
|
||||
private final int min;
|
||||
private final int max;
|
||||
private final PuzzleWidget.TextAction setTextAction;
|
||||
private final PuzzleWidget.ChangeSliderValueAction changeAction;
|
||||
|
||||
public PuzzleSliderWidget(int min, int max, int x, int y, int width, int height, float defaultValue, PuzzleWidget.TextAction setTextAction, PuzzleWidget.ChangeSliderValueAction changeAction) {
|
||||
super(x,y,width,height,Text.of(""),(defaultValue-min) / (max - min));
|
||||
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
|
||||
this.setTextAction = setTextAction;
|
||||
this.changeAction = changeAction;
|
||||
try {
|
||||
this.updateMessage();
|
||||
} catch (Exception e) {e.fillInStackTrace(); this.visible = false;}
|
||||
}
|
||||
public int getInt() {
|
||||
int difference = max - min;
|
||||
int r = (int) (value * difference);
|
||||
return r + min;
|
||||
}
|
||||
public void setInt(int v) {
|
||||
value = value / v - value * min;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateMessage() {
|
||||
this.setTextAction.setTitle(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyValue() {
|
||||
this.changeAction.onChange(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package net.puzzlemc.gui.screen.widget;
|
||||
|
||||
import net.minecraft.client.font.TextRenderer;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
public class PuzzleTextFieldWidget extends TextFieldWidget {
|
||||
private final PuzzleWidget.SetTextValueAction setValueAction;
|
||||
private final PuzzleWidget.ChangeTextValueAction change;
|
||||
|
||||
public PuzzleTextFieldWidget(TextRenderer textRenderer, int x, int y, int width, int height, PuzzleWidget.SetTextValueAction setValue, PuzzleWidget.ChangeTextValueAction change) {
|
||||
super(textRenderer, x, y, width, height, Text.of(""));
|
||||
this.setValueAction = setValue;
|
||||
this.change = change;
|
||||
try {
|
||||
setValueAction.setTextValue(this);
|
||||
} catch (Exception e) {e.fillInStackTrace(); this.setVisible(false);}
|
||||
}
|
||||
@Override
|
||||
public void write(String text) {
|
||||
super.write(text);
|
||||
this.change.onChange(this);
|
||||
setValueAction.setTextValue(this);
|
||||
}
|
||||
}
|
||||
78
common/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleWidget.java
Executable file
78
common/src/main/java/net/puzzlemc/gui/screen/widget/PuzzleWidget.java
Executable file
@@ -0,0 +1,78 @@
|
||||
package net.puzzlemc.gui.screen.widget;
|
||||
|
||||
import net.minecraft.client.gui.widget.ButtonWidget;
|
||||
import net.minecraft.client.gui.widget.ClickableWidget;
|
||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.function.IntSupplier;
|
||||
|
||||
public class PuzzleWidget {
|
||||
public ButtonType buttonType;
|
||||
public int min;
|
||||
public int max;
|
||||
public Text descriptionText;
|
||||
public TextAction buttonTextAction;
|
||||
public ButtonWidget.PressAction onPress;
|
||||
public PuzzleWidget.SetTextValueAction setTextValue;
|
||||
public IntSupplier defaultSliderValue;
|
||||
public PuzzleWidget.ChangeTextValueAction changeTextValue;
|
||||
public PuzzleWidget.ChangeSliderValueAction changeSliderValue;
|
||||
|
||||
/**
|
||||
* Puzzle Text Widget Container
|
||||
* @param descriptionText The text you want to display.
|
||||
*/
|
||||
public PuzzleWidget(Text descriptionText) {
|
||||
this.buttonType = ButtonType.TEXT;
|
||||
this.descriptionText = descriptionText;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puzzle Button Widget Container
|
||||
* @param descriptionText Tells the user what the option does.
|
||||
* @param getTitle Function to set the text on the button.
|
||||
* @param onPress Function to call when the user presses the button.
|
||||
*/
|
||||
public PuzzleWidget(Text descriptionText, PuzzleWidget.TextAction getTitle, ButtonWidget.PressAction onPress) {
|
||||
this.buttonType = ButtonType.BUTTON;
|
||||
this.descriptionText = descriptionText;
|
||||
this.buttonTextAction = getTitle;
|
||||
this.onPress = onPress;
|
||||
}
|
||||
/**
|
||||
* Puzzle Slider Widget Container
|
||||
*/
|
||||
public PuzzleWidget(int min, int max, Text descriptionText, IntSupplier defaultSliderValue, PuzzleWidget.TextAction setTextAction, PuzzleWidget.ChangeSliderValueAction changeAction) {
|
||||
this.buttonType = ButtonType.SLIDER;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.descriptionText = descriptionText;
|
||||
this.defaultSliderValue = defaultSliderValue;
|
||||
this.buttonTextAction = setTextAction;
|
||||
this.changeSliderValue = changeAction;
|
||||
}
|
||||
/**
|
||||
* Puzzle Text Field Widget Container (WIP - Doesn't work)
|
||||
*/
|
||||
public PuzzleWidget(int min, int max, Text descriptionText, PuzzleWidget.SetTextValueAction setValue, ChangeTextValueAction changeAction) {
|
||||
this.buttonType = ButtonType.TEXT_FIELD;
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.descriptionText = descriptionText;
|
||||
this.setTextValue = setValue;
|
||||
this.changeTextValue = changeAction;
|
||||
}
|
||||
public interface ChangeTextValueAction {
|
||||
void onChange(TextFieldWidget textField);
|
||||
}
|
||||
public interface ChangeSliderValueAction {
|
||||
void onChange(PuzzleSliderWidget slider);
|
||||
}
|
||||
public interface SetTextValueAction {
|
||||
void setTextValue(TextFieldWidget textField);
|
||||
}
|
||||
public interface TextAction {
|
||||
void setTitle(ClickableWidget button);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package net.puzzlemc.models.mixin;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import net.minecraft.client.render.model.json.ModelElement;
|
||||
import net.minecraft.util.JsonHelper;
|
||||
import net.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;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(ModelElement.Deserializer.class)
|
||||
public abstract class MixinModelElementDeserializer {
|
||||
@Shadow protected abstract Vector3f deserializeVec3f(JsonObject object, String name);
|
||||
|
||||
@Inject(at = @At("HEAD"),method = "deserializeRotationAngle", cancellable = true)
|
||||
private void puzzle$deserializeRotationAngle(JsonObject object, CallbackInfoReturnable<Float> cir) {
|
||||
if (PuzzleConfig.unlimitedRotations) {
|
||||
float angle = JsonHelper.getFloat(object, "angle");
|
||||
cir.setReturnValue(angle);
|
||||
}
|
||||
}
|
||||
@Inject(at = @At("HEAD"),method = "deserializeTo", cancellable = true)
|
||||
private void puzzle$deserializeTo(JsonObject object, CallbackInfoReturnable<Vector3f> cir) {
|
||||
if (PuzzleConfig.biggerModels) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@Inject(at = @At("HEAD"),method = "deserializeFrom", cancellable = true)
|
||||
private void puzzle$deserializeFrom(JsonObject object, CallbackInfoReturnable<Vector3f> cir) {
|
||||
if (PuzzleConfig.biggerModels) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
173
common/src/main/java/net/puzzlemc/splashscreen/PuzzleSplashScreen.java
Executable file
173
common/src/main/java/net/puzzlemc/splashscreen/PuzzleSplashScreen.java
Executable file
@@ -0,0 +1,173 @@
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
114
common/src/main/java/net/puzzlemc/splashscreen/mixin/MixinSplashScreen.java
Executable file
114
common/src/main/java/net/puzzlemc/splashscreen/mixin/MixinSplashScreen.java
Executable file
@@ -0,0 +1,114 @@
|
||||
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.*;
|
||||
import net.minecraft.client.texture.NativeImage;
|
||||
import net.minecraft.client.texture.NativeImageBackedTexture;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Util;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.puzzlemc.core.config.PuzzleConfig;
|
||||
import net.puzzlemc.splashscreen.PuzzleSplashScreen;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.*;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.util.function.IntSupplier;
|
||||
|
||||
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 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;
|
||||
}
|
||||
|
||||
@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()) {
|
||||
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(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(DrawContext context, int mouseX, int mouseY, float delta, CallbackInfo ci) {
|
||||
if (PuzzleConfig.resourcepackSplashScreen) {
|
||||
if (PuzzleConfig.disableBlend) RenderSystem.defaultBlendFunc();
|
||||
else if (PuzzleConfig.customBlendFunction.size() == 4) 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)));
|
||||
}
|
||||
}
|
||||
@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.enableBlend();
|
||||
RenderSystem.blendEquation(32774);
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.setShader(GameRenderer::getPositionTexProgram);
|
||||
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, s);
|
||||
context.drawTexture(BACKGROUND, 0, 0, 1, 0, 0, width, height, width, height);
|
||||
RenderSystem.defaultBlendFunc();
|
||||
RenderSystem.disableBlend();
|
||||
}
|
||||
}
|
||||
@Inject(method = "renderProgressBar", at = @At("HEAD"))
|
||||
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);
|
||||
RenderSystem.disableBlend();
|
||||
context.fill(minX, minY, maxX, maxY, withAlpha(PuzzleConfig.progressBarBackgroundColor, m));
|
||||
}
|
||||
|
||||
@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/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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user