diff --git a/build.gradle b/build.gradle index a943b5c..069cf8d 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ plugins { id 'fabric-loom' version "${loom_version}" + id 'io.github.juuxel.loom-vineflower' version "${loom_vineflower_version}" id 'maven-publish' } @@ -10,6 +11,14 @@ archivesBaseName = project.archives_base_name version = project.mod_version + '+' + project.mod_minecraft_version + getExtraBuildMetadata() group = project.maven_group +String getExtraBuildMetadata() { + String buildNumber = System.getenv('GITHUB_RUN_NUMBER') + if (buildNumber != null) { + return ".build.${buildNumber}" + } + return '' +} + repositories { maven { name 'TerraformersMC' @@ -20,6 +29,7 @@ repositories { url 'https://api.modrinth.com/maven' } maven { + name "VRAM" url 'https://maven.vram.io' } maven { @@ -37,22 +47,14 @@ dependencies { // Fabric API modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - modImplementation('com.terraformersmc:modmenu:5.0.2') { + modImplementation("com.terraformersmc:modmenu:${modmenu_version}") { exclude group: 'net.fabricmc.fabric-api' } - modCompileOnly 'maven.modrinth:sodium:mc1.19.3-0.4.9' - modCompileOnly 'maven.modrinth:indium:1.0.12+mc1.19.3' - modCompileOnly 'io.vram:frex-fabric-mc119:6.1.305' - modCompileOnly 'io.vram:canvas-fabric-mc119:1.0.2503' -} - -String getExtraBuildMetadata() { - String buildNumber = System.getenv('GITHUB_RUN_NUMBER') - if (buildNumber != null) { - return "-build.${buildNumber}" - } - return '' + modCompileOnly "maven.modrinth:sodium:${sodium_version}" + modCompileOnly "maven.modrinth:indium:${indium_version}" + modCompileOnly "io.vram:frex-fabric:${frex_version}" + modCompileOnly "io.vram:canvas-fabric:${canvas_version}" } processResources { diff --git a/gradle.properties b/gradle.properties index dc03223..55f1415 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,16 +2,22 @@ org.gradle.jvmargs = -Xmx1G # Fabric Properties - loom_version = 1.1-SNAPSHOT - minecraft_version = 1.19.3 - yarn_mappings = 1.19.3+build.5 - loader_version = 0.14.13 +loom_version = 1.3.8 +loom_vineflower_version = 1.11.0 +minecraft_version = 1.19.3 +yarn_mappings = 1.19.3+build.5 +loader_version = 0.14.21 # Mod Properties - mod_version = 3.0.0-beta.2 - mod_minecraft_version = 1.19.3 - maven_group = me.pepperbell - archives_base_name = continuity +mod_version = 3.0.0-beta.3 +mod_minecraft_version = 1.19.3 +maven_group = me.pepperbell +archives_base_name = continuity # Dependencies - fabric_version = 0.71.0+1.19.3 +fabric_version = 0.76.1+1.19.3 +modmenu_version = 5.1.0 +sodium_version = mc1.19.3-0.4.9 +indium_version = 1.0.14+mc1.19.3 +frex_version = 19.3.324 +canvas_version = 19.3.2607 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 943f0cb..033e24c 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 5083229..9f4197d 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 65dcd68..fcb6fca 100755 --- a/gradlew +++ b/gradlew @@ -85,9 +85,6 @@ done APP_BASE_NAME=${0##*/} APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -133,10 +130,13 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. @@ -144,7 +144,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -197,6 +197,10 @@ if "$cygwin" || "$msys" ; then done fi + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in diff --git a/src/main/java/me/pepperbell/continuity/client/config/ContinuityConfig.java b/src/main/java/me/pepperbell/continuity/client/config/ContinuityConfig.java index ff9f185..f7a6ac6 100644 --- a/src/main/java/me/pepperbell/continuity/client/config/ContinuityConfig.java +++ b/src/main/java/me/pepperbell/continuity/client/config/ContinuityConfig.java @@ -21,7 +21,6 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectMap; import it.unimi.dsi.fastutil.objects.ObjectBidirectionalIterator; import net.fabricmc.loader.api.FabricLoader; -import net.minecraft.client.MinecraftClient; public class ContinuityConfig { protected static final Logger LOGGER = LoggerFactory.getLogger("Continuity Config"); @@ -64,10 +63,6 @@ public void save() { } } - public void onChange() { - MinecraftClient.getInstance().worldRenderer.reload(); - } - protected void fromJson(JsonElement json) throws JsonParseException { if (json.isJsonObject()) { JsonObject object = json.getAsJsonObject(); diff --git a/src/main/java/me/pepperbell/continuity/client/config/ContinuityConfigScreen.java b/src/main/java/me/pepperbell/continuity/client/config/ContinuityConfigScreen.java index fb7d0cc..0f96c6b 100644 --- a/src/main/java/me/pepperbell/continuity/client/config/ContinuityConfigScreen.java +++ b/src/main/java/me/pepperbell/continuity/client/config/ContinuityConfigScreen.java @@ -1,5 +1,11 @@ package me.pepperbell.continuity.client.config; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.tooltip.Tooltip; import net.minecraft.client.gui.widget.ButtonWidget; @@ -11,6 +17,8 @@ public class ContinuityConfigScreen extends Screen { private final Screen parent; private final ContinuityConfig config; + private List> values; + public ContinuityConfigScreen(Screen parent, ContinuityConfig config) { super(Text.translatable(getTranslationKey("title"))); this.parent = parent; @@ -19,18 +27,31 @@ public ContinuityConfigScreen(Screen parent, ContinuityConfig config) { @Override protected void init() { - addDrawableChild(startBooleanOptionButton(config.connectedTextures) + Value connectedTextures = Value.of(config.connectedTextures, Value.Flag.RELOAD_WORLD_RENDERER); + Value emissiveTextures = Value.of(config.emissiveTextures, Value.Flag.RELOAD_WORLD_RENDERER); + Value customBlockLayers = Value.of(config.customBlockLayers, Value.Flag.RELOAD_WORLD_RENDERER); + + values = List.of(connectedTextures, emissiveTextures, customBlockLayers); + + addDrawableChild(startBooleanValueButton(connectedTextures) .dimensions(width / 2 - 100 - 110, height / 2 - 10 - 12, 200, 20) .build()); - addDrawableChild(startBooleanOptionButton(config.emissiveTextures) + addDrawableChild(startBooleanValueButton(emissiveTextures) .dimensions(width / 2 - 100 + 110, height / 2 - 10 - 12, 200, 20) .build()); - addDrawableChild(startBooleanOptionButton(config.customBlockLayers) + addDrawableChild(startBooleanValueButton(customBlockLayers) .dimensions(width / 2 - 100 - 110, height / 2 - 10 + 12, 200, 20) .build()); - addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, button -> close()) - .dimensions(width / 2 - 100, height - 40, 200, 20) + addDrawableChild(ButtonWidget.builder(ScreenTexts.DONE, + button -> { + saveValues(); + close(); + }) + .dimensions(width / 2 - 75 - 79, height - 40, 150, 20) + .build()); + addDrawableChild(ButtonWidget.builder(ScreenTexts.CANCEL, button -> close()) + .dimensions(width / 2 - 75 + 79, height - 40, 150, 20) .build()); } @@ -46,10 +67,21 @@ public void close() { client.setScreen(parent); } - @Override - public void removed() { + private void saveValues() { + EnumSet flags = EnumSet.noneOf(Value.Flag.class); + + for (Value value : values) { + if (value.isChanged()) { + value.saveToOption(); + flags.addAll(value.getFlags()); + } + } + config.save(); - config.onChange(); + + for (Value.Flag flag : flags) { + flag.onSave(); + } } private static String getTranslationKey(String optionKey) { @@ -60,16 +92,76 @@ private static String getTooltipKey(String translationKey) { return translationKey + ".tooltip"; } - private ButtonWidget.Builder startBooleanOptionButton(Option option) { - String translationKey = getTranslationKey(option.getKey()); + private ButtonWidget.Builder startBooleanValueButton(Value value) { + String translationKey = getTranslationKey(value.getOption().getKey()); Text text = Text.translatable(translationKey); Text tooltipText = Text.translatable(getTooltipKey(translationKey)); - return ButtonWidget.builder(ScreenTexts.composeToggleText(text, option.get()), + + return ButtonWidget.builder(ScreenTexts.composeGenericOptionText(text, ScreenTexts.onOrOff(value.get())), button -> { - boolean newValue = !option.get(); - button.setMessage(ScreenTexts.composeToggleText(text, newValue)); - option.set(newValue); + boolean newValue = !value.get(); + value.set(newValue); + Text valueText = ScreenTexts.onOrOff(newValue); + if (value.isChanged()) { + valueText = valueText.copy().styled(style -> style.withBold(true)); + } + button.setMessage(ScreenTexts.composeGenericOptionText(text, valueText)); }) .tooltip(Tooltip.of(tooltipText)); } + + private static class Value { + private final Option option; + private final Set flags; + private final T originalValue; + private T value; + + public Value(Option option, Set flags) { + this.option = option; + this.flags = flags; + originalValue = this.option.get(); + value = originalValue; + } + + public static Value of(Option option, Flag... flags) { + EnumSet flagSet = EnumSet.noneOf(Flag.class); + Collections.addAll(flagSet, flags); + return new Value<>(option, flagSet); + } + + public Option getOption() { + return option; + } + + public Set getFlags() { + return flags; + } + + public T get() { + return value; + } + + public void set(T value) { + this.value = value; + } + + public boolean isChanged() { + return !value.equals(originalValue); + } + + public void saveToOption() { + option.set(value); + } + + public enum Flag { + RELOAD_WORLD_RENDERER { + @Override + public void onSave() { + MinecraftClient.getInstance().worldRenderer.reload(); + } + }; + + public abstract void onSave(); + } + } } diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/RenderLayersMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/RenderLayersMixin.java index 4eab597..96762c4 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/RenderLayersMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/RenderLayersMixin.java @@ -22,4 +22,14 @@ public class RenderLayersMixin { } } } + + @Inject(method = "getMovingBlockLayer(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/RenderLayer;", at = @At("HEAD"), cancellable = true) + private static void continuity$onHeadGetMovingBlockLayer(BlockState state, CallbackInfoReturnable cir) { + if (ContinuityConfig.INSTANCE.customBlockLayers.get()) { + RenderLayer layer = CustomBlockLayers.getLayer(state); + if (layer != null) { + cir.setReturnValue(layer == RenderLayer.getTranslucent() ? RenderLayer.getTranslucentMovingBlock() : layer); + } + } + } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/CompactCTMQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/CompactCTMQuadProcessor.java index 78c601d..c22b462 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/CompactCTMQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/CompactCTMQuadProcessor.java @@ -458,10 +458,10 @@ protected static boolean shouldSplitUV(int signumA, int signumB) { protected int getSpriteIndex(int quadrantIndex, int connections) { int index1 = quadrantIndex; int index2 = (quadrantIndex + 3) % 4; - boolean connected1 = ((connections >> index1 * 2) & 1) == 1; - boolean connected2 = ((connections >> index2 * 2) & 1) == 1; + boolean connected1 = ((connections >>> index1 * 2) & 1) == 1; + boolean connected2 = ((connections >>> index2 * 2) & 1) == 1; if (connected1 && connected2) { - if (((connections >> (index2 * 2 + 1)) & 1) == 1) { + if (((connections >>> (index2 * 2 + 1)) & 1) == 1) { return 1; } return 4; diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/CTMSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/CTMSpriteProvider.java index aeb5b02..849ab22 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/CTMSpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/CTMSpriteProvider.java @@ -73,7 +73,7 @@ public static int getConnections(ConnectionPredicate connectionPredicate, boolea for (int i = 0; i < 4; i++) { int index1 = i; int index2 = (i + 1) % 4; - if (((connections >> index1 * 2) & 1) == 1 && ((connections >> index2 * 2) & 1) == 1) { + if (((connections >>> index1 * 2) & 1) == 1 && ((connections >>> index2 * 2) & 1) == 1) { mutablePos.set(pos, directions[index1]).move(directions[index2]); if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, face, quadSprite, innerSeams)) { connections |= 1 << (i * 2 + 1); diff --git a/src/main/java/me/pepperbell/continuity/client/properties/BaseCTMProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/BaseCTMProperties.java index 632f368..f5e73c0 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/BaseCTMProperties.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/BaseCTMProperties.java @@ -222,21 +222,35 @@ protected void parseTiles() { if (!path.endsWith(".png")) { path += ".png"; } - if (path.startsWith("./")) { - path = basePath + path.substring(2); - } else if (path.startsWith("~/")) { - path = "optifine/" + path.substring(2); - } else if (path.startsWith("/")) { - path = "optifine/" + path.substring(1); - } else if (!path.startsWith("textures/") && !path.startsWith("optifine/")) { - path = basePath + path; - } + if (namespace == null) { + if (path.startsWith("assets/minecraft/")) { + path = path.substring(17); + } else if (path.startsWith("./")) { + path = basePath + path.substring(2); + } else if (path.startsWith("~/")) { + path = "optifine/" + path.substring(2); + } else if (path.startsWith("/")) { + path = "optifine/" + path.substring(1); + } + + if (!path.startsWith("textures/") && !path.startsWith("optifine/")) { + path = basePath + path; + } + if (path.startsWith("optifine/")) { namespace = id.getNamespace(); - } else { - namespace = Identifier.DEFAULT_NAMESPACE; } + } else { + if (!path.contains("/")) { + path = "textures/block/" + path; + } else if (!path.startsWith("textures/") && !path.startsWith("optifine/")) { + path = "textures/" + path; + } + } + + if (namespace == null) { + namespace = Identifier.DEFAULT_NAMESPACE; } try { diff --git a/src/main/java/me/pepperbell/continuity/client/properties/PropertiesParsingHelper.java b/src/main/java/me/pepperbell/continuity/client/properties/PropertiesParsingHelper.java index 870e60a..67b20d0 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/PropertiesParsingHelper.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/PropertiesParsingHelper.java @@ -58,15 +58,19 @@ public static ImmutableSet parseMatchTiles(Properties properties, St if (path.endsWith(".png")) { path = path.substring(0, path.length() - 4); } - if (path.startsWith("./")) { - path = basePath + path.substring(2); - } else if (path.startsWith("~/")) { - path = "optifine/" + path.substring(2); - } else if (path.startsWith("/")) { - path = "optifine/" + path.substring(1); - } else if (!path.contains("/")) { - path = "textures/block/" + path; + + if (namespace == null) { + if (path.startsWith("assets/minecraft/")) { + path = path.substring(17); + } else if (path.startsWith("./")) { + path = basePath + path.substring(2); + } else if (path.startsWith("~/")) { + path = "optifine/" + path.substring(2); + } else if (path.startsWith("/")) { + path = "optifine/" + path.substring(1); + } } + if (path.startsWith("textures/")) { path = path.substring(9); } else if (path.startsWith("optifine/")) { @@ -77,7 +81,10 @@ public static ImmutableSet parseMatchTiles(Properties properties, St if (namespace == null) { namespace = fileLocation.getNamespace(); } + } else if (!path.contains("/")) { + path = "block/" + path; } + if (namespace == null) { namespace = Identifier.DEFAULT_NAMESPACE; } diff --git a/src/main/java/me/pepperbell/continuity/client/util/MathUtil.java b/src/main/java/me/pepperbell/continuity/client/util/MathUtil.java index 65ec026..f9caac2 100644 --- a/src/main/java/me/pepperbell/continuity/client/util/MathUtil.java +++ b/src/main/java/me/pepperbell/continuity/client/util/MathUtil.java @@ -21,15 +21,15 @@ public static int lerp(float delta, int start, int end) { } public static int lerpColor(float delta, int colorA, int colorB) { - return (lerp(delta, colorA >> 24 & 0xFF, colorB >> 24 & 0xFF) << 24) - | (lerp(delta, colorA >> 16 & 0xFF, colorB >> 16 & 0xFF) << 16) - | (lerp(delta, colorA >> 8 & 0xFF, colorB >> 8 & 0xFF) << 8) + return (lerp(delta, colorA >>> 24 & 0xFF, colorB >>> 24 & 0xFF) << 24) + | (lerp(delta, colorA >>> 16 & 0xFF, colorB >>> 16 & 0xFF) << 16) + | (lerp(delta, colorA >>> 8 & 0xFF, colorB >>> 8 & 0xFF) << 8) | (lerp(delta, colorA & 0xFF, colorB & 0xFF)); } public static int lerpLight(float delta, int lightA, int lightB) { - return (lerp(delta, lightA >> 20 & 0xF, lightB >> 20 & 0xF) << 20) - | (lerp(delta, lightA >> 4 & 0xF, lightB >> 4 & 0xF) << 4); + return (lerp(delta, lightA >>> 20 & 0xF, lightB >>> 20 & 0xF) << 20) + | (lerp(delta, lightA >>> 4 & 0xF, lightB >>> 4 & 0xF) << 4); } // Borrowed from SplittableRandom diff --git a/src/main/resources/assets/continuity/lang/en_us.json b/src/main/resources/assets/continuity/lang/en_us.json index c23a925..42502b4 100644 --- a/src/main/resources/assets/continuity/lang/en_us.json +++ b/src/main/resources/assets/continuity/lang/en_us.json @@ -7,7 +7,7 @@ "options.continuity.custom_block_layers": "Custom Block Layers", "options.continuity.custom_block_layers.tooltip": "Enable or disable custom block layers.", "resourcePack.continuity.default.name": "Default Connected Textures", - "resourcePack.continuity.default.description": "Bookshelves, sandstone, and glass", + "resourcePack.continuity.default.description": "Glass, sandstone, bookshelves", "resourcePack.continuity.glass_pane_culling_fix.name": "Glass Pane Culling Fix", - "resourcePack.continuity.glass_pane_culling_fix.description": "Fixes top and bottom face culling" + "resourcePack.continuity.glass_pane_culling_fix.description": "Cull faces between glass panes" } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 62538fe..0faa08e 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -6,10 +6,10 @@ "name": "Continuity", "description": "Continuity is a Fabric mod built around modern APIs to allow for the most efficient connected textures experience possible. It is designed to provide full Optifine parity for all resource packs that use the Optifine CTM format. Continuity also supports Optifine-format emissive textures for block and item models.", "authors": [ - "Pepper_Bell" + "PepperCode1" ], "contact": { - "homepage": "https://www.curseforge.com/minecraft/mc-mods/continuity", + "homepage": "https://modrinth.com/mod/continuity", "issues": "https://github.com/PepperCode1/Continuity/issues", "sources": "https://github.com/PepperCode1/Continuity" }, @@ -31,10 +31,8 @@ ], "depends": { - "fabricloader": ">=0.11.7", - "fabric": ">=0.58.0", - "minecraft": ">=1.19.3", - "java": ">=17" + "minecraft": "1.19.3", + "fabric": ">=0.76.1" }, "custom": { diff --git a/src/main/resources/resourcepacks/default/pack.png b/src/main/resources/resourcepacks/default/pack.png index bce5605..6996d90 100644 Binary files a/src/main/resources/resourcepacks/default/pack.png and b/src/main/resources/resourcepacks/default/pack.png differ diff --git a/src/main/resources/resourcepacks/glass_pane_culling_fix/pack.png b/src/main/resources/resourcepacks/glass_pane_culling_fix/pack.png new file mode 100644 index 0000000..19fe45c Binary files /dev/null and b/src/main/resources/resourcepacks/glass_pane_culling_fix/pack.png differ