diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c281b75c..94a463c7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,11 +6,11 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Validate Gradle wrapper - uses: gradle/wrapper-validation-action@v1 + uses: gradle/wrapper-validation-action@v2 - name: Set up JDK 17 - uses: actions/setup-java@v2 + uses: actions/setup-java@v4 with: distribution: temurin java-version: 17 @@ -18,7 +18,7 @@ jobs: - name: Build artifacts run: ./gradlew build --stacktrace - name: Upload artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: build-artifacts path: build/libs/ diff --git a/build.gradle b/build.gradle index 731b75ba..fa1972b7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,17 +1,16 @@ plugins { id 'fabric-loom' version "${loom_version}" - id 'io.github.juuxel.loom-vineflower' version "${loom_vineflower_version}" id 'maven-publish' } -sourceCompatibility = JavaVersion.VERSION_17 -targetCompatibility = JavaVersion.VERSION_17 - -archivesBaseName = project.archives_base_name version = project.mod_version + '+' + project.mod_minecraft_version + getExtraBuildMetadata() group = project.maven_group -String getExtraBuildMetadata() { +base { + archivesName = project.archives_base_name +} + +static String getExtraBuildMetadata() { String buildNumber = System.getenv('GITHUB_RUN_NUMBER') if (buildNumber != null) { return ".build.${buildNumber}" @@ -66,8 +65,7 @@ processResources { } tasks.withType(JavaCompile).configureEach { - // Minecraft 1.18 (1.18-pre2) upwards uses Java 17. - it.options.release.set(17) + it.options.release = 17 } java { @@ -75,18 +73,22 @@ java { // if it is present. // If you remove this line, sources will not be generated. withSourcesJar() + + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } jar { from('LICENSE') { - rename { "${it}_${project.archivesBaseName}" } + rename { "${it}_${project.base.archivesName.get()}" } } } // configure the maven publication publishing { publications { - mavenJava(MavenPublication) { + create('mavenJava', MavenPublication) { + artifactId = project.archives_base_name from components.java } } diff --git a/gradle.properties b/gradle.properties index 55f14158..77929926 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,15 +1,15 @@ # Done to increase the memory available to Gradle. org.gradle.jvmargs = -Xmx1G +org.gradle.parallel = true # Fabric Properties -loom_version = 1.3.8 -loom_vineflower_version = 1.11.0 +loom_version = 1.6.11 minecraft_version = 1.19.3 yarn_mappings = 1.19.3+build.5 -loader_version = 0.14.21 +loader_version = 0.15.10 # Mod Properties -mod_version = 3.0.0-beta.3 +mod_version = 3.0.0-beta.5 mod_minecraft_version = 1.19.3 maven_group = me.pepperbell archives_base_name = continuity diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 033e24c4..e6441136 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 9f4197d5..b82aa23a 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index fcb6fca1..1aa94a42 100755 --- a/gradlew +++ b/gradlew @@ -83,7 +83,8 @@ done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -144,7 +145,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=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -152,7 +153,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=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -201,11 +202,11 @@ 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 -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ diff --git a/gradlew.bat b/gradlew.bat index 93e3f59f..25da30db 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -43,11 +43,11 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail @@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 goto fail diff --git a/src/main/java/me/pepperbell/continuity/api/client/CTMLoader.java b/src/main/java/me/pepperbell/continuity/api/client/CTMLoader.java deleted file mode 100644 index b0f18e1c..00000000 --- a/src/main/java/me/pepperbell/continuity/api/client/CTMLoader.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.pepperbell.continuity.api.client; - -public interface CTMLoader { - CTMPropertiesFactory getPropertiesFactory(); - - QuadProcessorFactory getProcessorFactory(); - - CachingPredicatesFactory getPredicatesFactory(); -} diff --git a/src/main/java/me/pepperbell/continuity/api/client/CTMLoaderRegistry.java b/src/main/java/me/pepperbell/continuity/api/client/CTMLoaderRegistry.java deleted file mode 100644 index 209f732e..00000000 --- a/src/main/java/me/pepperbell/continuity/api/client/CTMLoaderRegistry.java +++ /dev/null @@ -1,18 +0,0 @@ -package me.pepperbell.continuity.api.client; - -import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.Nullable; - -import me.pepperbell.continuity.impl.client.CTMLoaderRegistryImpl; - -@ApiStatus.NonExtendable -public interface CTMLoaderRegistry { - static CTMLoaderRegistry get() { - return CTMLoaderRegistryImpl.INSTANCE; - } - - void registerLoader(String method, CTMLoader loader); - - @Nullable - CTMLoader getLoader(String method); -} diff --git a/src/main/java/me/pepperbell/continuity/api/client/CTMProperties.java b/src/main/java/me/pepperbell/continuity/api/client/CTMProperties.java deleted file mode 100644 index 6c979f90..00000000 --- a/src/main/java/me/pepperbell/continuity/api/client/CTMProperties.java +++ /dev/null @@ -1,9 +0,0 @@ -package me.pepperbell.continuity.api.client; - -import java.util.Collection; - -import net.minecraft.client.util.SpriteIdentifier; - -public interface CTMProperties extends Comparable { - Collection getTextureDependencies(); -} diff --git a/src/main/java/me/pepperbell/continuity/api/client/CTMPropertiesFactory.java b/src/main/java/me/pepperbell/continuity/api/client/CTMPropertiesFactory.java deleted file mode 100644 index 86be53f3..00000000 --- a/src/main/java/me/pepperbell/continuity/api/client/CTMPropertiesFactory.java +++ /dev/null @@ -1,14 +0,0 @@ -package me.pepperbell.continuity.api.client; - -import java.util.Properties; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.resource.ResourceManager; -import net.minecraft.resource.ResourcePack; -import net.minecraft.util.Identifier; - -public interface CTMPropertiesFactory { - @Nullable - T createProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method); -} diff --git a/src/main/java/me/pepperbell/continuity/api/client/CachingPredicates.java b/src/main/java/me/pepperbell/continuity/api/client/CachingPredicates.java index 7a7e6acf..95259ae1 100644 --- a/src/main/java/me/pepperbell/continuity/api/client/CachingPredicates.java +++ b/src/main/java/me/pepperbell/continuity/api/client/CachingPredicates.java @@ -1,7 +1,10 @@ package me.pepperbell.continuity.api.client; +import java.util.function.Function; + import net.minecraft.block.BlockState; import net.minecraft.client.texture.Sprite; +import net.minecraft.client.util.SpriteIdentifier; public interface CachingPredicates { boolean affectsSprites(); @@ -13,4 +16,8 @@ public interface CachingPredicates { boolean affectsBlockState(BlockState state); boolean isValidForMultipass(); + + interface Factory { + CachingPredicates createPredicates(T properties, Function textureGetter); + } } diff --git a/src/main/java/me/pepperbell/continuity/api/client/CachingPredicatesFactory.java b/src/main/java/me/pepperbell/continuity/api/client/CachingPredicatesFactory.java deleted file mode 100644 index 99cf28a9..00000000 --- a/src/main/java/me/pepperbell/continuity/api/client/CachingPredicatesFactory.java +++ /dev/null @@ -1,10 +0,0 @@ -package me.pepperbell.continuity.api.client; - -import java.util.function.Function; - -import net.minecraft.client.texture.Sprite; -import net.minecraft.client.util.SpriteIdentifier; - -public interface CachingPredicatesFactory { - CachingPredicates createPredicates(T properties, Function textureGetter); -} diff --git a/src/main/java/me/pepperbell/continuity/api/client/CtmLoader.java b/src/main/java/me/pepperbell/continuity/api/client/CtmLoader.java new file mode 100644 index 00000000..c10a5719 --- /dev/null +++ b/src/main/java/me/pepperbell/continuity/api/client/CtmLoader.java @@ -0,0 +1,9 @@ +package me.pepperbell.continuity.api.client; + +public interface CtmLoader { + CtmProperties.Factory getPropertiesFactory(); + + QuadProcessor.Factory getProcessorFactory(); + + CachingPredicates.Factory getPredicatesFactory(); +} diff --git a/src/main/java/me/pepperbell/continuity/api/client/CtmLoaderRegistry.java b/src/main/java/me/pepperbell/continuity/api/client/CtmLoaderRegistry.java new file mode 100644 index 00000000..adca6666 --- /dev/null +++ b/src/main/java/me/pepperbell/continuity/api/client/CtmLoaderRegistry.java @@ -0,0 +1,18 @@ +package me.pepperbell.continuity.api.client; + +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Nullable; + +import me.pepperbell.continuity.impl.client.CtmLoaderRegistryImpl; + +@ApiStatus.NonExtendable +public interface CtmLoaderRegistry { + static CtmLoaderRegistry get() { + return CtmLoaderRegistryImpl.INSTANCE; + } + + void registerLoader(String method, CtmLoader loader); + + @Nullable + CtmLoader getLoader(String method); +} diff --git a/src/main/java/me/pepperbell/continuity/api/client/CtmProperties.java b/src/main/java/me/pepperbell/continuity/api/client/CtmProperties.java new file mode 100644 index 00000000..a68f0f8c --- /dev/null +++ b/src/main/java/me/pepperbell/continuity/api/client/CtmProperties.java @@ -0,0 +1,20 @@ +package me.pepperbell.continuity.api.client; + +import java.util.Collection; +import java.util.Properties; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.client.util.SpriteIdentifier; +import net.minecraft.resource.ResourceManager; +import net.minecraft.resource.ResourcePack; +import net.minecraft.util.Identifier; + +public interface CtmProperties extends Comparable { + Collection getTextureDependencies(); + + interface Factory { + @Nullable + T createProperties(Properties properties, Identifier resourceId, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method); + } +} diff --git a/src/main/java/me/pepperbell/continuity/api/client/QuadProcessor.java b/src/main/java/me/pepperbell/continuity/api/client/QuadProcessor.java index 9e88a643..06f3e4df 100644 --- a/src/main/java/me/pepperbell/continuity/api/client/QuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/api/client/QuadProcessor.java @@ -1,6 +1,7 @@ package me.pepperbell.continuity.api.client; import java.util.function.Consumer; +import java.util.function.Function; import java.util.function.Supplier; import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; @@ -8,6 +9,7 @@ import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.minecraft.block.BlockState; import net.minecraft.client.texture.Sprite; +import net.minecraft.client.util.SpriteIdentifier; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; @@ -26,9 +28,13 @@ interface ProcessingContext extends ProcessingDataProvider { } enum ProcessingResult { - CONTINUE, + NEXT_PROCESSOR, + NEXT_PASS, STOP, - ABORT_AND_RENDER_QUAD, - ABORT_AND_CANCEL_QUAD; + DISCARD; + } + + interface Factory { + QuadProcessor createProcessor(T properties, Function textureGetter); } } diff --git a/src/main/java/me/pepperbell/continuity/api/client/QuadProcessorFactory.java b/src/main/java/me/pepperbell/continuity/api/client/QuadProcessorFactory.java deleted file mode 100644 index 0e5dd1f7..00000000 --- a/src/main/java/me/pepperbell/continuity/api/client/QuadProcessorFactory.java +++ /dev/null @@ -1,10 +0,0 @@ -package me.pepperbell.continuity.api.client; - -import java.util.function.Function; - -import net.minecraft.client.texture.Sprite; -import net.minecraft.client.util.SpriteIdentifier; - -public interface QuadProcessorFactory { - QuadProcessor createProcessor(T properties, Function textureGetter); -} diff --git a/src/main/java/me/pepperbell/continuity/client/ContinuityClient.java b/src/main/java/me/pepperbell/continuity/client/ContinuityClient.java index 14c01dca..91f65c00 100644 --- a/src/main/java/me/pepperbell/continuity/client/ContinuityClient.java +++ b/src/main/java/me/pepperbell/continuity/client/ContinuityClient.java @@ -3,39 +3,39 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import me.pepperbell.continuity.api.client.CTMLoader; -import me.pepperbell.continuity.api.client.CTMLoaderRegistry; -import me.pepperbell.continuity.api.client.CTMProperties; -import me.pepperbell.continuity.api.client.CTMPropertiesFactory; -import me.pepperbell.continuity.api.client.CachingPredicatesFactory; -import me.pepperbell.continuity.api.client.QuadProcessorFactory; +import me.pepperbell.continuity.api.client.CachingPredicates; +import me.pepperbell.continuity.api.client.CtmLoader; +import me.pepperbell.continuity.api.client.CtmLoaderRegistry; +import me.pepperbell.continuity.api.client.CtmProperties; +import me.pepperbell.continuity.api.client.QuadProcessor; import me.pepperbell.continuity.client.processor.BaseCachingPredicates; -import me.pepperbell.continuity.client.processor.CompactCTMQuadProcessor; -import me.pepperbell.continuity.client.processor.HorizontalQuadProcessor; -import me.pepperbell.continuity.client.processor.HorizontalVerticalQuadProcessor; +import me.pepperbell.continuity.client.processor.CompactCtmQuadProcessor; import me.pepperbell.continuity.client.processor.ProcessingDataKeys; import me.pepperbell.continuity.client.processor.TopQuadProcessor; -import me.pepperbell.continuity.client.processor.VerticalHorizontalQuadProcessor; -import me.pepperbell.continuity.client.processor.VerticalQuadProcessor; import me.pepperbell.continuity.client.processor.overlay.SimpleOverlayQuadProcessor; import me.pepperbell.continuity.client.processor.overlay.StandardOverlayQuadProcessor; -import me.pepperbell.continuity.client.processor.simple.CTMSpriteProvider; +import me.pepperbell.continuity.client.processor.simple.CtmSpriteProvider; import me.pepperbell.continuity.client.processor.simple.FixedSpriteProvider; +import me.pepperbell.continuity.client.processor.simple.HorizontalSpriteProvider; +import me.pepperbell.continuity.client.processor.simple.HorizontalVerticalSpriteProvider; import me.pepperbell.continuity.client.processor.simple.RandomSpriteProvider; import me.pepperbell.continuity.client.processor.simple.RepeatSpriteProvider; import me.pepperbell.continuity.client.processor.simple.SimpleQuadProcessor; -import me.pepperbell.continuity.client.properties.BaseCTMProperties; -import me.pepperbell.continuity.client.properties.CompactConnectingCTMProperties; +import me.pepperbell.continuity.client.processor.simple.VerticalHorizontalSpriteProvider; +import me.pepperbell.continuity.client.processor.simple.VerticalSpriteProvider; +import me.pepperbell.continuity.client.properties.BaseCtmProperties; +import me.pepperbell.continuity.client.properties.CompactConnectingCtmProperties; +import me.pepperbell.continuity.client.properties.ConnectingCtmProperties; +import me.pepperbell.continuity.client.properties.OrientedConnectingCtmProperties; import me.pepperbell.continuity.client.properties.PropertiesParsingHelper; -import me.pepperbell.continuity.client.properties.RandomCTMProperties; -import me.pepperbell.continuity.client.properties.RepeatCTMProperties; -import me.pepperbell.continuity.client.properties.StandardConnectingCTMProperties; +import me.pepperbell.continuity.client.properties.RandomCtmProperties; +import me.pepperbell.continuity.client.properties.RepeatCtmProperties; import me.pepperbell.continuity.client.properties.TileAmountValidator; -import me.pepperbell.continuity.client.properties.overlay.BaseOverlayCTMProperties; -import me.pepperbell.continuity.client.properties.overlay.RandomOverlayCTMProperties; -import me.pepperbell.continuity.client.properties.overlay.RepeatOverlayCTMProperties; -import me.pepperbell.continuity.client.properties.overlay.StandardConnectingOverlayCTMProperties; -import me.pepperbell.continuity.client.properties.overlay.StandardOverlayCTMProperties; +import me.pepperbell.continuity.client.properties.overlay.BaseOverlayCtmProperties; +import me.pepperbell.continuity.client.properties.overlay.OrientedConnectingOverlayCtmProperties; +import me.pepperbell.continuity.client.properties.overlay.RandomOverlayCtmProperties; +import me.pepperbell.continuity.client.properties.overlay.RepeatOverlayCtmProperties; +import me.pepperbell.continuity.client.properties.overlay.StandardOverlayCtmProperties; import me.pepperbell.continuity.client.resource.CustomBlockLayers; import me.pepperbell.continuity.client.util.RenderUtil; import me.pepperbell.continuity.client.util.biome.BiomeHolderManager; @@ -67,184 +67,203 @@ public void onInitializeClient() { ResourceManagerHelper.registerBuiltinResourcePack(asId("glass_pane_culling_fix"), container, Text.translatable("resourcePack.continuity.glass_pane_culling_fix.name"), ResourcePackActivationType.NORMAL); }); - // Regular methods + CtmLoaderRegistry registry = CtmLoaderRegistry.get(); + CtmLoader loader; - /* - "ctm" "glass" - "ctm_compact" - "horizontal" "bookshelf" - "vertical" - "horizontal+vertical" "h+v" - "vertical+horizontal" "v+h" - "top" - "random" - "repeat" - "fixed" - */ - - CTMLoaderRegistry registry = CTMLoaderRegistry.get(); - CTMLoader loader; + // Standard simple methods loader = createLoader( - StandardConnectingCTMProperties::new, + OrientedConnectingCtmProperties::new, new TileAmountValidator.AtLeast<>(47), - new SimpleQuadProcessor.Factory<>(new CTMSpriteProvider.Factory(true)) + new SimpleQuadProcessor.Factory<>(new CtmSpriteProvider.Factory()) ); registry.registerLoader("ctm", loader); registry.registerLoader("glass", loader); loader = createLoader( - CompactConnectingCTMProperties::new, + CompactConnectingCtmProperties::new, new TileAmountValidator.AtLeast<>(5), - new CompactCTMQuadProcessor.Factory(), + new CompactCtmQuadProcessor.Factory(), false ); registry.registerLoader("ctm_compact", loader); loader = createLoader( - StandardConnectingCTMProperties::new, + OrientedConnectingCtmProperties::new, new TileAmountValidator.Exactly<>(4), - new HorizontalQuadProcessor.Factory() + new SimpleQuadProcessor.Factory<>(new HorizontalSpriteProvider.Factory()) ); registry.registerLoader("horizontal", loader); registry.registerLoader("bookshelf", loader); loader = createLoader( - StandardConnectingCTMProperties::new, + OrientedConnectingCtmProperties::new, new TileAmountValidator.Exactly<>(4), - new VerticalQuadProcessor.Factory() + new SimpleQuadProcessor.Factory<>(new VerticalSpriteProvider.Factory()) ); registry.registerLoader("vertical", loader); loader = createLoader( - StandardConnectingCTMProperties::new, + OrientedConnectingCtmProperties::new, new TileAmountValidator.Exactly<>(7), - new HorizontalVerticalQuadProcessor.Factory() + new SimpleQuadProcessor.Factory<>(new HorizontalVerticalSpriteProvider.Factory()) ); registry.registerLoader("horizontal+vertical", loader); registry.registerLoader("h+v", loader); loader = createLoader( - StandardConnectingCTMProperties::new, + OrientedConnectingCtmProperties::new, new TileAmountValidator.Exactly<>(7), - new VerticalHorizontalQuadProcessor.Factory() + new SimpleQuadProcessor.Factory<>(new VerticalHorizontalSpriteProvider.Factory()) ); registry.registerLoader("vertical+horizontal", loader); registry.registerLoader("v+h", loader); loader = createLoader( - StandardConnectingCTMProperties::new, + ConnectingCtmProperties::new, new TileAmountValidator.Exactly<>(1), new TopQuadProcessor.Factory() ); registry.registerLoader("top", loader); loader = createLoader( - RandomCTMProperties::new, + RandomCtmProperties::new, new SimpleQuadProcessor.Factory<>(new RandomSpriteProvider.Factory()) ); registry.registerLoader("random", loader); loader = createLoader( - RepeatCTMProperties::new, - new RepeatCTMProperties.Validator<>(), + RepeatCtmProperties::new, + new RepeatCtmProperties.Validator<>(), new SimpleQuadProcessor.Factory<>(new RepeatSpriteProvider.Factory()) ); registry.registerLoader("repeat", loader); loader = createLoader( - BaseCTMProperties::new, + BaseCtmProperties::new, new TileAmountValidator.Exactly<>(1), new SimpleQuadProcessor.Factory<>(new FixedSpriteProvider.Factory()) ); registry.registerLoader("fixed", loader); - // Overlay methods - - /* - "overlay" - "overlay_ctm" - "overlay_random" - "overlay_repeat" - "overlay_fixed" - */ + // Standard overlay methods loader = createLoader( - StandardOverlayCTMProperties::new, + StandardOverlayCtmProperties::new, new TileAmountValidator.AtLeast<>(17), new StandardOverlayQuadProcessor.Factory() ); registry.registerLoader("overlay", loader); loader = createLoader( - StandardConnectingOverlayCTMProperties::new, + OrientedConnectingOverlayCtmProperties::new, new TileAmountValidator.AtLeast<>(47), - new SimpleOverlayQuadProcessor.Factory<>(new CTMSpriteProvider.Factory(false)) + new SimpleOverlayQuadProcessor.Factory<>(new CtmSpriteProvider.Factory()) ); registry.registerLoader("overlay_ctm", loader); loader = createLoader( - RandomOverlayCTMProperties::new, + RandomOverlayCtmProperties::new, new SimpleOverlayQuadProcessor.Factory<>(new RandomSpriteProvider.Factory()) ); registry.registerLoader("overlay_random", loader); loader = createLoader( - RepeatOverlayCTMProperties::new, - new RepeatCTMProperties.Validator<>(), + RepeatOverlayCtmProperties::new, + new RepeatCtmProperties.Validator<>(), new SimpleOverlayQuadProcessor.Factory<>(new RepeatSpriteProvider.Factory()) ); registry.registerLoader("overlay_repeat", loader); loader = createLoader( - BaseOverlayCTMProperties::new, + BaseOverlayCtmProperties::new, new TileAmountValidator.Exactly<>(1), new SimpleOverlayQuadProcessor.Factory<>(new FixedSpriteProvider.Factory()) ); registry.registerLoader("overlay_fixed", loader); + + // Custom methods + + loader = createCustomLoader( + OrientedConnectingOverlayCtmProperties::new, + new TileAmountValidator.Exactly<>(4), + new SimpleOverlayQuadProcessor.Factory<>(new HorizontalSpriteProvider.Factory()) + ); + registry.registerLoader("overlay_horizontal", loader); + + loader = createCustomLoader( + OrientedConnectingOverlayCtmProperties::new, + new TileAmountValidator.Exactly<>(4), + new SimpleOverlayQuadProcessor.Factory<>(new VerticalSpriteProvider.Factory()) + ); + registry.registerLoader("overlay_vertical", loader); + + loader = createCustomLoader( + OrientedConnectingOverlayCtmProperties::new, + new TileAmountValidator.Exactly<>(7), + new SimpleOverlayQuadProcessor.Factory<>(new HorizontalVerticalSpriteProvider.Factory()) + ); + registry.registerLoader("overlay_horizontal+vertical", loader); + registry.registerLoader("overlay_h+v", loader); + + loader = createCustomLoader( + OrientedConnectingOverlayCtmProperties::new, + new TileAmountValidator.Exactly<>(7), + new SimpleOverlayQuadProcessor.Factory<>(new VerticalHorizontalSpriteProvider.Factory()) + ); + registry.registerLoader("overlay_vertical+horizontal", loader); + registry.registerLoader("overlay_v+h", loader); } - private static CTMLoader createLoader(CTMPropertiesFactory propertiesFactory, QuadProcessorFactory processorFactory, CachingPredicatesFactory predicatesFactory) { - return new CTMLoader<>() { + private static CtmLoader createLoader(CtmProperties.Factory propertiesFactory, QuadProcessor.Factory processorFactory, CachingPredicates.Factory predicatesFactory) { + return new CtmLoader<>() { @Override - public CTMPropertiesFactory getPropertiesFactory() { + public CtmProperties.Factory getPropertiesFactory() { return propertiesFactory; } @Override - public QuadProcessorFactory getProcessorFactory() { + public QuadProcessor.Factory getProcessorFactory() { return processorFactory; } @Override - public CachingPredicatesFactory getPredicatesFactory() { + public CachingPredicates.Factory getPredicatesFactory() { return predicatesFactory; } }; } - private static CTMLoader createLoader(CTMPropertiesFactory propertiesFactory, TileAmountValidator validator, QuadProcessorFactory processorFactory, boolean isValidForMultipass) { - return createLoader(wrapWithOptifineOnlyCheck(TileAmountValidator.wrapFactory(BaseCTMProperties.wrapFactory(propertiesFactory), validator)), processorFactory, new BaseCachingPredicates.Factory<>(isValidForMultipass)); + private static CtmLoader createLoader(CtmProperties.Factory propertiesFactory, TileAmountValidator validator, QuadProcessor.Factory processorFactory, boolean isValidForMultipass) { + return createLoader(wrapWithOptifineOnlyCheck(TileAmountValidator.wrapFactory(BaseCtmProperties.wrapFactory(propertiesFactory), validator)), processorFactory, new BaseCachingPredicates.Factory<>(isValidForMultipass)); } - private static CTMLoader createLoader(CTMPropertiesFactory propertiesFactory, TileAmountValidator validator, QuadProcessorFactory processorFactory) { + private static CtmLoader createLoader(CtmProperties.Factory propertiesFactory, TileAmountValidator validator, QuadProcessor.Factory processorFactory) { return createLoader(propertiesFactory, validator, processorFactory, true); } - private static CTMLoader createLoader(CTMPropertiesFactory propertiesFactory, QuadProcessorFactory processorFactory, boolean isValidForMultipass) { - return createLoader(wrapWithOptifineOnlyCheck(BaseCTMProperties.wrapFactory(propertiesFactory)), processorFactory, new BaseCachingPredicates.Factory<>(isValidForMultipass)); + private static CtmLoader createLoader(CtmProperties.Factory propertiesFactory, QuadProcessor.Factory processorFactory, boolean isValidForMultipass) { + return createLoader(wrapWithOptifineOnlyCheck(BaseCtmProperties.wrapFactory(propertiesFactory)), processorFactory, new BaseCachingPredicates.Factory<>(isValidForMultipass)); } - private static CTMLoader createLoader(CTMPropertiesFactory propertiesFactory, QuadProcessorFactory processorFactory) { + private static CtmLoader createLoader(CtmProperties.Factory propertiesFactory, QuadProcessor.Factory processorFactory) { return createLoader(propertiesFactory, processorFactory, true); } - private static CTMPropertiesFactory wrapWithOptifineOnlyCheck(CTMPropertiesFactory factory) { - return (properties, id, pack, packPriority, resourceManager, method) -> { - if (PropertiesParsingHelper.parseOptifineOnly(properties, id)) { + private static CtmLoader createCustomLoader(CtmProperties.Factory propertiesFactory, TileAmountValidator validator, QuadProcessor.Factory processorFactory, boolean isValidForMultipass) { + return createLoader(TileAmountValidator.wrapFactory(BaseCtmProperties.wrapFactory(propertiesFactory), validator), processorFactory, new BaseCachingPredicates.Factory<>(isValidForMultipass)); + } + + private static CtmLoader createCustomLoader(CtmProperties.Factory propertiesFactory, TileAmountValidator validator, QuadProcessor.Factory processorFactory) { + return createCustomLoader(propertiesFactory, validator, processorFactory, true); + } + + private static CtmProperties.Factory wrapWithOptifineOnlyCheck(CtmProperties.Factory factory) { + return (properties, resourceId, pack, packPriority, resourceManager, method) -> { + if (PropertiesParsingHelper.parseOptifineOnly(properties, resourceId)) { return null; } - return factory.createProperties(properties, id, pack, packPriority, resourceManager, method); + return factory.createProperties(properties, resourceId, pack, packPriority, resourceManager, method); }; } diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/AtlasLoaderMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/AtlasLoaderMixin.java index 6f04dfba..cc965c75 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/AtlasLoaderMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/AtlasLoaderMixin.java @@ -29,12 +29,12 @@ import net.minecraft.util.Identifier; @Mixin(AtlasLoader.class) -public class AtlasLoaderMixin { +abstract class AtlasLoaderMixin { @ModifyVariable(method = "(Ljava/util/List;)V", at = @At(value = "LOAD", ordinal = 0), argsOnly = true, ordinal = 0) private List continuity$modifySources(List sources) { AtlasLoaderInitContext context = AtlasLoaderInitContext.THREAD_LOCAL.get(); if (context != null) { - Set extraIds = context.getExtraIdsFuture().join(); + Set extraIds = context.getExtraIds(); if (extraIds != null && !extraIds.isEmpty()) { List extraSources = new ObjectArrayList<>(); for (Identifier extraId : extraIds) { @@ -59,7 +59,7 @@ public class AtlasLoaderMixin { if (context != null) { String emissiveSuffix = EmissiveSuffixLoader.getEmissiveSuffix(); if (emissiveSuffix != null) { - Map extraSuppliers = new Object2ObjectOpenHashMap<>(); + Map emissiveSuppliers = new Object2ObjectOpenHashMap<>(); Map emissiveIdMap = new Object2ObjectOpenHashMap<>(); suppliers.forEach((id, supplier) -> { if (!id.getPath().endsWith(emissiveSuffix)) { @@ -69,7 +69,7 @@ public class AtlasLoaderMixin { Optional optionalResource = resourceManager.getResource(emissiveLocation); if (optionalResource.isPresent()) { Resource resource = optionalResource.get(); - extraSuppliers.put(emissiveId, () -> SpriteLoader.load(emissiveId, resource)); + emissiveSuppliers.put(emissiveId, () -> SpriteLoader.load(emissiveId, resource)); emissiveIdMap.put(id, emissiveId); } } else { @@ -77,7 +77,7 @@ public class AtlasLoaderMixin { } } }); - suppliers.putAll(extraSuppliers); + suppliers.putAll(emissiveSuppliers); if (!emissiveIdMap.isEmpty()) { context.setEmissiveIdMap(emissiveIdMap); } diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/BakedModelManagerMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/BakedModelManagerMixin.java index 2ee1d0f7..de7740fc 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/BakedModelManagerMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/BakedModelManagerMixin.java @@ -8,11 +8,12 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Coerce; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; + import me.pepperbell.continuity.client.resource.BakedModelManagerReloadExtension; import net.minecraft.client.render.model.BakedModelManager; import net.minecraft.client.render.model.ModelLoader; @@ -23,7 +24,7 @@ import net.minecraft.util.profiler.Profiler; @Mixin(BakedModelManager.class) -public class BakedModelManagerMixin { +abstract class BakedModelManagerMixin { @Unique @Nullable private volatile BakedModelManagerReloadExtension continuity$reloadExtension; @@ -32,33 +33,36 @@ public class BakedModelManagerMixin { private void continuity$onHeadReload(ResourceReloader.Synchronizer synchronizer, ResourceManager resourceManager, Profiler prepareProfiler, Profiler applyProfiler, Executor prepareExecutor, Executor applyExecutor, CallbackInfoReturnable> cir) { continuity$reloadExtension = new BakedModelManagerReloadExtension(resourceManager, prepareExecutor); - BakedModelManagerReloadExtension reloadExtension = this.continuity$reloadExtension; + BakedModelManagerReloadExtension reloadExtension = continuity$reloadExtension; if (reloadExtension != null) { reloadExtension.setContext(); } } - @Inject(method = "reload(Lnet/minecraft/resource/ResourceReloader$Synchronizer;Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/util/profiler/Profiler;Lnet/minecraft/util/profiler/Profiler;Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;", at = @At("RETURN"), cancellable = true) - private void continuity$onReturnReload(ResourceReloader.Synchronizer synchronizer, ResourceManager resourceManager, Profiler prepareProfiler, Profiler applyProfiler, Executor prepareExecutor, Executor applyExecutor, CallbackInfoReturnable> cir) { - BakedModelManagerReloadExtension reloadExtension = this.continuity$reloadExtension; + @Inject(method = "reload(Lnet/minecraft/resource/ResourceReloader$Synchronizer;Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/util/profiler/Profiler;Lnet/minecraft/util/profiler/Profiler;Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;", at = @At("RETURN")) + private void continuity$onReturnReload(CallbackInfoReturnable> cir) { + BakedModelManagerReloadExtension reloadExtension = continuity$reloadExtension; if (reloadExtension != null) { reloadExtension.clearContext(); } + } - cir.setReturnValue(cir.getReturnValue().thenRun(() -> this.continuity$reloadExtension = null)); + @ModifyReturnValue(method = "reload(Lnet/minecraft/resource/ResourceReloader$Synchronizer;Lnet/minecraft/resource/ResourceManager;Lnet/minecraft/util/profiler/Profiler;Lnet/minecraft/util/profiler/Profiler;Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;", at = @At("RETURN")) + private CompletableFuture continuity$modifyReturnReload(CompletableFuture original) { + return original.thenRun(() -> continuity$reloadExtension = null); } @Inject(method = "bake(Lnet/minecraft/util/profiler/Profiler;Ljava/util/Map;Lnet/minecraft/client/render/model/ModelLoader;)Lnet/minecraft/client/render/model/BakedModelManager$BakingResult;", at = @At("HEAD")) private void continuity$onHeadBake(Profiler profiler, Map preparations, ModelLoader modelLoader, CallbackInfoReturnable cir) { - BakedModelManagerReloadExtension reloadExtension = this.continuity$reloadExtension; + BakedModelManagerReloadExtension reloadExtension = continuity$reloadExtension; if (reloadExtension != null) { reloadExtension.beforeBaking(preparations, modelLoader); } } @Inject(method = "upload(Lnet/minecraft/client/render/model/BakedModelManager$BakingResult;Lnet/minecraft/util/profiler/Profiler;)V", at = @At("RETURN")) - private void continuity$onReturnUpload(@Coerce Object bakingResult, Profiler profiler, CallbackInfo ci) { - BakedModelManagerReloadExtension reloadExtension = this.continuity$reloadExtension; + private void continuity$onReturnUpload(CallbackInfo ci) { + BakedModelManagerReloadExtension reloadExtension = continuity$reloadExtension; if (reloadExtension != null) { reloadExtension.apply(); } diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/BlockModelsMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/BlockModelsMixin.java index c3cae2d3..bcd183e7 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/BlockModelsMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/BlockModelsMixin.java @@ -9,7 +9,7 @@ import net.minecraft.client.render.block.BlockModels; @Mixin(BlockModels.class) -public class BlockModelsMixin { +abstract class BlockModelsMixin { @Inject(method = "setModels(Ljava/util/Map;)V", at = @At("HEAD")) private void continuity$onHeadSetModels(CallbackInfo ci) { SpriteCalculator.clearCache(); diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/ChunkRendererRegionMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/ChunkRendererRegionMixin.java index e8a816ff..9f1dcb9d 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/ChunkRendererRegionMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/ChunkRendererRegionMixin.java @@ -12,7 +12,7 @@ import net.minecraft.world.biome.Biome; @Mixin(ChunkRendererRegion.class) -public class ChunkRendererRegionMixin implements ChunkRendererRegionExtension { +abstract class ChunkRendererRegionMixin implements ChunkRendererRegionExtension { @Shadow @Final protected World world; diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/FallingBlockEntityRendererMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/FallingBlockEntityRendererMixin.java index d18741ff..8c4b31da 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/FallingBlockEntityRendererMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/FallingBlockEntityRendererMixin.java @@ -6,22 +6,19 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import me.pepperbell.continuity.api.client.ContinuityFeatureStates; -import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.FallingBlockEntityRenderer; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.FallingBlockEntity; @Mixin(FallingBlockEntityRenderer.class) -public class FallingBlockEntityRendererMixin { +abstract class FallingBlockEntityRendererMixin { @Inject(method = "render(Lnet/minecraft/entity/FallingBlockEntity;FFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockModelRenderer;render(Lnet/minecraft/world/BlockRenderView;Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;ZLnet/minecraft/util/math/random/Random;JI)V")) - private void continuity$beforeRenderModel(FallingBlockEntity fallingBlockEntity, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) { + private void continuity$beforeRenderModel(CallbackInfo ci) { ContinuityFeatureStates states = ContinuityFeatureStates.get(); states.getConnectedTexturesState().disable(); states.getEmissiveTexturesState().disable(); } @Inject(method = "render(Lnet/minecraft/entity/FallingBlockEntity;FFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockModelRenderer;render(Lnet/minecraft/world/BlockRenderView;Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;ZLnet/minecraft/util/math/random/Random;JI)V", shift = At.Shift.AFTER)) - private void continuity$afterRenderModel(FallingBlockEntity fallingBlockEntity, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) { + private void continuity$afterRenderModel(CallbackInfo ci) { ContinuityFeatureStates states = ContinuityFeatureStates.get(); states.getConnectedTexturesState().enable(); states.getEmissiveTexturesState().enable(); diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/IdentifierMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/IdentifierMixin.java index bb875935..d92f49e6 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/IdentifierMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/IdentifierMixin.java @@ -9,9 +9,9 @@ import net.minecraft.util.Identifier; @Mixin(Identifier.class) -public class IdentifierMixin { +abstract class IdentifierMixin { @Inject(method = "isPathValid(Ljava/lang/String;)Z", at = @At("HEAD"), cancellable = true) - private static void continuity$onIsPathValid(String path, CallbackInfoReturnable cir) { + private static void continuity$onIsPathValid(CallbackInfoReturnable cir) { if (InvalidIdentifierStateHolder.get().isEnabled()) { cir.setReturnValue(true); } diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/LifecycledResourceManagerImplMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/LifecycledResourceManagerImplMixin.java index cc9bccb9..aa3a031d 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/LifecycledResourceManagerImplMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/LifecycledResourceManagerImplMixin.java @@ -18,7 +18,7 @@ import net.minecraft.util.Identifier; @Mixin(LifecycledResourceManagerImpl.class) -public class LifecycledResourceManagerImplMixin implements LifecycledResourceManagerImplExtension { +abstract class LifecycledResourceManagerImplMixin implements LifecycledResourceManagerImplExtension { @Unique private ResourceRedirectHandler continuity$redirectHandler; diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/ModelLoaderBakerImplMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/ModelLoaderBakerImplMixin.java index 64cdf62b..938fd7e4 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/ModelLoaderBakerImplMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/ModelLoaderBakerImplMixin.java @@ -2,14 +2,14 @@ import java.util.function.BiFunction; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; 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.ModifyVariable; -import org.spongepowered.asm.mixin.injection.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import me.pepperbell.continuity.client.mixinterface.ModelLoaderExtension; import me.pepperbell.continuity.client.resource.ModelWrappingHandler; @@ -21,30 +21,21 @@ import net.minecraft.util.Identifier; @Mixin(targets = "net/minecraft/client/render/model/ModelLoader$BakerImpl") -public class ModelLoaderBakerImplMixin { - @Unique - private boolean continuity$wrapCTM; - +abstract class ModelLoaderBakerImplMixin { @Unique - private boolean continuity$wrapEmissive; + @Nullable + private ModelWrappingHandler continuity$modelWrappingHandler; @Inject(method = "(Lnet/minecraft/client/render/model/ModelLoader;Ljava/util/function/BiFunction;Lnet/minecraft/util/Identifier;)V", at = @At("TAIL")) private void continuity$onTailInit(ModelLoader modelLoader, BiFunction spriteLoader, Identifier modelId, CallbackInfo ci) { - continuity$wrapCTM = ((ModelLoaderExtension) modelLoader).continuity$getWrapCTM(); - continuity$wrapEmissive = ((ModelLoaderExtension) modelLoader).continuity$getWrapEmissive(); + continuity$modelWrappingHandler = ((ModelLoaderExtension) modelLoader).continuity$getModelWrappingHandler(); } - @Inject(method = "bake(Lnet/minecraft/util/Identifier;Lnet/minecraft/client/render/model/ModelBakeSettings;)Lnet/minecraft/client/render/model/BakedModel;", slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/json/ItemModelGenerator;create(Ljava/util/function/Function;Lnet/minecraft/client/render/model/json/JsonUnbakedModel;)Lnet/minecraft/client/render/model/json/JsonUnbakedModel;")), at = @At(value = "RETURN", ordinal = 0), cancellable = true) - private void continuity$onReturnBakeGenerated(Identifier id, ModelBakeSettings settings, CallbackInfoReturnable cir) { - BakedModel model = cir.getReturnValue(); - BakedModel wrappedModel = ModelWrappingHandler.wrap(model, id, continuity$wrapCTM, continuity$wrapEmissive); - if (model != wrappedModel) { - cir.setReturnValue(wrappedModel); + @ModifyExpressionValue(method = "bake(Lnet/minecraft/util/Identifier;Lnet/minecraft/client/render/model/ModelBakeSettings;)Lnet/minecraft/client/render/model/BakedModel;", at = { @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/json/JsonUnbakedModel;bake(Lnet/minecraft/client/render/model/Baker;Lnet/minecraft/client/render/model/json/JsonUnbakedModel;Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Lnet/minecraft/util/Identifier;Z)Lnet/minecraft/client/render/model/BakedModel;"), @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/UnbakedModel;bake(Lnet/minecraft/client/render/model/Baker;Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/render/model/BakedModel;") }) + private BakedModel continuity$modifyBakedModel(BakedModel original, Identifier id, ModelBakeSettings settings) { + if (continuity$modelWrappingHandler != null) { + return continuity$modelWrappingHandler.wrap(original, id); } - } - - @ModifyVariable(method = "bake(Lnet/minecraft/util/Identifier;Lnet/minecraft/client/render/model/ModelBakeSettings;)Lnet/minecraft/client/render/model/BakedModel;", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/client/render/model/UnbakedModel;bake(Lnet/minecraft/client/render/model/Baker;Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Lnet/minecraft/util/Identifier;)Lnet/minecraft/client/render/model/BakedModel;")) - private BakedModel continuity$modifyBakedModel(BakedModel model, Identifier id, ModelBakeSettings settings) { - return ModelWrappingHandler.wrap(model, id, continuity$wrapCTM, continuity$wrapEmissive); + return original; } } diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/ModelLoaderMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/ModelLoaderMixin.java index ec44e27b..22e2fa29 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/ModelLoaderMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/ModelLoaderMixin.java @@ -1,36 +1,27 @@ package me.pepperbell.continuity.client.mixin; +import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import me.pepperbell.continuity.client.mixinterface.ModelLoaderExtension; +import me.pepperbell.continuity.client.resource.ModelWrappingHandler; import net.minecraft.client.render.model.ModelLoader; @Mixin(ModelLoader.class) -public class ModelLoaderMixin implements ModelLoaderExtension { +abstract class ModelLoaderMixin implements ModelLoaderExtension { @Unique - private boolean continuity$wrapCTM; - - @Unique - private boolean continuity$wrapEmissive; - - @Override - public boolean continuity$getWrapCTM() { - return continuity$wrapCTM; - } - - @Override - public void continuity$setWrapCTM(boolean wrapCTM) { - this.continuity$wrapCTM = wrapCTM; - } + @Nullable + private ModelWrappingHandler continuity$modelWrappingHandler; @Override - public boolean continuity$getWrapEmissive() { - return continuity$wrapEmissive; + @Nullable + public ModelWrappingHandler continuity$getModelWrappingHandler() { + return continuity$modelWrappingHandler; } @Override - public void continuity$setWrapEmissive(boolean wrapEmissive) { - this.continuity$wrapEmissive = wrapEmissive; + public void continuity$setModelWrappingHandler(@Nullable ModelWrappingHandler handler) { + this.continuity$modelWrappingHandler = handler; } } diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/NamespaceResourceManagerMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/NamespaceResourceManagerMixin.java index 3ae2b678..8041034f 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/NamespaceResourceManagerMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/NamespaceResourceManagerMixin.java @@ -10,14 +10,14 @@ import net.minecraft.util.Identifier; @Mixin(NamespaceResourceManager.class) -public class NamespaceResourceManagerMixin { +abstract class NamespaceResourceManagerMixin { @Inject(method = "getMetadataPath(Lnet/minecraft/util/Identifier;)Lnet/minecraft/util/Identifier;", at = @At("HEAD")) - private static void continuity$onHeadGetMetadataPath(Identifier id, CallbackInfoReturnable cir) { + private static void continuity$onHeadGetMetadataPath(CallbackInfoReturnable cir) { InvalidIdentifierStateHolder.get().enable(); } @Inject(method = "getMetadataPath(Lnet/minecraft/util/Identifier;)Lnet/minecraft/util/Identifier;", at = @At("TAIL")) - private static void continuity$onTailGetMetadataPath(Identifier id, CallbackInfoReturnable cir) { + private static void continuity$onTailGetMetadataPath(CallbackInfoReturnable cir) { InvalidIdentifierStateHolder.get().disable(); } } diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/PistonBlockEntityRendererMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/PistonBlockEntityRendererMixin.java index 0ee19651..4001100d 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/PistonBlockEntityRendererMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/PistonBlockEntityRendererMixin.java @@ -6,22 +6,19 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import me.pepperbell.continuity.api.client.ContinuityFeatureStates; -import net.minecraft.block.entity.PistonBlockEntity; -import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.block.entity.PistonBlockEntityRenderer; -import net.minecraft.client.util.math.MatrixStack; @Mixin(PistonBlockEntityRenderer.class) -public class PistonBlockEntityRendererMixin { +abstract class PistonBlockEntityRendererMixin { @Inject(method = "render(Lnet/minecraft/block/entity/PistonBlockEntity;FLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;II)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockModelRenderer;enableBrightnessCache()V")) - private void continuity$beforeRenderModels(PistonBlockEntity pistonBlockEntity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, CallbackInfo ci) { + private void continuity$beforeRenderModels(CallbackInfo ci) { ContinuityFeatureStates states = ContinuityFeatureStates.get(); states.getConnectedTexturesState().disable(); states.getEmissiveTexturesState().disable(); } @Inject(method = "render(Lnet/minecraft/block/entity/PistonBlockEntity;FLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;II)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockModelRenderer;disableBrightnessCache()V", shift = At.Shift.AFTER)) - private void continuity$afterRenderModels(PistonBlockEntity pistonBlockEntity, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, CallbackInfo ci) { + private void continuity$afterRenderModels(CallbackInfo ci) { ContinuityFeatureStates states = ContinuityFeatureStates.get(); states.getConnectedTexturesState().enable(); states.getEmissiveTexturesState().enable(); 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 3ea3d4c9..8076f370 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/RenderLayersMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/RenderLayersMixin.java @@ -12,7 +12,7 @@ import net.minecraft.client.render.RenderLayers; @Mixin(RenderLayers.class) -public class RenderLayersMixin { +abstract class RenderLayersMixin { @Inject(method = "getBlockLayer(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/RenderLayer;", at = @At("HEAD"), cancellable = true) private static void continuity$onHeadGetBlockLayer(BlockState state, CallbackInfoReturnable cir) { if (!CustomBlockLayers.isEmpty() && ContinuityConfig.INSTANCE.customBlockLayers.get()) { diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/SpriteLoaderMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/SpriteLoaderMixin.java index f7e5e2e0..4a60ce3c 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/SpriteLoaderMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/SpriteLoaderMixin.java @@ -5,7 +5,6 @@ import java.util.Set; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; -import java.util.concurrent.atomic.AtomicReference; import java.util.function.Function; import java.util.function.Supplier; @@ -29,7 +28,7 @@ import net.minecraft.util.Identifier; @Mixin(SpriteLoader.class) -public class SpriteLoaderMixin { +abstract class SpriteLoaderMixin { @Shadow @Final private Identifier id; @@ -39,11 +38,11 @@ public class SpriteLoaderMixin { SpriteLoaderLoadContext context = SpriteLoaderLoadContext.THREAD_LOCAL.get(); if (context != null) { CompletableFuture<@Nullable Set> extraIdsFuture = context.getExtraIdsFuture(id); - if (context.getEmissiveControl(id) != null) { - AtomicReference<@Nullable Map> emissiveIdMapHolder = context.getEmissiveIdMapHolder(); + SpriteLoaderLoadContext.EmissiveControl emissiveControl = context.getEmissiveControl(id); + if (emissiveControl != null) { return () -> { - AtlasLoaderInitContext.THREAD_LOCAL.set(() -> extraIdsFuture); - AtlasLoaderLoadContext.THREAD_LOCAL.set(emissiveIdMapHolder::set); + AtlasLoaderInitContext.THREAD_LOCAL.set(extraIdsFuture::join); + AtlasLoaderLoadContext.THREAD_LOCAL.set(emissiveControl::setEmissiveIdMap); List> list = supplier.get(); AtlasLoaderInitContext.THREAD_LOCAL.set(null); AtlasLoaderLoadContext.THREAD_LOCAL.set(null); @@ -51,7 +50,7 @@ public class SpriteLoaderMixin { }; } return () -> { - AtlasLoaderInitContext.THREAD_LOCAL.set(() -> extraIdsFuture); + AtlasLoaderInitContext.THREAD_LOCAL.set(extraIdsFuture::join); List> list = supplier.get(); AtlasLoaderInitContext.THREAD_LOCAL.set(null); return list; @@ -66,9 +65,8 @@ public class SpriteLoaderMixin { if (context != null) { SpriteLoaderLoadContext.EmissiveControl emissiveControl = context.getEmissiveControl(id); if (emissiveControl != null) { - AtomicReference<@Nullable Map> emissiveIdMapHolder = context.getEmissiveIdMapHolder(); return spriteContentsList -> { - Map emissiveIdMap = emissiveIdMapHolder.get(); + Map emissiveIdMap = emissiveControl.getEmissiveIdMap(); if (emissiveIdMap != null) { SpriteLoaderStitchContext.THREAD_LOCAL.set(new SpriteLoaderStitchContext() { @Override @@ -83,7 +81,6 @@ public void markHasEmissives() { }); SpriteLoader.StitchResult result = function.apply(spriteContentsList); SpriteLoaderStitchContext.THREAD_LOCAL.set(null); - emissiveIdMapHolder.set(null); return result; } return function.apply(spriteContentsList); diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/SpriteMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/SpriteMixin.java index 9874590b..e790e8d9 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/SpriteMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/SpriteMixin.java @@ -8,7 +8,7 @@ import net.minecraft.client.texture.Sprite; @Mixin(Sprite.class) -public class SpriteMixin implements SpriteExtension { +abstract class SpriteMixin implements SpriteExtension { @Unique private Sprite continuity$emissiveSprite; diff --git a/src/main/java/me/pepperbell/continuity/client/mixinterface/ModelLoaderExtension.java b/src/main/java/me/pepperbell/continuity/client/mixinterface/ModelLoaderExtension.java index a40d0964..0a96e03c 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixinterface/ModelLoaderExtension.java +++ b/src/main/java/me/pepperbell/continuity/client/mixinterface/ModelLoaderExtension.java @@ -1,11 +1,12 @@ package me.pepperbell.continuity.client.mixinterface; -public interface ModelLoaderExtension { - boolean continuity$getWrapCTM(); +import org.jetbrains.annotations.Nullable; - void continuity$setWrapCTM(boolean wrapCTM); +import me.pepperbell.continuity.client.resource.ModelWrappingHandler; - boolean continuity$getWrapEmissive(); +public interface ModelLoaderExtension { + @Nullable + ModelWrappingHandler continuity$getModelWrappingHandler(); - void continuity$setWrapEmissive(boolean wrapEmissive); + void continuity$setModelWrappingHandler(@Nullable ModelWrappingHandler handler); } diff --git a/src/main/java/me/pepperbell/continuity/client/model/CTMBakedModel.java b/src/main/java/me/pepperbell/continuity/client/model/CtmBakedModel.java similarity index 88% rename from src/main/java/me/pepperbell/continuity/client/model/CTMBakedModel.java rename to src/main/java/me/pepperbell/continuity/client/model/CtmBakedModel.java index dea9ec48..ba9d65f8 100644 --- a/src/main/java/me/pepperbell/continuity/client/model/CTMBakedModel.java +++ b/src/main/java/me/pepperbell/continuity/client/model/CtmBakedModel.java @@ -17,13 +17,13 @@ import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; -public class CTMBakedModel extends ForwardingBakedModel { +public class CtmBakedModel extends ForwardingBakedModel { public static final int PASSES = 4; protected final BlockState defaultState; protected volatile Function defaultSliceFunc; - public CTMBakedModel(BakedModel wrapped, BlockState defaultState) { + public CtmBakedModel(BakedModel wrapped, BlockState defaultState) { this.wrapped = wrapped; this.defaultState = defaultState; } @@ -41,7 +41,7 @@ public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos return; } - CTMQuadTransform quadTransform = container.ctmQuadTransform; + CtmQuadTransform quadTransform = container.ctmQuadTransform; if (quadTransform.isActive()) { super.emitBlockQuads(blockView, state, pos, randomSupplier, context); return; @@ -59,6 +59,9 @@ public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos @Override public boolean isVanillaAdapter() { + if (!ContinuityConfig.INSTANCE.connectedTextures.get()) { + return super.isVanillaAdapter(); + } return false; } @@ -69,8 +72,8 @@ protected Function getSliceFunc(BlockState state) synchronized (this) { sliceFunc = defaultSliceFunc; if (sliceFunc == null) { - defaultSliceFunc = QuadProcessors.getCache(state); - sliceFunc = defaultSliceFunc; + sliceFunc = QuadProcessors.getCache(state); + defaultSliceFunc = sliceFunc; } } } @@ -79,7 +82,7 @@ protected Function getSliceFunc(BlockState state) return QuadProcessors.getCache(state); } - protected static class CTMQuadTransform implements RenderContext.QuadTransform { + protected static class CtmQuadTransform implements RenderContext.QuadTransform { protected final ProcessingContextImpl processingContext = new ProcessingContextImpl(); protected final CullingCache cullingCache = new CullingCache(); @@ -114,18 +117,18 @@ protected Boolean transformOnce(MutableQuadView quad, int pass) { QuadProcessor[] processors = pass == 0 ? slice.processors() : slice.multipassProcessors(); for (QuadProcessor processor : processors) { QuadProcessor.ProcessingResult result = processor.processQuad(quad, sprite, blockView, state, pos, randomSupplier, pass, processingContext); - if (result == QuadProcessor.ProcessingResult.CONTINUE) { + if (result == QuadProcessor.ProcessingResult.NEXT_PROCESSOR) { continue; } - if (result == QuadProcessor.ProcessingResult.STOP) { + if (result == QuadProcessor.ProcessingResult.NEXT_PASS) { return null; } - if (result == QuadProcessor.ProcessingResult.ABORT_AND_CANCEL_QUAD) { - return false; - } - if (result == QuadProcessor.ProcessingResult.ABORT_AND_RENDER_QUAD) { + if (result == QuadProcessor.ProcessingResult.STOP) { return true; } + if (result == QuadProcessor.ProcessingResult.DISCARD) { + return false; + } } return true; } diff --git a/src/main/java/me/pepperbell/continuity/client/model/EmissiveBakedModel.java b/src/main/java/me/pepperbell/continuity/client/model/EmissiveBakedModel.java index 2f3e4e27..2e6c7114 100644 --- a/src/main/java/me/pepperbell/continuity/client/model/EmissiveBakedModel.java +++ b/src/main/java/me/pepperbell/continuity/client/model/EmissiveBakedModel.java @@ -111,6 +111,9 @@ public void emitItemQuads(ItemStack stack, Supplier randomSupplier, Rend @Override public boolean isVanillaAdapter() { + if (!ContinuityConfig.INSTANCE.emissiveTextures.get()) { + return super.isVanillaAdapter(); + } return false; } diff --git a/src/main/java/me/pepperbell/continuity/client/model/ModelObjectsContainer.java b/src/main/java/me/pepperbell/continuity/client/model/ModelObjectsContainer.java index 44d23831..eb0936ec 100644 --- a/src/main/java/me/pepperbell/continuity/client/model/ModelObjectsContainer.java +++ b/src/main/java/me/pepperbell/continuity/client/model/ModelObjectsContainer.java @@ -7,7 +7,7 @@ public class ModelObjectsContainer { public static final ThreadLocal THREAD_LOCAL = ThreadLocal.withInitial(ModelObjectsContainer::new); - public final CTMBakedModel.CTMQuadTransform ctmQuadTransform = new CTMBakedModel.CTMQuadTransform(); + public final CtmBakedModel.CtmQuadTransform ctmQuadTransform = new CtmBakedModel.CtmQuadTransform(); public final EmissiveBakedModel.EmissiveBlockQuadTransform emissiveBlockQuadTransform = new EmissiveBakedModel.EmissiveBlockQuadTransform(); public final EmissiveBakedModel.EmissiveItemQuadTransform emissiveItemQuadTransform = new EmissiveBakedModel.EmissiveItemQuadTransform(); diff --git a/src/main/java/me/pepperbell/continuity/client/model/QuadProcessors.java b/src/main/java/me/pepperbell/continuity/client/model/QuadProcessors.java index b5a390fc..da09a7cd 100644 --- a/src/main/java/me/pepperbell/continuity/client/model/QuadProcessors.java +++ b/src/main/java/me/pepperbell/continuity/client/model/QuadProcessors.java @@ -1,15 +1,14 @@ package me.pepperbell.continuity.client.model; import java.util.List; -import java.util.Map; import java.util.concurrent.locks.StampedLock; import java.util.function.Function; import org.jetbrains.annotations.ApiStatus; import it.unimi.dsi.fastutil.Hash; -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; import me.pepperbell.continuity.api.client.CachingPredicates; import me.pepperbell.continuity.api.client.QuadProcessor; import net.minecraft.block.BlockState; @@ -61,28 +60,48 @@ public record ProcessorHolder(QuadProcessor processor, CachingPredicates predica public record Slice(QuadProcessor[] processors, QuadProcessor[] multipassProcessors) { } - private static class BlockStateKeyCache implements Function { - private final Map map = new Object2ObjectOpenHashMap<>(); + private static class BlockStateKeyCache { + private final Reference2ReferenceOpenHashMap map = new Reference2ReferenceOpenHashMap<>(); private final StampedLock lock = new StampedLock(); - @Override public SpriteKeyCache apply(BlockState state) { SpriteKeyCache innerCache; + + long optimisticReadStamp = lock.tryOptimisticRead(); + if (optimisticReadStamp != 0L) { + try { + // This map read could happen at the same time as a map write, so catch any exceptions. + // This is safe due to the map implementation used, which is guaranteed to not mutate the map during + // a read. + innerCache = map.get(state); + if (innerCache != null && lock.validate(optimisticReadStamp)) { + return innerCache; + } + } catch (Exception e) { + // + } + } + long readStamp = lock.readLock(); try { innerCache = map.get(state); } finally { lock.unlockRead(readStamp); } + if (innerCache == null) { long writeStamp = lock.writeLock(); try { - innerCache = new SpriteKeyCache(state); - map.put(state, innerCache); + innerCache = map.get(state); + if (innerCache == null) { + innerCache = new SpriteKeyCache(state); + map.put(state, innerCache); + } } finally { lock.unlockWrite(writeStamp); } } + return innerCache; } @@ -97,7 +116,7 @@ public void clear() { } private static class SpriteKeyCache implements Function { - private final Map map = new Object2ObjectOpenHashMap<>(4, Hash.FAST_LOAD_FACTOR); + private final Reference2ReferenceOpenHashMap map = new Reference2ReferenceOpenHashMap<>(4, Hash.FAST_LOAD_FACTOR); private final StampedLock lock = new StampedLock(); private final BlockState state; @@ -108,21 +127,42 @@ public SpriteKeyCache(BlockState state) { @Override public Slice apply(Sprite sprite) { Slice slice; + + long optimisticReadStamp = lock.tryOptimisticRead(); + if (optimisticReadStamp != 0L) { + try { + // This map read could happen at the same time as a map write, so catch any exceptions. + // This is safe due to the map implementation used, which is guaranteed to not mutate the map during + // a read. + slice = map.get(sprite); + if (slice != null && lock.validate(optimisticReadStamp)) { + return slice; + } + } catch (Exception e) { + // + } + } + long readStamp = lock.readLock(); try { slice = map.get(sprite); } finally { lock.unlockRead(readStamp); } + if (slice == null) { long writeStamp = lock.writeLock(); try { - slice = computeSlice(state, sprite); - map.put(sprite, slice); + slice = map.get(sprite); + if (slice == null) { + slice = computeSlice(state, sprite); + map.put(sprite, slice); + } } finally { lock.unlockWrite(writeStamp); } } + return slice; } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/AbstractQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/AbstractQuadProcessor.java index 41afcaa0..866175cf 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/AbstractQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/AbstractQuadProcessor.java @@ -22,7 +22,7 @@ public AbstractQuadProcessor(Sprite[] sprites, ProcessingPredicate processingPre @Override public ProcessingResult processQuad(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { if (!processingPredicate.shouldProcessQuad(quad, sprite, blockView, state, pos, context)) { - return ProcessingResult.CONTINUE; + return ProcessingResult.NEXT_PROCESSOR; } return processQuadInner(quad, sprite, blockView, state, pos, randomSupplier, pass, context); } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/AbstractQuadProcessorFactory.java b/src/main/java/me/pepperbell/continuity/client/processor/AbstractQuadProcessorFactory.java index 6221396d..93d3a0a2 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/AbstractQuadProcessorFactory.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/AbstractQuadProcessorFactory.java @@ -4,14 +4,13 @@ import java.util.function.Function; import me.pepperbell.continuity.api.client.QuadProcessor; -import me.pepperbell.continuity.api.client.QuadProcessorFactory; import me.pepperbell.continuity.client.ContinuityClient; -import me.pepperbell.continuity.client.properties.BaseCTMProperties; +import me.pepperbell.continuity.client.properties.BaseCtmProperties; import me.pepperbell.continuity.client.util.TextureUtil; import net.minecraft.client.texture.Sprite; import net.minecraft.client.util.SpriteIdentifier; -public abstract class AbstractQuadProcessorFactory implements QuadProcessorFactory { +public abstract class AbstractQuadProcessorFactory implements QuadProcessor.Factory { @Override public QuadProcessor createProcessor(T properties, Function textureGetter) { int textureAmount = getTextureAmount(properties); @@ -20,7 +19,7 @@ public QuadProcessor createProcessor(T properties, Function textureAmount) { - ContinuityClient.LOGGER.warn("Method '" + properties.getMethod() + "' requires " + textureAmount + " tiles but " + provided + " were provided in file '" + properties.getId() + "' in pack '" + properties.getPackName() + "'"); + ContinuityClient.LOGGER.warn("Method '" + properties.getMethod() + "' requires " + textureAmount + " tiles but " + provided + " were provided in file '" + properties.getResourceId() + "' in pack '" + properties.getPackName() + "'"); max = textureAmount; } @@ -30,9 +29,9 @@ public QuadProcessor createProcessor(T properties, Function implements CachingPredicatesFactory { + public static class Factory implements CachingPredicates.Factory { protected boolean isValidForMultipass; public Factory(boolean isValidForMultipass) { diff --git a/src/main/java/me/pepperbell/continuity/client/processor/BaseProcessingPredicate.java b/src/main/java/me/pepperbell/continuity/client/processor/BaseProcessingPredicate.java index be49c74d..449052a7 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/BaseProcessingPredicate.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/BaseProcessingPredicate.java @@ -7,7 +7,7 @@ import org.jetbrains.annotations.Nullable; import me.pepperbell.continuity.api.client.ProcessingDataProvider; -import me.pepperbell.continuity.client.properties.BaseCTMProperties; +import me.pepperbell.continuity.client.properties.BaseCtmProperties; import me.pepperbell.continuity.client.util.biome.BiomeRetriever; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.minecraft.block.BlockState; @@ -73,7 +73,7 @@ public boolean shouldProcessQuad(QuadView quad, Sprite sprite, BlockRenderView b return true; } - public static BaseProcessingPredicate fromProperties(BaseCTMProperties properties) { + public static BaseProcessingPredicate fromProperties(BaseCtmProperties properties) { return new BaseProcessingPredicate(properties.getFaces(), properties.getBiomePredicate(), properties.getHeightPredicate(), properties.getBlockEntityNamePredicate()); } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/CompactCTMQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/CompactCtmQuadProcessor.java similarity index 92% rename from src/main/java/me/pepperbell/continuity/client/processor/CompactCTMQuadProcessor.java rename to src/main/java/me/pepperbell/continuity/client/processor/CompactCtmQuadProcessor.java index fa388290..0fcba2d4 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/CompactCTMQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/CompactCtmQuadProcessor.java @@ -11,11 +11,10 @@ import it.unimi.dsi.fastutil.ints.Int2IntMaps; import it.unimi.dsi.fastutil.objects.ObjectIterator; import me.pepperbell.continuity.api.client.QuadProcessor; -import me.pepperbell.continuity.api.client.QuadProcessorFactory; import me.pepperbell.continuity.client.ContinuityClient; -import me.pepperbell.continuity.client.processor.simple.CTMSpriteProvider; -import me.pepperbell.continuity.client.properties.BaseCTMProperties; -import me.pepperbell.continuity.client.properties.CompactConnectingCTMProperties; +import me.pepperbell.continuity.client.processor.simple.CtmSpriteProvider; +import me.pepperbell.continuity.client.properties.BaseCtmProperties; +import me.pepperbell.continuity.client.properties.CompactConnectingCtmProperties; import me.pepperbell.continuity.client.util.MathUtil; import me.pepperbell.continuity.client.util.QuadUtil; import me.pepperbell.continuity.client.util.TextureUtil; @@ -32,7 +31,7 @@ import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; -public class CompactCTMQuadProcessor extends ConnectingQuadProcessor { +public class CompactCtmQuadProcessor extends AbstractQuadProcessor { protected static final int[][] QUADRANT_INDEX_MAPS = new int[8][]; static { int[][] map = QUADRANT_INDEX_MAPS; @@ -55,31 +54,37 @@ public class CompactCTMQuadProcessor extends ConnectingQuadProcessor { ArrayUtils.shift(map[7], 1); } + protected ConnectionPredicate connectionPredicate; + protected boolean innerSeams; + protected OrientationMode orientationMode; @Nullable protected Sprite[] replacementSprites; - public CompactCTMQuadProcessor(Sprite[] sprites, ProcessingPredicate processingPredicate, ConnectionPredicate connectionPredicate, boolean innerSeams, @Nullable Sprite[] replacementSprites) { - super(sprites, processingPredicate, connectionPredicate, innerSeams); + public CompactCtmQuadProcessor(Sprite[] sprites, ProcessingPredicate processingPredicate, ConnectionPredicate connectionPredicate, boolean innerSeams, OrientationMode orientationMode, @Nullable Sprite[] replacementSprites) { + super(sprites, processingPredicate); + this.connectionPredicate = connectionPredicate; + this.innerSeams = innerSeams; + this.orientationMode = orientationMode; this.replacementSprites = replacementSprites; } @Override public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { - int orientation = QuadUtil.getTextureOrientation(quad); + int orientation = orientationMode.getOrientation(quad, state); Direction[] directions = DirectionMaps.getMap(quad.lightFace())[orientation]; BlockPos.Mutable mutablePos = context.getData(ProcessingDataKeys.MUTABLE_POS_KEY); - int connections = CTMSpriteProvider.getConnections(connectionPredicate, innerSeams, directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); + int connections = CtmSpriteProvider.getConnections(connectionPredicate, innerSeams, directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); // if (replacementSprites != null) { - int ctmIndex = CTMSpriteProvider.SPRITE_INDEX_MAP[connections]; + int ctmIndex = CtmSpriteProvider.SPRITE_INDEX_MAP[connections]; Sprite replacementSprite = replacementSprites[ctmIndex]; if (replacementSprite != null) { if (!TextureUtil.isMissingSprite(replacementSprite)) { QuadUtil.interpolate(quad, sprite, replacementSprite); } - return ProcessingResult.STOP; + return ProcessingResult.NEXT_PASS; } } @@ -116,17 +121,17 @@ public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, Bl // Cannot split across U and V at the same time if (uSplit01 & vSplit01 | uSplit12 & vSplit12 | uSplit23 & vSplit23 | uSplit30 & vSplit30) { - return ProcessingResult.CONTINUE; + return ProcessingResult.NEXT_PROCESSOR; } // Cannot split across U twice in a row if (uSplit01 & uSplit12 | uSplit12 & uSplit23 | uSplit23 & uSplit30 | uSplit30 & uSplit01) { - return ProcessingResult.CONTINUE; + return ProcessingResult.NEXT_PROCESSOR; } // Cannot split across V twice in a row if (vSplit01 & vSplit12 | vSplit12 & vSplit23 | vSplit23 & vSplit30 | vSplit30 & vSplit01) { - return ProcessingResult.CONTINUE; + return ProcessingResult.NEXT_PROCESSOR; } // @@ -149,7 +154,7 @@ public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, Bl if (!(split01 | split12 | split23 | split30)) { tryInterpolate(quad, sprite, spriteIndex0); - return ProcessingResult.ABORT_AND_RENDER_QUAD; + return ProcessingResult.STOP; } VertexContainer vertexContainer = context.getData(ProcessingDataKeys.VERTEX_CONTAINER_KEY); @@ -341,7 +346,7 @@ public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, Bl } context.markHasExtraQuads(); - return ProcessingResult.ABORT_AND_CANCEL_QUAD; + return ProcessingResult.DISCARD; } else if (uSplit | vSplit) { boolean firstSplit; boolean swapAB; @@ -371,7 +376,7 @@ public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, Bl if (spriteIndexA == spriteIndexB) { tryInterpolate(quad, sprite, spriteIndexA); - return ProcessingResult.ABORT_AND_RENDER_QUAD; + return ProcessingResult.STOP; } if (swapAB) { @@ -422,7 +427,7 @@ public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, Bl } context.markHasExtraQuads(); - return ProcessingResult.ABORT_AND_CANCEL_QUAD; + return ProcessingResult.DISCARD; } else { int quadrant; if ((uSignum0 + uSignum1 + uSignum2 + uSignum3) <= 0) { @@ -441,7 +446,7 @@ public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, Bl int spriteIndex = getSpriteIndex(quadrant, connections); tryInterpolate(quad, sprite, spriteIndex); - return ProcessingResult.ABORT_AND_RENDER_QUAD; + return ProcessingResult.STOP; } } @@ -607,9 +612,9 @@ public void fillBaseVertices(QuadView quad) { } // TODO - public static class Factory implements QuadProcessorFactory { + public static class Factory implements QuadProcessor.Factory { @Override - public QuadProcessor createProcessor(CompactConnectingCTMProperties properties, Function textureGetter) { + public QuadProcessor createProcessor(CompactConnectingCtmProperties properties, Function textureGetter) { int textureAmount = getTextureAmount(properties); List spriteIds = properties.getSpriteIds(); int provided = spriteIds.size(); @@ -629,17 +634,17 @@ public QuadProcessor createProcessor(CompactConnectingCTMProperties properties, if (value < provided) { replacementSprites[key] = textureGetter.apply(spriteIds.get(value)); } else { - ContinuityClient.LOGGER.warn("Cannot replace tile " + key + " with tile " + value + " as only " + provided + " tiles were provided in file '" + properties.getId() + "' in pack '" + properties.getPackName() + "'"); + ContinuityClient.LOGGER.warn("Cannot replace tile " + key + " with tile " + value + " as only " + provided + " tiles were provided in file '" + properties.getResourceId() + "' in pack '" + properties.getPackName() + "'"); } } else { - ContinuityClient.LOGGER.warn("Cannot replace tile " + key + " as method '" + properties.getMethod() + "' only supports " + replacementTextureAmount + " replacement tiles in file '" + properties.getId() + "' in pack '" + properties.getPackName() + "'"); + ContinuityClient.LOGGER.warn("Cannot replace tile " + key + " as method '" + properties.getMethod() + "' only supports " + replacementTextureAmount + " replacement tiles in file '" + properties.getResourceId() + "' in pack '" + properties.getPackName() + "'"); } } } if (provided > textureAmount) { if (replacementSprites == null) { - ContinuityClient.LOGGER.warn("Method '" + properties.getMethod() + "' requires " + textureAmount + " tiles but " + provided + " were provided in file '" + properties.getId() + "' in pack '" + properties.getPackName() + "'"); + ContinuityClient.LOGGER.warn("Method '" + properties.getMethod() + "' requires " + textureAmount + " tiles but " + provided + " were provided in file '" + properties.getResourceId() + "' in pack '" + properties.getPackName() + "'"); } max = textureAmount; } @@ -650,9 +655,9 @@ public QuadProcessor createProcessor(CompactConnectingCTMProperties properties, for (int i = 0; i < max; i++) { Sprite sprite; SpriteIdentifier spriteId = spriteIds.get(i); - if (spriteId.equals(BaseCTMProperties.SPECIAL_SKIP_SPRITE_ID)) { + if (spriteId.equals(BaseCtmProperties.SPECIAL_SKIP_SPRITE_ID)) { sprite = missingSprite; - } else if (spriteId.equals(BaseCTMProperties.SPECIAL_DEFAULT_SPRITE_ID)) { + } else if (spriteId.equals(BaseCtmProperties.SPECIAL_DEFAULT_SPRITE_ID)) { sprite = supportsNullSprites ? null : missingSprite; } else { sprite = textureGetter.apply(spriteId); @@ -661,7 +666,7 @@ public QuadProcessor createProcessor(CompactConnectingCTMProperties properties, } if (provided < textureAmount) { - ContinuityClient.LOGGER.error("Method '" + properties.getMethod() + "' requires at least " + textureAmount + " tiles but only " + provided + " were provided in file '" + properties.getId() + "' in pack '" + properties.getPackName() + "'"); + ContinuityClient.LOGGER.error("Method '" + properties.getMethod() + "' requires at least " + textureAmount + " tiles but only " + provided + " were provided in file '" + properties.getResourceId() + "' in pack '" + properties.getPackName() + "'"); for (int i = provided; i < textureAmount; i++) { sprites[i] = missingSprite; } @@ -670,19 +675,19 @@ public QuadProcessor createProcessor(CompactConnectingCTMProperties properties, return createProcessor(properties, sprites, replacementSprites); } - public QuadProcessor createProcessor(CompactConnectingCTMProperties properties, Sprite[] sprites, @Nullable Sprite[] replacementSprites) { - return new CompactCTMQuadProcessor(sprites, BaseProcessingPredicate.fromProperties(properties), properties.getConnectionPredicate(), properties.getInnerSeams(), replacementSprites); + public QuadProcessor createProcessor(CompactConnectingCtmProperties properties, Sprite[] sprites, @Nullable Sprite[] replacementSprites) { + return new CompactCtmQuadProcessor(sprites, BaseProcessingPredicate.fromProperties(properties), properties.getConnectionPredicate(), properties.getInnerSeams(), properties.getOrientationMode(), replacementSprites); } - public int getTextureAmount(CompactConnectingCTMProperties properties) { + public int getTextureAmount(CompactConnectingCtmProperties properties) { return 5; } - public int getReplacementTextureAmount(CompactConnectingCTMProperties properties) { + public int getReplacementTextureAmount(CompactConnectingCtmProperties properties) { return 47; } - public boolean supportsNullSprites(CompactConnectingCTMProperties properties) { + public boolean supportsNullSprites(CompactConnectingCtmProperties properties) { return false; } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/ConnectingQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/ConnectingQuadProcessor.java deleted file mode 100644 index 85738871..00000000 --- a/src/main/java/me/pepperbell/continuity/client/processor/ConnectingQuadProcessor.java +++ /dev/null @@ -1,14 +0,0 @@ -package me.pepperbell.continuity.client.processor; - -import net.minecraft.client.texture.Sprite; - -public abstract class ConnectingQuadProcessor extends AbstractQuadProcessor { - protected ConnectionPredicate connectionPredicate; - protected boolean innerSeams; - - public ConnectingQuadProcessor(Sprite[] sprites, ProcessingPredicate processingPredicate, ConnectionPredicate connectionPredicate, boolean innerSeams) { - super(sprites, processingPredicate); - this.connectionPredicate = connectionPredicate; - this.innerSeams = innerSeams; - } -} diff --git a/src/main/java/me/pepperbell/continuity/client/processor/DirectionMaps.java b/src/main/java/me/pepperbell/continuity/client/processor/DirectionMaps.java index 2acdeb64..026a28b1 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/DirectionMaps.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/DirectionMaps.java @@ -2,8 +2,8 @@ import org.apache.commons.lang3.ArrayUtils; -import me.pepperbell.continuity.client.util.QuadUtil; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; +import net.minecraft.block.BlockState; import net.minecraft.util.math.Direction; public final class DirectionMaps { @@ -51,7 +51,7 @@ public static Direction[][] getMap(Direction direction) { return DIRECTION_MAPS[direction.ordinal()]; } - public static Direction[] getDirections(QuadView quad) { - return getMap(quad.lightFace())[QuadUtil.getTextureOrientation(quad)]; + public static Direction[] getDirections(OrientationMode orientationMode, QuadView quad, BlockState state) { + return getMap(quad.lightFace())[orientationMode.getOrientation(quad, state)]; } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/HorizontalQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/HorizontalQuadProcessor.java deleted file mode 100644 index dbb7cd5f..00000000 --- a/src/main/java/me/pepperbell/continuity/client/processor/HorizontalQuadProcessor.java +++ /dev/null @@ -1,58 +0,0 @@ -package me.pepperbell.continuity.client.processor; - -import java.util.function.Supplier; - -import me.pepperbell.continuity.api.client.QuadProcessor; -import me.pepperbell.continuity.client.processor.simple.SimpleQuadProcessor; -import me.pepperbell.continuity.client.properties.StandardConnectingCTMProperties; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; -import net.minecraft.block.BlockState; -import net.minecraft.client.texture.Sprite; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.random.Random; -import net.minecraft.world.BlockRenderView; - -public class HorizontalQuadProcessor extends ConnectingQuadProcessor { - // Indices for this array are formed from these bit values: - // 1 * 2 - protected static final int[] SPRITE_INDEX_MAP = new int[] { - 3, 2, 0, 1, - }; - - public HorizontalQuadProcessor(Sprite[] sprites, ProcessingPredicate processingPredicate, ConnectionPredicate connectionPredicate, boolean innerSeams) { - super(sprites, processingPredicate, connectionPredicate, innerSeams); - } - - @Override - public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { - Direction[] directions = DirectionMaps.getDirections(quad); - BlockPos.Mutable mutablePos = context.getData(ProcessingDataKeys.MUTABLE_POS_KEY); - int connections = getConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); - Sprite newSprite = sprites[SPRITE_INDEX_MAP[connections]]; - return SimpleQuadProcessor.process(quad, sprite, newSprite); - } - - protected int getConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { - int connections = 0; - for (int i = 0; i < 2; i++) { - mutablePos.set(pos, directions[i * 2]); - if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, face, quadSprite, innerSeams)) { - connections |= 1 << i; - } - } - return connections; - } - - public static class Factory extends AbstractQuadProcessorFactory { - @Override - public QuadProcessor createProcessor(StandardConnectingCTMProperties properties, Sprite[] sprites) { - return new HorizontalQuadProcessor(sprites, BaseProcessingPredicate.fromProperties(properties), properties.getConnectionPredicate(), properties.getInnerSeams()); - } - - @Override - public int getTextureAmount(StandardConnectingCTMProperties properties) { - return 4; - } - } -} diff --git a/src/main/java/me/pepperbell/continuity/client/processor/OrientationMode.java b/src/main/java/me/pepperbell/continuity/client/processor/OrientationMode.java new file mode 100644 index 00000000..5af4e634 --- /dev/null +++ b/src/main/java/me/pepperbell/continuity/client/processor/OrientationMode.java @@ -0,0 +1,34 @@ +package me.pepperbell.continuity.client.processor; + +import me.pepperbell.continuity.client.util.QuadUtil; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; +import net.minecraft.block.BlockState; +import net.minecraft.state.property.Properties; +import net.minecraft.util.math.Direction; + +public enum OrientationMode { + NONE, + STATE_AXIS, + TEXTURE; + + public static final int[][] AXIS_ORIENTATIONS = new int[][] { + { 3, 3, 1, 3, 0, 2 }, + { 0, 0, 0, 0, 0, 0 }, + { 2, 0, 2, 0, 1, 3 } + }; + + public int getOrientation(QuadView quad, BlockState state) { + return switch (this) { + case NONE -> 0; + case STATE_AXIS -> { + if (state.contains(Properties.AXIS)) { + Direction.Axis axis = state.get(Properties.AXIS); + yield AXIS_ORIENTATIONS[axis.ordinal()][quad.lightFace().ordinal()]; + } else { + yield 0; + } + } + case TEXTURE -> QuadUtil.getTextureOrientation(quad); + }; + } +} diff --git a/src/main/java/me/pepperbell/continuity/client/processor/ProcessingDataKeys.java b/src/main/java/me/pepperbell/continuity/client/processor/ProcessingDataKeys.java index 9ae7fb50..e2d7dbe8 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/ProcessingDataKeys.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/ProcessingDataKeys.java @@ -14,7 +14,7 @@ public final class ProcessingDataKeys { public static final ProcessingDataKey MUTABLE_POS_KEY = create("mutable_pos", BlockPos.Mutable::new); public static final ProcessingDataKey BIOME_CACHE_KEY = create("biome_cache", BaseProcessingPredicate.BiomeCache::new, BaseProcessingPredicate.BiomeCache::reset); public static final ProcessingDataKey BLOCK_ENTITY_NAME_CACHE_KEY = create("block_entity_name_cache", BaseProcessingPredicate.BlockEntityNameCache::new, BaseProcessingPredicate.BlockEntityNameCache::reset); - public static final ProcessingDataKey VERTEX_CONTAINER_KEY = create("vertex_container", CompactCTMQuadProcessor.VertexContainer::new); + public static final ProcessingDataKey VERTEX_CONTAINER_KEY = create("vertex_container", CompactCtmQuadProcessor.VertexContainer::new); public static final ProcessingDataKey STANDARD_OVERLAY_EMITTER_POOL_KEY = create("standard_overlay_emitter_pool", StandardOverlayQuadProcessor.OverlayEmitterPool::new, StandardOverlayQuadProcessor.OverlayEmitterPool::reset); public static final ProcessingDataKey SIMPLE_OVERLAY_EMITTER_POOL_KEY = create("simple_overlay_emitter_pool", SimpleOverlayQuadProcessor.OverlayEmitterPool::new, SimpleOverlayQuadProcessor.OverlayEmitterPool::reset); diff --git a/src/main/java/me/pepperbell/continuity/client/processor/Symmetry.java b/src/main/java/me/pepperbell/continuity/client/processor/Symmetry.java index f655ee9b..542676c6 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/Symmetry.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/Symmetry.java @@ -7,7 +7,7 @@ public enum Symmetry { OPPOSITE, ALL; - public Direction getActualFace(Direction face) { + public Direction apply(Direction face) { if (this == Symmetry.OPPOSITE) { if (face.getDirection() == Direction.AxisDirection.POSITIVE) { face = face.getOpposite(); diff --git a/src/main/java/me/pepperbell/continuity/client/processor/TopQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/TopQuadProcessor.java index 34df6304..221c7bda 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/TopQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/TopQuadProcessor.java @@ -4,7 +4,7 @@ import me.pepperbell.continuity.api.client.QuadProcessor; import me.pepperbell.continuity.client.processor.simple.SimpleQuadProcessor; -import me.pepperbell.continuity.client.properties.StandardConnectingCTMProperties; +import me.pepperbell.continuity.client.properties.ConnectingCtmProperties; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.minecraft.block.BlockState; import net.minecraft.client.texture.Sprite; @@ -14,9 +14,14 @@ import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; -public class TopQuadProcessor extends ConnectingQuadProcessor { +public class TopQuadProcessor extends AbstractQuadProcessor { + protected ConnectionPredicate connectionPredicate; + protected boolean innerSeams; + public TopQuadProcessor(Sprite[] sprites, ProcessingPredicate processingPredicate, ConnectionPredicate connectionPredicate, boolean innerSeams) { - super(sprites, processingPredicate, connectionPredicate, innerSeams); + super(sprites, processingPredicate); + this.connectionPredicate = connectionPredicate; + this.innerSeams = innerSeams; } @Override @@ -35,17 +40,17 @@ public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, Bl return SimpleQuadProcessor.process(quad, sprite, sprites[0]); } } - return ProcessingResult.CONTINUE; + return ProcessingResult.NEXT_PROCESSOR; } - public static class Factory extends AbstractQuadProcessorFactory { + public static class Factory extends AbstractQuadProcessorFactory { @Override - public QuadProcessor createProcessor(StandardConnectingCTMProperties properties, Sprite[] sprites) { + public QuadProcessor createProcessor(ConnectingCtmProperties properties, Sprite[] sprites) { return new TopQuadProcessor(sprites, BaseProcessingPredicate.fromProperties(properties), properties.getConnectionPredicate(), properties.getInnerSeams()); } @Override - public int getTextureAmount(StandardConnectingCTMProperties properties) { + public int getTextureAmount(ConnectingCtmProperties properties) { return 1; } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/VerticalQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/VerticalQuadProcessor.java deleted file mode 100644 index 45ca8954..00000000 --- a/src/main/java/me/pepperbell/continuity/client/processor/VerticalQuadProcessor.java +++ /dev/null @@ -1,60 +0,0 @@ -package me.pepperbell.continuity.client.processor; - -import java.util.function.Supplier; - -import me.pepperbell.continuity.api.client.QuadProcessor; -import me.pepperbell.continuity.client.processor.simple.SimpleQuadProcessor; -import me.pepperbell.continuity.client.properties.StandardConnectingCTMProperties; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; -import net.minecraft.block.BlockState; -import net.minecraft.client.texture.Sprite; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; -import net.minecraft.util.math.random.Random; -import net.minecraft.world.BlockRenderView; - -public class VerticalQuadProcessor extends ConnectingQuadProcessor { - // Indices for this array are formed from these bit values: - // 2 - // * - // 1 - protected static final int[] SPRITE_INDEX_MAP = new int[] { - 3, 2, 0, 1, - }; - - public VerticalQuadProcessor(Sprite[] sprites, ProcessingPredicate processingPredicate, ConnectionPredicate connectionPredicate, boolean innerSeams) { - super(sprites, processingPredicate, connectionPredicate, innerSeams); - } - - @Override - public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { - Direction[] directions = DirectionMaps.getDirections(quad); - BlockPos.Mutable mutablePos = context.getData(ProcessingDataKeys.MUTABLE_POS_KEY); - int connections = getConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); - Sprite newSprite = sprites[SPRITE_INDEX_MAP[connections]]; - return SimpleQuadProcessor.process(quad, sprite, newSprite); - } - - protected int getConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { - int connections = 0; - for (int i = 0; i < 2; i++) { - mutablePos.set(pos, directions[i * 2 + 1]); - if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, face, quadSprite, innerSeams)) { - connections |= 1 << i; - } - } - return connections; - } - - public static class Factory extends AbstractQuadProcessorFactory { - @Override - public QuadProcessor createProcessor(StandardConnectingCTMProperties properties, Sprite[] sprites) { - return new VerticalQuadProcessor(sprites, BaseProcessingPredicate.fromProperties(properties), properties.getConnectionPredicate(), properties.getInnerSeams()); - } - - @Override - public int getTextureAmount(StandardConnectingCTMProperties properties) { - return 4; - } - } -} diff --git a/src/main/java/me/pepperbell/continuity/client/processor/overlay/OverlayProcessingPredicate.java b/src/main/java/me/pepperbell/continuity/client/processor/overlay/OverlayProcessingPredicate.java index 8a9ad71a..2b730125 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/overlay/OverlayProcessingPredicate.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/overlay/OverlayProcessingPredicate.java @@ -8,7 +8,7 @@ import me.pepperbell.continuity.api.client.ProcessingDataProvider; import me.pepperbell.continuity.client.processor.BaseProcessingPredicate; -import me.pepperbell.continuity.client.properties.BaseCTMProperties; +import me.pepperbell.continuity.client.properties.BaseCtmProperties; import me.pepperbell.continuity.client.util.QuadUtil; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.minecraft.block.BlockState; @@ -31,7 +31,7 @@ public boolean shouldProcessQuad(QuadView quad, Sprite sprite, BlockRenderView b return QuadUtil.isQuadUnitSquare(quad); } - public static OverlayProcessingPredicate fromProperties(BaseCTMProperties properties) { + public static OverlayProcessingPredicate fromProperties(BaseCtmProperties properties) { return new OverlayProcessingPredicate(properties.getFaces(), properties.getBiomePredicate(), properties.getHeightPredicate(), properties.getBlockEntityNamePredicate()); } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/overlay/SimpleOverlayQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/overlay/SimpleOverlayQuadProcessor.java index 71635db7..e9b0076c 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/overlay/SimpleOverlayQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/overlay/SimpleOverlayQuadProcessor.java @@ -12,7 +12,7 @@ import me.pepperbell.continuity.client.processor.ProcessingPredicate; import me.pepperbell.continuity.client.processor.simple.SimpleQuadProcessor; import me.pepperbell.continuity.client.processor.simple.SpriteProvider; -import me.pepperbell.continuity.client.properties.BaseCTMProperties; +import me.pepperbell.continuity.client.properties.BaseCtmProperties; import me.pepperbell.continuity.client.properties.overlay.OverlayPropertiesSection; import me.pepperbell.continuity.client.util.QuadUtil; import me.pepperbell.continuity.client.util.RenderUtil; @@ -51,7 +51,7 @@ public ProcessingResult processQuad(MutableQuadView quad, Sprite sprite, BlockRe context.addEmitterConsumer(emitter); } } - return ProcessingResult.CONTINUE; + return ProcessingResult.NEXT_PROCESSOR; } public static class OverlayEmitter implements Consumer { @@ -91,7 +91,7 @@ public void reset() { } } - public static class Factory extends SimpleQuadProcessor.Factory { + public static class Factory extends SimpleQuadProcessor.Factory { public Factory(SpriteProvider.Factory spriteProviderFactory) { super(spriteProviderFactory); } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/overlay/StandardOverlayQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/overlay/StandardOverlayQuadProcessor.java index a874a9cb..d83e3fcc 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/overlay/StandardOverlayQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/overlay/StandardOverlayQuadProcessor.java @@ -18,7 +18,7 @@ import me.pepperbell.continuity.client.processor.ProcessingDataKeys; import me.pepperbell.continuity.client.processor.ProcessingPredicate; import me.pepperbell.continuity.client.properties.overlay.OverlayPropertiesSection; -import me.pepperbell.continuity.client.properties.overlay.StandardOverlayCTMProperties; +import me.pepperbell.continuity.client.properties.overlay.StandardOverlayCtmProperties; import me.pepperbell.continuity.client.util.QuadUtil; import me.pepperbell.continuity.client.util.RenderUtil; import me.pepperbell.continuity.client.util.SpriteCalculator; @@ -72,7 +72,7 @@ public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, Bl if (emitter != null) { context.addEmitterConsumer(emitter); } - return ProcessingResult.CONTINUE; + return ProcessingResult.NEXT_PROCESSOR; } protected boolean appliesOverlay(BlockState other, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { @@ -379,20 +379,20 @@ public void reset() { } } - public static class Factory extends AbstractQuadProcessorFactory { + public static class Factory extends AbstractQuadProcessorFactory { @Override - public QuadProcessor createProcessor(StandardOverlayCTMProperties properties, Sprite[] sprites) { + public QuadProcessor createProcessor(StandardOverlayCtmProperties properties, Sprite[] sprites) { OverlayPropertiesSection overlaySection = properties.getOverlayPropertiesSection(); return new StandardOverlayQuadProcessor(sprites, OverlayProcessingPredicate.fromProperties(properties), properties.getMatchTilesSet(), properties.getMatchBlocksPredicate(), properties.getConnectTilesSet(), properties.getConnectBlocksPredicate(), properties.getConnectionPredicate(), overlaySection.getTintIndex(), overlaySection.getTintBlock(), overlaySection.getLayer()); } @Override - public int getTextureAmount(StandardOverlayCTMProperties properties) { + public int getTextureAmount(StandardOverlayCtmProperties properties) { return 17; } @Override - public boolean supportsNullSprites(StandardOverlayCTMProperties properties) { + public boolean supportsNullSprites(StandardOverlayCtmProperties properties) { return false; } } 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 similarity index 77% rename from src/main/java/me/pepperbell/continuity/client/processor/simple/CTMSpriteProvider.java rename to src/main/java/me/pepperbell/continuity/client/processor/simple/CtmSpriteProvider.java index 849ab228..9cb170ac 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 @@ -7,8 +7,9 @@ import me.pepperbell.continuity.api.client.ProcessingDataProvider; import me.pepperbell.continuity.client.processor.ConnectionPredicate; import me.pepperbell.continuity.client.processor.DirectionMaps; +import me.pepperbell.continuity.client.processor.OrientationMode; import me.pepperbell.continuity.client.processor.ProcessingDataKeys; -import me.pepperbell.continuity.client.properties.StandardConnectingCTMProperties; +import me.pepperbell.continuity.client.properties.OrientedConnectingCtmProperties; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.minecraft.block.BlockState; import net.minecraft.client.texture.Sprite; @@ -17,7 +18,7 @@ import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; -public class CTMSpriteProvider implements SpriteProvider { +public class CtmSpriteProvider implements SpriteProvider { // Indices for this array are formed from these bit values: // 128 64 32 // 1 * 16 @@ -44,19 +45,19 @@ public class CTMSpriteProvider implements SpriteProvider { protected Sprite[] sprites; protected ConnectionPredicate connectionPredicate; protected boolean innerSeams; - protected boolean useTextureOrientation; + protected OrientationMode orientationMode; - public CTMSpriteProvider(Sprite[] sprites, ConnectionPredicate connectionPredicate, boolean innerSeams, boolean useTextureOrientation) { + public CtmSpriteProvider(Sprite[] sprites, ConnectionPredicate connectionPredicate, boolean innerSeams, OrientationMode orientationMode) { this.sprites = sprites; this.connectionPredicate = connectionPredicate; this.innerSeams = innerSeams; - this.useTextureOrientation = useTextureOrientation; + this.orientationMode = orientationMode; } @Override @Nullable public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { - Direction[] directions = useTextureOrientation ? DirectionMaps.getDirections(quad) : DirectionMaps.getMap(quad.lightFace())[0]; + Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, state); BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS_KEY); int connections = getConnections(connectionPredicate, innerSeams, directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); return sprites[SPRITE_INDEX_MAP[connections]]; @@ -83,20 +84,14 @@ public static int getConnections(ConnectionPredicate connectionPredicate, boolea return connections; } - public static class Factory implements SpriteProvider.Factory { - protected boolean useTextureOrientation; - - public Factory(boolean useTextureOrientation) { - this.useTextureOrientation = useTextureOrientation; - } - + public static class Factory implements SpriteProvider.Factory { @Override - public SpriteProvider createSpriteProvider(Sprite[] sprites, StandardConnectingCTMProperties properties) { - return new CTMSpriteProvider(sprites, properties.getConnectionPredicate(), properties.getInnerSeams(), useTextureOrientation); + public SpriteProvider createSpriteProvider(Sprite[] sprites, OrientedConnectingCtmProperties properties) { + return new CtmSpriteProvider(sprites, properties.getConnectionPredicate(), properties.getInnerSeams(), properties.getOrientationMode()); } @Override - public int getTextureAmount(StandardConnectingCTMProperties properties) { + public int getTextureAmount(OrientedConnectingCtmProperties properties) { return 47; } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/FixedSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/FixedSpriteProvider.java index 1bfb5440..67f9e197 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/FixedSpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/FixedSpriteProvider.java @@ -5,7 +5,7 @@ import org.jetbrains.annotations.Nullable; import me.pepperbell.continuity.api.client.ProcessingDataProvider; -import me.pepperbell.continuity.client.properties.BaseCTMProperties; +import me.pepperbell.continuity.client.properties.BaseCtmProperties; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.minecraft.block.BlockState; import net.minecraft.client.texture.Sprite; @@ -26,14 +26,14 @@ public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, return this.sprite; } - public static class Factory implements SpriteProvider.Factory { + public static class Factory implements SpriteProvider.Factory { @Override - public SpriteProvider createSpriteProvider(Sprite[] sprites, BaseCTMProperties properties) { + public SpriteProvider createSpriteProvider(Sprite[] sprites, BaseCtmProperties properties) { return new FixedSpriteProvider(sprites[0]); } @Override - public int getTextureAmount(BaseCTMProperties properties) { + public int getTextureAmount(BaseCtmProperties properties) { return 1; } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalSpriteProvider.java new file mode 100644 index 00000000..11ccc2b7 --- /dev/null +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalSpriteProvider.java @@ -0,0 +1,71 @@ +package me.pepperbell.continuity.client.processor.simple; + +import java.util.function.Supplier; + +import org.jetbrains.annotations.Nullable; + +import me.pepperbell.continuity.api.client.ProcessingDataProvider; +import me.pepperbell.continuity.client.processor.ConnectionPredicate; +import me.pepperbell.continuity.client.processor.DirectionMaps; +import me.pepperbell.continuity.client.processor.OrientationMode; +import me.pepperbell.continuity.client.processor.ProcessingDataKeys; +import me.pepperbell.continuity.client.properties.OrientedConnectingCtmProperties; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; +import net.minecraft.block.BlockState; +import net.minecraft.client.texture.Sprite; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.random.Random; +import net.minecraft.world.BlockRenderView; + +public class HorizontalSpriteProvider implements SpriteProvider { + // Indices for this array are formed from these bit values: + // 1 * 2 + protected static final int[] SPRITE_INDEX_MAP = new int[] { + 3, 2, 0, 1, + }; + + protected Sprite[] sprites; + protected ConnectionPredicate connectionPredicate; + protected boolean innerSeams; + protected OrientationMode orientationMode; + + public HorizontalSpriteProvider(Sprite[] sprites, ConnectionPredicate connectionPredicate, boolean innerSeams, OrientationMode orientationMode) { + this.sprites = sprites; + this.connectionPredicate = connectionPredicate; + this.innerSeams = innerSeams; + this.orientationMode = orientationMode; + } + + @Override + @Nullable + public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { + Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, state); + BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS_KEY); + int connections = getConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); + return sprites[SPRITE_INDEX_MAP[connections]]; + } + + protected int getConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { + int connections = 0; + for (int i = 0; i < 2; i++) { + mutablePos.set(pos, directions[i * 2]); + if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, face, quadSprite, innerSeams)) { + connections |= 1 << i; + } + } + return connections; + } + + public static class Factory implements SpriteProvider.Factory { + @Override + public SpriteProvider createSpriteProvider(Sprite[] sprites, OrientedConnectingCtmProperties properties) { + return new HorizontalSpriteProvider(sprites, properties.getConnectionPredicate(), properties.getInnerSeams(), properties.getOrientationMode()); + } + + @Override + public int getTextureAmount(OrientedConnectingCtmProperties properties) { + return 4; + } + } +} diff --git a/src/main/java/me/pepperbell/continuity/client/processor/HorizontalVerticalQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalVerticalSpriteProvider.java similarity index 50% rename from src/main/java/me/pepperbell/continuity/client/processor/HorizontalVerticalQuadProcessor.java rename to src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalVerticalSpriteProvider.java index 446d3b86..1781149f 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/HorizontalVerticalQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/HorizontalVerticalSpriteProvider.java @@ -1,11 +1,16 @@ -package me.pepperbell.continuity.client.processor; +package me.pepperbell.continuity.client.processor.simple; import java.util.function.Supplier; -import me.pepperbell.continuity.api.client.QuadProcessor; -import me.pepperbell.continuity.client.processor.simple.SimpleQuadProcessor; -import me.pepperbell.continuity.client.properties.StandardConnectingCTMProperties; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; +import org.jetbrains.annotations.Nullable; + +import me.pepperbell.continuity.api.client.ProcessingDataProvider; +import me.pepperbell.continuity.client.processor.ConnectionPredicate; +import me.pepperbell.continuity.client.processor.DirectionMaps; +import me.pepperbell.continuity.client.processor.OrientationMode; +import me.pepperbell.continuity.client.processor.ProcessingDataKeys; +import me.pepperbell.continuity.client.properties.OrientedConnectingCtmProperties; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.minecraft.block.BlockState; import net.minecraft.client.texture.Sprite; import net.minecraft.util.math.BlockPos; @@ -13,7 +18,7 @@ import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; -public class HorizontalVerticalQuadProcessor extends HorizontalQuadProcessor { +public class HorizontalVerticalSpriteProvider extends HorizontalSpriteProvider { // Indices for this array are formed from these bit values: // 32 16 8 // * @@ -25,23 +30,22 @@ public class HorizontalVerticalQuadProcessor extends HorizontalQuadProcessor { 3, 3, 6, 3, 3, 3, 3, 3, 3, 3, 6, 3, 3, 3, 3, 3, }; - public HorizontalVerticalQuadProcessor(Sprite[] sprites, ProcessingPredicate processingPredicate, ConnectionPredicate connectionPredicate, boolean innerSeams) { - super(sprites, processingPredicate, connectionPredicate, innerSeams); + public HorizontalVerticalSpriteProvider(Sprite[] sprites, ConnectionPredicate connectionPredicate, boolean innerSeams, OrientationMode orientationMode) { + super(sprites, connectionPredicate, innerSeams, orientationMode); } @Override - public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { - Direction[] directions = DirectionMaps.getDirections(quad); - BlockPos.Mutable mutablePos = context.getData(ProcessingDataKeys.MUTABLE_POS_KEY); + @Nullable + public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { + Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, state); + BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS_KEY); int connections = getConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); - Sprite newSprite; if (connections != 0) { - newSprite = sprites[SPRITE_INDEX_MAP[connections]]; + return sprites[SPRITE_INDEX_MAP[connections]]; } else { int secondaryConnections = getSecondaryConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); - newSprite = sprites[SECONDARY_SPRITE_INDEX_MAP[secondaryConnections]]; + return sprites[SECONDARY_SPRITE_INDEX_MAP[secondaryConnections]]; } - return SimpleQuadProcessor.process(quad, sprite, newSprite); } protected int getSecondaryConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { @@ -62,14 +66,14 @@ protected int getSecondaryConnections(Direction[] directions, BlockPos.Mutable m return connections; } - public static class Factory extends AbstractQuadProcessorFactory { + public static class Factory implements SpriteProvider.Factory { @Override - public QuadProcessor createProcessor(StandardConnectingCTMProperties properties, Sprite[] sprites) { - return new HorizontalVerticalQuadProcessor(sprites, BaseProcessingPredicate.fromProperties(properties), properties.getConnectionPredicate(), properties.getInnerSeams()); + public SpriteProvider createSpriteProvider(Sprite[] sprites, OrientedConnectingCtmProperties properties) { + return new HorizontalVerticalSpriteProvider(sprites, properties.getConnectionPredicate(), properties.getInnerSeams(), properties.getOrientationMode()); } @Override - public int getTextureAmount(StandardConnectingCTMProperties properties) { + public int getTextureAmount(OrientedConnectingCtmProperties properties) { return 7; } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/RandomSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/RandomSpriteProvider.java index 1c9a057b..3fdf36b7 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/RandomSpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/RandomSpriteProvider.java @@ -7,7 +7,7 @@ import me.pepperbell.continuity.api.client.ProcessingDataProvider; import me.pepperbell.continuity.client.processor.ProcessingDataKeys; import me.pepperbell.continuity.client.processor.Symmetry; -import me.pepperbell.continuity.client.properties.RandomCTMProperties; +import me.pepperbell.continuity.client.properties.RandomCtmProperties; import me.pepperbell.continuity.client.util.MathUtil; import me.pepperbell.continuity.client.util.RandomIndexProvider; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; @@ -37,7 +37,7 @@ public RandomSpriteProvider(Sprite[] sprites, RandomIndexProvider indexProvider, @Override @Nullable public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { - Direction face = symmetry.getActualFace(quad.lightFace()); + Direction face = symmetry.apply(quad.lightFace()); int x = pos.getX(); int y = pos.getY(); @@ -59,9 +59,9 @@ public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, return sprites[indexProvider.getRandomIndex(seed)]; } - public static class Factory implements SpriteProvider.Factory { + public static class Factory implements SpriteProvider.Factory { @Override - public SpriteProvider createSpriteProvider(Sprite[] sprites, RandomCTMProperties properties) { + public SpriteProvider createSpriteProvider(Sprite[] sprites, RandomCtmProperties properties) { if (sprites.length == 1) { return new FixedSpriteProvider(sprites[0]); } @@ -69,7 +69,7 @@ public SpriteProvider createSpriteProvider(Sprite[] sprites, RandomCTMProperties } @Override - public int getTextureAmount(RandomCTMProperties properties) { + public int getTextureAmount(RandomCtmProperties properties) { return properties.getSpriteIds().size(); } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/RepeatSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/RepeatSpriteProvider.java index a90ff967..1c2a0491 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/RepeatSpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/RepeatSpriteProvider.java @@ -5,8 +5,9 @@ import org.jetbrains.annotations.Nullable; import me.pepperbell.continuity.api.client.ProcessingDataProvider; +import me.pepperbell.continuity.client.processor.OrientationMode; import me.pepperbell.continuity.client.processor.Symmetry; -import me.pepperbell.continuity.client.properties.RepeatCTMProperties; +import me.pepperbell.continuity.client.properties.RepeatCtmProperties; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.minecraft.block.BlockState; import net.minecraft.client.texture.Sprite; @@ -20,18 +21,20 @@ public class RepeatSpriteProvider implements SpriteProvider { protected int width; protected int height; protected Symmetry symmetry; + protected OrientationMode orientationMode; - public RepeatSpriteProvider(Sprite[] sprites, int width, int height, Symmetry symmetry) { + public RepeatSpriteProvider(Sprite[] sprites, int width, int height, Symmetry symmetry, OrientationMode orientationMode) { this.sprites = sprites; this.width = width; this.height = height; this.symmetry = symmetry; + this.orientationMode = orientationMode; } @Override @Nullable public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { - Direction face = symmetry.getActualFace(quad.lightFace()); + Direction face = symmetry.apply(quad.lightFace()); int x = pos.getX(); int y = pos.getY(); @@ -74,6 +77,39 @@ public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, } } + switch (orientationMode.getOrientation(quad, state)) { + case 1 -> { + int temp = spriteX; + spriteX = -spriteY - 1; + spriteY = temp; + } + case 2 -> { + spriteX = -spriteX - 1; + spriteY = -spriteY - 1; + } + case 3 -> { + int temp = spriteX; + spriteX = spriteY; + spriteY = -temp - 1; + } + case 4 -> { + int temp = spriteX; + spriteX = spriteY; + spriteY = temp; + } + case 5 -> { + spriteY = -spriteY - 1; + } + case 6 -> { + int temp = spriteX; + spriteX = -spriteY - 1; + spriteY = -temp - 1; + } + case 7 -> { + spriteX = -spriteX - 1; + } + } + spriteX %= width; if (spriteX < 0) { spriteX += width; @@ -86,14 +122,14 @@ public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, return sprites[width * spriteY + spriteX]; } - public static class Factory implements SpriteProvider.Factory { + public static class Factory implements SpriteProvider.Factory { @Override - public SpriteProvider createSpriteProvider(Sprite[] sprites, RepeatCTMProperties properties) { - return new RepeatSpriteProvider(sprites, properties.getWidth(), properties.getHeight(), properties.getSymmetry()); + public SpriteProvider createSpriteProvider(Sprite[] sprites, RepeatCtmProperties properties) { + return new RepeatSpriteProvider(sprites, properties.getWidth(), properties.getHeight(), properties.getSymmetry(), properties.getOrientationMode()); } @Override - public int getTextureAmount(RepeatCTMProperties properties) { + public int getTextureAmount(RepeatCtmProperties properties) { return properties.getWidth() * properties.getHeight(); } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/SimpleQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/SimpleQuadProcessor.java index 436e14c8..92101d7e 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/SimpleQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/SimpleQuadProcessor.java @@ -2,11 +2,13 @@ import java.util.function.Supplier; +import org.jetbrains.annotations.Nullable; + import me.pepperbell.continuity.api.client.QuadProcessor; import me.pepperbell.continuity.client.processor.AbstractQuadProcessorFactory; import me.pepperbell.continuity.client.processor.BaseProcessingPredicate; import me.pepperbell.continuity.client.processor.ProcessingPredicate; -import me.pepperbell.continuity.client.properties.BaseCTMProperties; +import me.pepperbell.continuity.client.properties.BaseCtmProperties; import me.pepperbell.continuity.client.util.QuadUtil; import me.pepperbell.continuity.client.util.TextureUtil; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; @@ -28,25 +30,24 @@ public SimpleQuadProcessor(SpriteProvider spriteProvider, ProcessingPredicate pr @Override public ProcessingResult processQuad(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { if (!processingPredicate.shouldProcessQuad(quad, sprite, blockView, state, pos, context)) { - return ProcessingResult.CONTINUE; + return ProcessingResult.NEXT_PROCESSOR; } Sprite newSprite = spriteProvider.getSprite(quad, sprite, blockView, state, pos, randomSupplier, context); return process(quad, sprite, newSprite); } - // TODO: rename? move? - public static ProcessingResult process(MutableQuadView quad, Sprite oldSprite, Sprite newSprite) { + public static ProcessingResult process(MutableQuadView quad, Sprite oldSprite, @Nullable Sprite newSprite) { if (newSprite == null) { - return ProcessingResult.ABORT_AND_RENDER_QUAD; + return ProcessingResult.STOP; } if (TextureUtil.isMissingSprite(newSprite)) { - return ProcessingResult.CONTINUE; + return ProcessingResult.NEXT_PROCESSOR; } QuadUtil.interpolate(quad, oldSprite, newSprite); - return ProcessingResult.STOP; + return ProcessingResult.NEXT_PASS; } - public static class Factory extends AbstractQuadProcessorFactory { + public static class Factory extends AbstractQuadProcessorFactory { protected SpriteProvider.Factory spriteProviderFactory; public Factory(SpriteProvider.Factory spriteProviderFactory) { diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/SpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/SpriteProvider.java index 87ab7d7f..5c87131c 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/simple/SpriteProvider.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/SpriteProvider.java @@ -5,7 +5,7 @@ import org.jetbrains.annotations.Nullable; import me.pepperbell.continuity.api.client.ProcessingDataProvider; -import me.pepperbell.continuity.client.properties.BaseCTMProperties; +import me.pepperbell.continuity.client.properties.BaseCtmProperties; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.minecraft.block.BlockState; import net.minecraft.client.texture.Sprite; @@ -17,7 +17,7 @@ public interface SpriteProvider { @Nullable Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider); - interface Factory { + interface Factory { SpriteProvider createSpriteProvider(Sprite[] sprites, T properties); int getTextureAmount(T properties); diff --git a/src/main/java/me/pepperbell/continuity/client/processor/VerticalHorizontalQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalHorizontalSpriteProvider.java similarity index 50% rename from src/main/java/me/pepperbell/continuity/client/processor/VerticalHorizontalQuadProcessor.java rename to src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalHorizontalSpriteProvider.java index 3a7a8dd9..dd455a84 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/VerticalHorizontalQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalHorizontalSpriteProvider.java @@ -1,11 +1,16 @@ -package me.pepperbell.continuity.client.processor; +package me.pepperbell.continuity.client.processor.simple; import java.util.function.Supplier; -import me.pepperbell.continuity.api.client.QuadProcessor; -import me.pepperbell.continuity.client.processor.simple.SimpleQuadProcessor; -import me.pepperbell.continuity.client.properties.StandardConnectingCTMProperties; -import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; +import org.jetbrains.annotations.Nullable; + +import me.pepperbell.continuity.api.client.ProcessingDataProvider; +import me.pepperbell.continuity.client.processor.ConnectionPredicate; +import me.pepperbell.continuity.client.processor.DirectionMaps; +import me.pepperbell.continuity.client.processor.OrientationMode; +import me.pepperbell.continuity.client.processor.ProcessingDataKeys; +import me.pepperbell.continuity.client.properties.OrientedConnectingCtmProperties; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; import net.minecraft.block.BlockState; import net.minecraft.client.texture.Sprite; import net.minecraft.util.math.BlockPos; @@ -13,7 +18,7 @@ import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; -public class VerticalHorizontalQuadProcessor extends VerticalQuadProcessor { +public class VerticalHorizontalSpriteProvider extends VerticalSpriteProvider { // Indices for this array are formed from these bit values: // 32 16 // 1 * 8 @@ -25,23 +30,22 @@ public class VerticalHorizontalQuadProcessor extends VerticalQuadProcessor { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, }; - public VerticalHorizontalQuadProcessor(Sprite[] sprites, ProcessingPredicate processingPredicate, ConnectionPredicate connectionPredicate, boolean innerSeams) { - super(sprites, processingPredicate, connectionPredicate, innerSeams); + public VerticalHorizontalSpriteProvider(Sprite[] sprites, ConnectionPredicate connectionPredicate, boolean innerSeams, OrientationMode orientationMode) { + super(sprites, connectionPredicate, innerSeams, orientationMode); } @Override - public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { - Direction[] directions = DirectionMaps.getDirections(quad); - BlockPos.Mutable mutablePos = context.getData(ProcessingDataKeys.MUTABLE_POS_KEY); + @Nullable + public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { + Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, state); + BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS_KEY); int connections = getConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); - Sprite newSprite; if (connections != 0) { - newSprite = sprites[SPRITE_INDEX_MAP[connections]]; + return sprites[SPRITE_INDEX_MAP[connections]]; } else { int secondaryConnections = getSecondaryConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); - newSprite = sprites[SECONDARY_SPRITE_INDEX_MAP[secondaryConnections]]; + return sprites[SECONDARY_SPRITE_INDEX_MAP[secondaryConnections]]; } - return SimpleQuadProcessor.process(quad, sprite, newSprite); } protected int getSecondaryConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { @@ -62,14 +66,14 @@ protected int getSecondaryConnections(Direction[] directions, BlockPos.Mutable m return connections; } - public static class Factory extends AbstractQuadProcessorFactory { + public static class Factory implements SpriteProvider.Factory { @Override - public QuadProcessor createProcessor(StandardConnectingCTMProperties properties, Sprite[] sprites) { - return new VerticalHorizontalQuadProcessor(sprites, BaseProcessingPredicate.fromProperties(properties), properties.getConnectionPredicate(), properties.getInnerSeams()); + public SpriteProvider createSpriteProvider(Sprite[] sprites, OrientedConnectingCtmProperties properties) { + return new VerticalHorizontalSpriteProvider(sprites, properties.getConnectionPredicate(), properties.getInnerSeams(), properties.getOrientationMode()); } @Override - public int getTextureAmount(StandardConnectingCTMProperties properties) { + public int getTextureAmount(OrientedConnectingCtmProperties properties) { return 7; } } diff --git a/src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalSpriteProvider.java b/src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalSpriteProvider.java new file mode 100644 index 00000000..b3489e5a --- /dev/null +++ b/src/main/java/me/pepperbell/continuity/client/processor/simple/VerticalSpriteProvider.java @@ -0,0 +1,73 @@ +package me.pepperbell.continuity.client.processor.simple; + +import java.util.function.Supplier; + +import org.jetbrains.annotations.Nullable; + +import me.pepperbell.continuity.api.client.ProcessingDataProvider; +import me.pepperbell.continuity.client.processor.ConnectionPredicate; +import me.pepperbell.continuity.client.processor.DirectionMaps; +import me.pepperbell.continuity.client.processor.OrientationMode; +import me.pepperbell.continuity.client.processor.ProcessingDataKeys; +import me.pepperbell.continuity.client.properties.OrientedConnectingCtmProperties; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadView; +import net.minecraft.block.BlockState; +import net.minecraft.client.texture.Sprite; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.random.Random; +import net.minecraft.world.BlockRenderView; + +public class VerticalSpriteProvider implements SpriteProvider { + // Indices for this array are formed from these bit values: + // 2 + // * + // 1 + protected static final int[] SPRITE_INDEX_MAP = new int[] { + 3, 2, 0, 1, + }; + + protected Sprite[] sprites; + protected ConnectionPredicate connectionPredicate; + protected boolean innerSeams; + protected OrientationMode orientationMode; + + public VerticalSpriteProvider(Sprite[] sprites, ConnectionPredicate connectionPredicate, boolean innerSeams, OrientationMode orientationMode) { + this.sprites = sprites; + this.connectionPredicate = connectionPredicate; + this.innerSeams = innerSeams; + this.orientationMode = orientationMode; + } + + @Override + @Nullable + public Sprite getSprite(QuadView quad, Sprite sprite, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, ProcessingDataProvider dataProvider) { + Direction[] directions = DirectionMaps.getDirections(orientationMode, quad, state); + BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS_KEY); + int connections = getConnections(directions, mutablePos, blockView, state, pos, quad.lightFace(), sprite); + return sprites[SPRITE_INDEX_MAP[connections]]; + } + + protected int getConnections(Direction[] directions, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState state, BlockPos pos, Direction face, Sprite quadSprite) { + int connections = 0; + for (int i = 0; i < 2; i++) { + mutablePos.set(pos, directions[i * 2 + 1]); + if (connectionPredicate.shouldConnect(blockView, state, pos, mutablePos, face, quadSprite, innerSeams)) { + connections |= 1 << i; + } + } + return connections; + } + + public static class Factory implements SpriteProvider.Factory { + @Override + public SpriteProvider createSpriteProvider(Sprite[] sprites, OrientedConnectingCtmProperties properties) { + return new VerticalSpriteProvider(sprites, properties.getConnectionPredicate(), properties.getInnerSeams(), properties.getOrientationMode()); + } + + @Override + public int getTextureAmount(OrientedConnectingCtmProperties properties) { + return 4; + } + } +} diff --git a/src/main/java/me/pepperbell/continuity/client/properties/BaseCTMProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/BaseCtmProperties.java similarity index 88% rename from src/main/java/me/pepperbell/continuity/client/properties/BaseCTMProperties.java rename to src/main/java/me/pepperbell/continuity/client/properties/BaseCtmProperties.java index 36432566..0f687b8b 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/BaseCTMProperties.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/BaseCtmProperties.java @@ -21,8 +21,7 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -import me.pepperbell.continuity.api.client.CTMProperties; -import me.pepperbell.continuity.api.client.CTMPropertiesFactory; +import me.pepperbell.continuity.api.client.CtmProperties; import me.pepperbell.continuity.client.ContinuityClient; import me.pepperbell.continuity.client.resource.ResourceRedirectHandler; import me.pepperbell.continuity.client.util.MathUtil; @@ -32,7 +31,6 @@ import me.pepperbell.continuity.client.util.biome.BiomeSetPredicate; import net.minecraft.block.Block; import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; import net.minecraft.client.MinecraftClient; import net.minecraft.client.util.SpriteIdentifier; import net.minecraft.registry.Registries; @@ -45,7 +43,7 @@ import net.minecraft.util.math.Direction; import net.minecraft.world.biome.Biome; -public class BaseCTMProperties implements CTMProperties { +public class BaseCtmProperties implements CtmProperties { public static final Identifier SPECIAL_SKIP_ID = ContinuityClient.asId("special/skip"); public static final Identifier SPECIAL_DEFAULT_ID = ContinuityClient.asId("special/default"); public static final SpriteIdentifier SPECIAL_SKIP_SPRITE_ID = TextureUtil.toSpriteId(SPECIAL_SKIP_ID); @@ -54,7 +52,7 @@ public class BaseCTMProperties implements CTMProperties { protected static final int DIRECTION_AMOUNT = Direction.values().length; protected Properties properties; - protected Identifier id; + protected Identifier resourceId; protected String packName; protected int packPriority; protected ResourceManager resourceManager; @@ -80,9 +78,9 @@ public class BaseCTMProperties implements CTMProperties { protected Set textureDependencies; protected List spriteIds; - public BaseCTMProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { + public BaseCtmProperties(Properties properties, Identifier resourceId, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { this.properties = properties; - this.id = id; + this.resourceId = resourceId; this.packName = pack.getName(); this.packPriority = packPriority; this.resourceManager = resourceManager; @@ -104,8 +102,8 @@ public Set getTextureDependencies() { 1 this > o */ @Override - public int compareTo(@NotNull CTMProperties o) { - if (o instanceof BaseCTMProperties o1) { + public int compareTo(@NotNull CtmProperties o) { + if (o instanceof BaseCtmProperties o1) { if (prioritized && !o1.prioritized) { return 1; } @@ -116,7 +114,7 @@ public int compareTo(@NotNull CTMProperties o) { if (c != 0) { return c; } - return o1.getId().compareTo(getId()); + return o1.getResourceId().compareTo(getResourceId()); } return 0; } @@ -137,27 +135,27 @@ public void init() { } protected void parseMatchTiles() { - matchTilesSet = PropertiesParsingHelper.parseMatchTiles(properties, "matchTiles", id, packName, ResourceRedirectHandler.get(resourceManager)); + matchTilesSet = PropertiesParsingHelper.parseMatchTiles(properties, "matchTiles", resourceId, packName, ResourceRedirectHandler.get(resourceManager)); if (matchTilesSet != null && matchTilesSet.isEmpty()) { valid = false; } } protected void parseMatchBlocks() { - matchBlocksPredicate = PropertiesParsingHelper.parseBlockStates(properties, "matchBlocks", id, packName); + matchBlocksPredicate = PropertiesParsingHelper.parseBlockStates(properties, "matchBlocks", resourceId, packName); if (matchBlocksPredicate == PropertiesParsingHelper.EMPTY_BLOCK_STATE_PREDICATE) { valid = false; } } protected void detectMatches() { - String baseName = FilenameUtils.getBaseName(id.getPath()); + String baseName = FilenameUtils.getBaseName(resourceId.getPath()); if (matchBlocksPredicate == null) { if (baseName.startsWith("block_")) { try { Identifier id = new Identifier(baseName.substring(6)); - Block block = Registries.BLOCK.get(id); - if (block != Blocks.AIR) { + if (Registries.BLOCK.containsId(id)) { + Block block = Registries.BLOCK.get(id); matchBlocksPredicate = state -> state.getBlock() == block; } } catch (InvalidIdentifierException e) { @@ -169,7 +167,7 @@ protected void detectMatches() { protected void validateMatches() { if (matchTilesSet == null && matchBlocksPredicate == null) { - ContinuityClient.LOGGER.error("No tile or block matches provided in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.error("No tile or block matches provided in file '" + resourceId + "' in pack '" + packName + "'"); valid = false; } } @@ -177,14 +175,14 @@ protected void validateMatches() { protected void parseTiles() { String tilesStr = properties.getProperty("tiles"); if (tilesStr == null) { - ContinuityClient.LOGGER.error("No 'tiles' value provided in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.error("No 'tiles' value provided in file '" + resourceId + "' in pack '" + packName + "'"); valid = false; return; } String[] tileStrs = tilesStr.trim().split("[ ,]"); if (tileStrs.length != 0) { - String basePath = FilenameUtils.getPath(id.getPath()); + String basePath = FilenameUtils.getPath(resourceId.getPath()); ImmutableList.Builder listBuilder = ImmutableList.builder(); for (int i = 0; i < tileStrs.length; i++) { @@ -210,13 +208,13 @@ protected void parseTiles() { if (min <= max) { try { for (int tile = min; tile <= max; tile++) { - listBuilder.add(new Identifier(id.getNamespace(), basePath + tile + ".png")); + listBuilder.add(new Identifier(resourceId.getNamespace(), basePath + tile + ".png")); } } catch (InvalidIdentifierException e) { - ContinuityClient.LOGGER.warn("Invalid 'tiles' element '" + tileStr + "' at index " + i + " in file '" + id + "' in pack '" + packName + "'", e); + ContinuityClient.LOGGER.warn("Invalid 'tiles' element '" + tileStr + "' at index " + i + " in file '" + resourceId + "' in pack '" + packName + "'", e); } } else { - ContinuityClient.LOGGER.warn("Invalid 'tiles' element '" + tileStr + "' at index " + i + " in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.warn("Invalid 'tiles' element '" + tileStr + "' at index " + i + " in file '" + resourceId + "' in pack '" + packName + "'"); } continue; } catch (NumberFormatException e) { @@ -256,7 +254,7 @@ protected void parseTiles() { } if (path.startsWith("optifine/")) { - namespace = id.getNamespace(); + namespace = resourceId.getNamespace(); } } else { if (!path.contains("/")) { @@ -273,11 +271,11 @@ protected void parseTiles() { try { listBuilder.add(new Identifier(namespace, path)); } catch (InvalidIdentifierException e) { - ContinuityClient.LOGGER.warn("Invalid 'tiles' element '" + tileStr + "' at index " + i + " in file '" + id + "' in pack '" + packName + "'", e); + ContinuityClient.LOGGER.warn("Invalid 'tiles' element '" + tileStr + "' at index " + i + " in file '" + resourceId + "' in pack '" + packName + "'", e); } } } else { - ContinuityClient.LOGGER.warn("Invalid 'tiles' element '" + tileStr + "' at index " + i + " in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.warn("Invalid 'tiles' element '" + tileStr + "' at index " + i + " in file '" + resourceId + "' in pack '" + packName + "'"); } } @@ -315,7 +313,7 @@ protected void parseFaces() { try { faces.add(Direction.valueOf(faceStr1)); } catch (IllegalArgumentException e) { - ContinuityClient.LOGGER.warn("Unknown 'faces' element '" + faceStr + "' at index " + i + " in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.warn("Unknown 'faces' element '" + faceStr + "' at index " + i + " in file '" + resourceId + "' in pack '" + packName + "'"); } } } @@ -358,7 +356,7 @@ protected void parseBiomes() { Identifier biomeId = new Identifier(biomeStr.toLowerCase(Locale.ROOT)); biomeHolderSet.add(BiomeHolderManager.getOrCreateHolder(biomeId)); } catch (InvalidIdentifierException e) { - ContinuityClient.LOGGER.warn("Invalid 'biomes' element '" + biomeStr + "' at index " + i + " in file '" + id + "' in pack '" + packName + "'", e); + ContinuityClient.LOGGER.warn("Invalid 'biomes' element '" + biomeStr + "' at index " + i + " in file '" + resourceId + "' in pack '" + packName + "'", e); } } @@ -448,7 +446,7 @@ protected void parseHeights() { } } } - ContinuityClient.LOGGER.warn("Invalid 'heights' element '" + heightStr + "' at index " + i + " in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.warn("Invalid 'heights' element '" + heightStr + "' at index " + i + " in file '" + resourceId + "' in pack '" + packName + "'"); } if (!predicateList.isEmpty()) { @@ -482,7 +480,7 @@ protected void parseLegacyHeights() { try { min = Integer.parseInt(minHeightStr.trim()); } catch (NumberFormatException e) { - ContinuityClient.LOGGER.warn("Invalid 'minHeight' value '" + minHeightStr + "' in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.warn("Invalid 'minHeight' value '" + minHeightStr + "' in file '" + resourceId + "' in pack '" + packName + "'"); hasMinHeight = false; } } @@ -490,7 +488,7 @@ protected void parseLegacyHeights() { try { max = Integer.parseInt(maxHeightStr.trim()); } catch (NumberFormatException e) { - ContinuityClient.LOGGER.warn("Invalid 'maxHeight' value '" + minHeightStr + "' in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.warn("Invalid 'maxHeight' value '" + minHeightStr + "' in file '" + resourceId + "' in pack '" + packName + "'"); hasMaxHeight = false; } } @@ -588,7 +586,7 @@ protected void parseResourceCondition() { try { resourceId = new Identifier(resourceStr); } catch (InvalidIdentifierException e) { - ContinuityClient.LOGGER.warn("Invalid resource '" + resourceStr + "' in 'resourceCondition' element '" + conditionStr + "' at index " + i + " in file '" + id + "' in pack '" + packName + "'", e); + ContinuityClient.LOGGER.warn("Invalid resource '" + resourceStr + "' in 'resourceCondition' element '" + conditionStr + "' at index " + i + " in file '" + this.resourceId + "' in pack '" + packName + "'", e); continue; } @@ -612,10 +610,10 @@ protected void parseResourceCondition() { break; } } else { - ContinuityClient.LOGGER.warn("Unknown pack '" + packStr + "' in 'resourceCondition' element '" + conditionStr + "' at index " + i + " in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.warn("Unknown pack '" + packStr + "' in 'resourceCondition' element '" + conditionStr + "' at index " + i + " in file '" + this.resourceId + "' in pack '" + packName + "'"); } } else { - ContinuityClient.LOGGER.warn("Invalid 'resourceCondition' element '" + conditionStr + "' at index " + i + " in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.warn("Invalid 'resourceCondition' element '" + conditionStr + "' at index " + i + " in file '" + resourceId + "' in pack '" + packName + "'"); } } } @@ -664,8 +662,8 @@ public Properties getProperties() { return properties; } - public Identifier getId() { - return id; + public Identifier getResourceId() { + return resourceId; } public String getPackName() { @@ -725,9 +723,9 @@ public List getSpriteIds() { return spriteIds; } - public static CTMPropertiesFactory wrapFactory(CTMPropertiesFactory factory) { - return (properties, id, pack, packPriority, resourceManager, method) -> { - T ctmProperties = factory.createProperties(properties, id, pack, packPriority, resourceManager, method); + public static Factory wrapFactory(Factory factory) { + return (properties, resourceId, pack, packPriority, resourceManager, method) -> { + T ctmProperties = factory.createProperties(properties, resourceId, pack, packPriority, resourceManager, method); if (ctmProperties == null) { return null; } diff --git a/src/main/java/me/pepperbell/continuity/client/properties/ConnectingCTMProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/BasicConnectingCtmProperties.java similarity index 87% rename from src/main/java/me/pepperbell/continuity/client/properties/ConnectingCTMProperties.java rename to src/main/java/me/pepperbell/continuity/client/properties/BasicConnectingCtmProperties.java index 11ff62bf..ee4ddf35 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/ConnectingCTMProperties.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/BasicConnectingCtmProperties.java @@ -15,11 +15,11 @@ import net.minecraft.util.math.Direction; import net.minecraft.world.BlockRenderView; -public class ConnectingCTMProperties extends BaseCTMProperties { +public class BasicConnectingCtmProperties extends BaseCtmProperties { protected ConnectionPredicate connectionPredicate; - public ConnectingCTMProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { - super(properties, id, pack, packPriority, resourceManager, method); + public BasicConnectingCtmProperties(Properties properties, Identifier resourceId, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { + super(properties, resourceId, pack, packPriority, resourceManager, method); } @Override @@ -55,7 +55,7 @@ protected void detectConnect() { protected void validateConnect() { if (connectionPredicate == null) { - ContinuityClient.LOGGER.error("No valid connection type provided in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.error("No valid connection type provided in file '" + resourceId + "' in pack '" + packName + "'"); valid = false; } } diff --git a/src/main/java/me/pepperbell/continuity/client/properties/CompactConnectingCTMProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/CompactConnectingCtmProperties.java similarity index 62% rename from src/main/java/me/pepperbell/continuity/client/properties/CompactConnectingCTMProperties.java rename to src/main/java/me/pepperbell/continuity/client/properties/CompactConnectingCtmProperties.java index 9763b50a..e55b9672 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/CompactConnectingCTMProperties.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/CompactConnectingCtmProperties.java @@ -7,16 +7,21 @@ import it.unimi.dsi.fastutil.ints.Int2IntArrayMap; import it.unimi.dsi.fastutil.ints.Int2IntMap; import me.pepperbell.continuity.client.ContinuityClient; +import me.pepperbell.continuity.client.processor.OrientationMode; import net.minecraft.resource.ResourceManager; import net.minecraft.resource.ResourcePack; import net.minecraft.util.Identifier; -public class CompactConnectingCTMProperties extends StandardConnectingCTMProperties { +public class CompactConnectingCtmProperties extends OrientedConnectingCtmProperties { @Nullable protected Int2IntMap tileReplacementMap; - public CompactConnectingCTMProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { - super(properties, id, pack, packPriority, resourceManager, method); + public CompactConnectingCtmProperties(Properties properties, Identifier resourceId, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method, OrientationMode defaultOrientationMode) { + super(properties, resourceId, pack, packPriority, resourceManager, method, defaultOrientationMode); + } + + public CompactConnectingCtmProperties(Properties properties, Identifier resourceId, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { + this(properties, resourceId, pack, packPriority, resourceManager, method, OrientationMode.TEXTURE); } @Override @@ -44,12 +49,12 @@ protected void parseTileReplacements() { try { value = Integer.parseInt(valueStr); } catch (NumberFormatException e) { - ContinuityClient.LOGGER.warn("Invalid '" + key + "' value '" + valueStr + "' in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.warn("Invalid '" + key + "' value '" + valueStr + "' in file '" + resourceId + "' in pack '" + packName + "'"); continue; } // TODO: deduplicate code if (value < 0) { - ContinuityClient.LOGGER.warn("Invalid '" + key + "' value '" + valueStr + "' in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.warn("Invalid '" + key + "' value '" + valueStr + "' in file '" + resourceId + "' in pack '" + packName + "'"); continue; } diff --git a/src/main/java/me/pepperbell/continuity/client/properties/StandardConnectingCTMProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/ConnectingCtmProperties.java similarity index 69% rename from src/main/java/me/pepperbell/continuity/client/properties/StandardConnectingCTMProperties.java rename to src/main/java/me/pepperbell/continuity/client/properties/ConnectingCtmProperties.java index 8d2cd17a..bd92e602 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/StandardConnectingCTMProperties.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/ConnectingCtmProperties.java @@ -6,11 +6,11 @@ import net.minecraft.resource.ResourcePack; import net.minecraft.util.Identifier; -public class StandardConnectingCTMProperties extends ConnectingCTMProperties { +public class ConnectingCtmProperties extends BasicConnectingCtmProperties { protected boolean innerSeams = false; - public StandardConnectingCTMProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { - super(properties, id, pack, packPriority, resourceManager, method); + public ConnectingCtmProperties(Properties properties, Identifier resourceId, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { + super(properties, resourceId, pack, packPriority, resourceManager, method); } @Override diff --git a/src/main/java/me/pepperbell/continuity/client/properties/OrientedConnectingCtmProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/OrientedConnectingCtmProperties.java new file mode 100644 index 00000000..420f7a1d --- /dev/null +++ b/src/main/java/me/pepperbell/continuity/client/properties/OrientedConnectingCtmProperties.java @@ -0,0 +1,38 @@ +package me.pepperbell.continuity.client.properties; + +import java.util.Properties; + +import me.pepperbell.continuity.client.processor.OrientationMode; +import net.minecraft.resource.ResourceManager; +import net.minecraft.resource.ResourcePack; +import net.minecraft.util.Identifier; + +public class OrientedConnectingCtmProperties extends ConnectingCtmProperties { + protected OrientationMode orientationMode; + + public OrientedConnectingCtmProperties(Properties properties, Identifier resourceId, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method, OrientationMode defaultOrientationMode) { + super(properties, resourceId, pack, packPriority, resourceManager, method); + orientationMode = defaultOrientationMode; + } + + public OrientedConnectingCtmProperties(Properties properties, Identifier resourceId, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { + this(properties, resourceId, pack, packPriority, resourceManager, method, OrientationMode.TEXTURE); + } + + @Override + public void init() { + super.init(); + parseOrient(); + } + + protected void parseOrient() { + OrientationMode orientationMode = PropertiesParsingHelper.parseOrientationMode(properties, "orient", resourceId, packName); + if (orientationMode != null) { + this.orientationMode = orientationMode; + } + } + + public OrientationMode getOrientationMode() { + return orientationMode; + } +} 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 aba1eedd..ed914a4a 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/PropertiesParsingHelper.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/PropertiesParsingHelper.java @@ -21,11 +21,11 @@ import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap; import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; import me.pepperbell.continuity.client.ContinuityClient; +import me.pepperbell.continuity.client.processor.OrientationMode; import me.pepperbell.continuity.client.processor.Symmetry; import me.pepperbell.continuity.client.resource.ResourceRedirectHandler; import net.minecraft.block.Block; import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; import net.minecraft.registry.Registries; import net.minecraft.state.property.Property; import net.minecraft.util.Identifier; @@ -150,8 +150,8 @@ public static Predicate parseBlockStates(Properties properties, Stri continue; } - Block block = Registries.BLOCK.get(blockId); - if (block != Blocks.AIR) { + if (Registries.BLOCK.containsId(blockId)) { + Block block = Registries.BLOCK.get(blockId); if (!blockSet.contains(block)) { if (parts.length > startIndex) { Object2ObjectOpenHashMap, ObjectOpenHashSet>> propertyMap = new Object2ObjectOpenHashMap<>(); @@ -280,6 +280,21 @@ public static Symmetry parseSymmetry(Properties properties, String propertyKey, return null; } + @Nullable + public static OrientationMode parseOrientationMode(Properties properties, String propertyKey, Identifier fileLocation, String packName) { + String orientationModeStr = properties.getProperty(propertyKey); + if (orientationModeStr == null) { + return null; + } + + try { + return OrientationMode.valueOf(orientationModeStr.trim().toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + ContinuityClient.LOGGER.warn("Unknown '" + propertyKey + "' value '" + orientationModeStr + "' in file '" + fileLocation + "' in pack '" + packName + "'"); + } + return null; + } + public static boolean parseOptifineOnly(Properties properties, Identifier fileLocation) { if (!fileLocation.getNamespace().equals(Identifier.DEFAULT_NAMESPACE)) { return false; diff --git a/src/main/java/me/pepperbell/continuity/client/properties/RandomCTMProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/RandomCtmProperties.java similarity index 85% rename from src/main/java/me/pepperbell/continuity/client/properties/RandomCTMProperties.java rename to src/main/java/me/pepperbell/continuity/client/properties/RandomCtmProperties.java index 71bfd0c4..f7eea826 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/RandomCTMProperties.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/RandomCtmProperties.java @@ -11,14 +11,14 @@ import net.minecraft.resource.ResourcePack; import net.minecraft.util.Identifier; -public class RandomCTMProperties extends BaseCTMProperties { +public class RandomCtmProperties extends BaseCtmProperties { protected RandomIndexProvider.Factory indexProviderFactory = RandomIndexProvider.UnweightedFactory.INSTANCE; protected int randomLoops = 0; protected Symmetry symmetry = Symmetry.NONE; protected boolean linked = false; - public RandomCTMProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { - super(properties, id, pack, packPriority, resourceManager, method); + public RandomCtmProperties(Properties properties, Identifier resourceId, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { + super(properties, resourceId, pack, packPriority, resourceManager, method); } @Override @@ -67,7 +67,7 @@ protected void parseWeights() { } catch (NumberFormatException e) { // } - ContinuityClient.LOGGER.warn("Invalid 'weights' element '" + weightStr + "' at index '" + i + "' in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.warn("Invalid 'weights' element '" + weightStr + "' at index '" + i + "' in file '" + resourceId + "' in pack '" + packName + "'"); } if (!weights.isEmpty()) { @@ -91,11 +91,11 @@ protected void parseRandomLoops() { } catch (NumberFormatException e) { // } - ContinuityClient.LOGGER.warn("Invalid 'randomLoops' value '" + randomLoopsStr + "' in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.warn("Invalid 'randomLoops' value '" + randomLoopsStr + "' in file '" + resourceId + "' in pack '" + packName + "'"); } protected void parseSymmetry() { - Symmetry symmetry = PropertiesParsingHelper.parseSymmetry(properties, "symmetry", id, packName); + Symmetry symmetry = PropertiesParsingHelper.parseSymmetry(properties, "symmetry", resourceId, packName); if (symmetry != null) { this.symmetry = symmetry; } diff --git a/src/main/java/me/pepperbell/continuity/client/properties/RepeatCTMProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/RepeatCtmProperties.java similarity index 63% rename from src/main/java/me/pepperbell/continuity/client/properties/RepeatCTMProperties.java rename to src/main/java/me/pepperbell/continuity/client/properties/RepeatCtmProperties.java index a97f5b93..9f93c7ff 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/RepeatCTMProperties.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/RepeatCtmProperties.java @@ -3,18 +3,20 @@ import java.util.Properties; import me.pepperbell.continuity.client.ContinuityClient; +import me.pepperbell.continuity.client.processor.OrientationMode; import me.pepperbell.continuity.client.processor.Symmetry; import net.minecraft.resource.ResourceManager; import net.minecraft.resource.ResourcePack; import net.minecraft.util.Identifier; -public class RepeatCTMProperties extends BaseCTMProperties { +public class RepeatCtmProperties extends BaseCtmProperties { protected int width; protected int height; protected Symmetry symmetry = Symmetry.NONE; + protected OrientationMode orientationMode = OrientationMode.NONE; - public RepeatCTMProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { - super(properties, id, pack, packPriority, resourceManager, method); + public RepeatCtmProperties(Properties properties, Identifier resourceId, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { + super(properties, resourceId, pack, packPriority, resourceManager, method); } @Override @@ -23,12 +25,13 @@ public void init() { parseWidth(); parseHeight(); parseSymmetry(); + parseOrient(); } protected void parseWidth() { String widthStr = properties.getProperty("width"); if (widthStr == null) { - ContinuityClient.LOGGER.error("No 'width' value provided in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.error("No 'width' value provided in file '" + resourceId + "' in pack '" + packName + "'"); valid = false; return; } @@ -42,14 +45,14 @@ protected void parseWidth() { } catch (NumberFormatException e) { // } - ContinuityClient.LOGGER.error("Invalid 'width' value '" + widthStr + "' in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.error("Invalid 'width' value '" + widthStr + "' in file '" + resourceId + "' in pack '" + packName + "'"); valid = false; } protected void parseHeight() { String heightStr = properties.getProperty("height"); if (heightStr == null) { - ContinuityClient.LOGGER.error("No 'height' value provided in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.error("No 'height' value provided in file '" + resourceId + "' in pack '" + packName + "'"); valid = false; return; } @@ -63,17 +66,24 @@ protected void parseHeight() { } catch (NumberFormatException e) { // } - ContinuityClient.LOGGER.error("Invalid 'height' value '" + heightStr + "' in file '" + id + "' in pack '" + packName + "'"); + ContinuityClient.LOGGER.error("Invalid 'height' value '" + heightStr + "' in file '" + resourceId + "' in pack '" + packName + "'"); valid = false; } protected void parseSymmetry() { - Symmetry symmetry = PropertiesParsingHelper.parseSymmetry(properties, "symmetry", id, packName); + Symmetry symmetry = PropertiesParsingHelper.parseSymmetry(properties, "symmetry", resourceId, packName); if (symmetry != null) { this.symmetry = symmetry; } } + protected void parseOrient() { + OrientationMode orientationMode = PropertiesParsingHelper.parseOrientationMode(properties, "orient", resourceId, packName); + if (orientationMode != null) { + this.orientationMode = orientationMode; + } + } + public int getWidth() { return width; } @@ -86,14 +96,18 @@ public Symmetry getSymmetry() { return symmetry; } - public static class Validator implements TileAmountValidator { + public OrientationMode getOrientationMode() { + return orientationMode; + } + + public static class Validator implements TileAmountValidator { @Override public boolean validateTileAmount(int amount, T properties) { int targetAmount = properties.getWidth() * properties.getHeight(); if (amount == targetAmount) { return true; } - ContinuityClient.LOGGER.error("Method '" + properties.getMethod() + "' requires exactly " + targetAmount + " tiles but " + amount + " were provided in file '" + properties.getId() + "' in pack '" + properties.getPackName() + "'"); + ContinuityClient.LOGGER.error("Method '" + properties.getMethod() + "' requires exactly " + targetAmount + " tiles but " + amount + " were provided in file '" + properties.getResourceId() + "' in pack '" + properties.getPackName() + "'"); return false; } } diff --git a/src/main/java/me/pepperbell/continuity/client/properties/TileAmountValidator.java b/src/main/java/me/pepperbell/continuity/client/properties/TileAmountValidator.java index 0506f836..589e686d 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/TileAmountValidator.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/TileAmountValidator.java @@ -1,14 +1,14 @@ package me.pepperbell.continuity.client.properties; -import me.pepperbell.continuity.api.client.CTMPropertiesFactory; +import me.pepperbell.continuity.api.client.CtmProperties; import me.pepperbell.continuity.client.ContinuityClient; -public interface TileAmountValidator { +public interface TileAmountValidator { boolean validateTileAmount(int amount, T properties); - static CTMPropertiesFactory wrapFactory(CTMPropertiesFactory factory, TileAmountValidator validator) { - return (properties, id, pack, packPriority, resourceManager, method) -> { - T ctmProperties = factory.createProperties(properties, id, pack, packPriority, resourceManager, method); + static CtmProperties.Factory wrapFactory(CtmProperties.Factory factory, TileAmountValidator validator) { + return (properties, resourceId, pack, packPriority, resourceManager, method) -> { + T ctmProperties = factory.createProperties(properties, resourceId, pack, packPriority, resourceManager, method); if (ctmProperties == null) { return null; } @@ -19,7 +19,7 @@ static CTMPropertiesFactory wrapFactory(CTMProp }; } - class Exactly implements TileAmountValidator { + class Exactly implements TileAmountValidator { protected final int targetAmount; public Exactly(int targetAmount) { @@ -31,12 +31,12 @@ public boolean validateTileAmount(int amount, T properties) { if (amount == targetAmount) { return true; } - ContinuityClient.LOGGER.error("Method '" + properties.getMethod() + "' requires exactly " + targetAmount + " tiles but " + amount + " were provided in file '" + properties.getId() + "' in pack '" + properties.getPackName() + "'"); + ContinuityClient.LOGGER.error("Method '" + properties.getMethod() + "' requires exactly " + targetAmount + " tiles but " + amount + " were provided in file '" + properties.getResourceId() + "' in pack '" + properties.getPackName() + "'"); return false; } } - class AtLeast implements TileAmountValidator { + class AtLeast implements TileAmountValidator { protected final int targetAmount; public AtLeast(int targetAmount) { @@ -48,7 +48,7 @@ public boolean validateTileAmount(int amount, T properties) { if (amount >= targetAmount) { return true; } - ContinuityClient.LOGGER.error("Method '" + properties.getMethod() + "' requires at least " + targetAmount + " tiles but only " + amount + " were provided in file '" + properties.getId() + "' in pack '" + properties.getPackName() + "'"); + ContinuityClient.LOGGER.error("Method '" + properties.getMethod() + "' requires at least " + targetAmount + " tiles but only " + amount + " were provided in file '" + properties.getResourceId() + "' in pack '" + properties.getPackName() + "'"); return false; } } diff --git a/src/main/java/me/pepperbell/continuity/client/properties/overlay/BaseOverlayCTMProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/overlay/BaseOverlayCtmProperties.java similarity index 79% rename from src/main/java/me/pepperbell/continuity/client/properties/overlay/BaseOverlayCTMProperties.java rename to src/main/java/me/pepperbell/continuity/client/properties/overlay/BaseOverlayCtmProperties.java index 09cdd647..a6769b09 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/overlay/BaseOverlayCTMProperties.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/overlay/BaseOverlayCtmProperties.java @@ -2,15 +2,15 @@ import java.util.Properties; -import me.pepperbell.continuity.client.properties.BaseCTMProperties; +import me.pepperbell.continuity.client.properties.BaseCtmProperties; import net.minecraft.resource.ResourceManager; import net.minecraft.resource.ResourcePack; import net.minecraft.util.Identifier; -public class BaseOverlayCTMProperties extends BaseCTMProperties implements OverlayPropertiesSection.Provider { +public class BaseOverlayCtmProperties extends BaseCtmProperties implements OverlayPropertiesSection.Provider { protected OverlayPropertiesSection overlaySection; - public BaseOverlayCTMProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { + public BaseOverlayCtmProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { super(properties, id, pack, packPriority, resourceManager, method); overlaySection = new OverlayPropertiesSection(properties, id, packName); } diff --git a/src/main/java/me/pepperbell/continuity/client/properties/overlay/OrientedConnectingOverlayCtmProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/overlay/OrientedConnectingOverlayCtmProperties.java new file mode 100644 index 00000000..5ad4de29 --- /dev/null +++ b/src/main/java/me/pepperbell/continuity/client/properties/overlay/OrientedConnectingOverlayCtmProperties.java @@ -0,0 +1,33 @@ +package me.pepperbell.continuity.client.properties.overlay; + +import java.util.Properties; + +import me.pepperbell.continuity.client.processor.OrientationMode; +import me.pepperbell.continuity.client.properties.OrientedConnectingCtmProperties; +import net.minecraft.resource.ResourceManager; +import net.minecraft.resource.ResourcePack; +import net.minecraft.util.Identifier; + +public class OrientedConnectingOverlayCtmProperties extends OrientedConnectingCtmProperties implements OverlayPropertiesSection.Provider { + protected OverlayPropertiesSection overlaySection; + + public OrientedConnectingOverlayCtmProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method, OrientationMode defaultOrientationMode) { + super(properties, id, pack, packPriority, resourceManager, method, defaultOrientationMode); + overlaySection = new OverlayPropertiesSection(properties, id, packName); + } + + public OrientedConnectingOverlayCtmProperties(Properties properties, Identifier resourceId, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { + this(properties, resourceId, pack, packPriority, resourceManager, method, OrientationMode.NONE); + } + + @Override + public void init() { + super.init(); + overlaySection.init(); + } + + @Override + public OverlayPropertiesSection getOverlayPropertiesSection() { + return overlaySection; + } +} diff --git a/src/main/java/me/pepperbell/continuity/client/properties/overlay/OverlayPropertiesSection.java b/src/main/java/me/pepperbell/continuity/client/properties/overlay/OverlayPropertiesSection.java index 1bce26dc..f05d185d 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/overlay/OverlayPropertiesSection.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/overlay/OverlayPropertiesSection.java @@ -9,7 +9,6 @@ import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; import net.minecraft.block.Block; import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; import net.minecraft.registry.Registries; import net.minecraft.util.Identifier; import net.minecraft.util.InvalidIdentifierException; @@ -74,8 +73,8 @@ protected void parseTintBlock() { return; } - Block block = Registries.BLOCK.get(blockId); - if (block != Blocks.AIR) { + if (Registries.BLOCK.containsId(blockId)) { + Block block = Registries.BLOCK.get(blockId); tintBlock = block.getDefaultState(); } else { ContinuityClient.LOGGER.warn("Unknown block '" + blockId + "' in 'tintBlock' value '" + tintBlockStr + "' in file '" + id + "' in pack '" + packName + "'"); diff --git a/src/main/java/me/pepperbell/continuity/client/properties/overlay/RepeatOverlayCTMProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/overlay/RandomOverlayCtmProperties.java similarity index 79% rename from src/main/java/me/pepperbell/continuity/client/properties/overlay/RepeatOverlayCTMProperties.java rename to src/main/java/me/pepperbell/continuity/client/properties/overlay/RandomOverlayCtmProperties.java index fce778c9..ed2100c2 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/overlay/RepeatOverlayCTMProperties.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/overlay/RandomOverlayCtmProperties.java @@ -2,15 +2,15 @@ import java.util.Properties; -import me.pepperbell.continuity.client.properties.RepeatCTMProperties; +import me.pepperbell.continuity.client.properties.RandomCtmProperties; import net.minecraft.resource.ResourceManager; import net.minecraft.resource.ResourcePack; import net.minecraft.util.Identifier; -public class RepeatOverlayCTMProperties extends RepeatCTMProperties implements OverlayPropertiesSection.Provider { +public class RandomOverlayCtmProperties extends RandomCtmProperties implements OverlayPropertiesSection.Provider { protected OverlayPropertiesSection overlaySection; - public RepeatOverlayCTMProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { + public RandomOverlayCtmProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { super(properties, id, pack, packPriority, resourceManager, method); overlaySection = new OverlayPropertiesSection(properties, id, packName); } diff --git a/src/main/java/me/pepperbell/continuity/client/properties/overlay/RandomOverlayCTMProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/overlay/RepeatOverlayCtmProperties.java similarity index 79% rename from src/main/java/me/pepperbell/continuity/client/properties/overlay/RandomOverlayCTMProperties.java rename to src/main/java/me/pepperbell/continuity/client/properties/overlay/RepeatOverlayCtmProperties.java index 1faaa675..7e7d2292 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/overlay/RandomOverlayCTMProperties.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/overlay/RepeatOverlayCtmProperties.java @@ -2,15 +2,15 @@ import java.util.Properties; -import me.pepperbell.continuity.client.properties.RandomCTMProperties; +import me.pepperbell.continuity.client.properties.RepeatCtmProperties; import net.minecraft.resource.ResourceManager; import net.minecraft.resource.ResourcePack; import net.minecraft.util.Identifier; -public class RandomOverlayCTMProperties extends RandomCTMProperties implements OverlayPropertiesSection.Provider { +public class RepeatOverlayCtmProperties extends RepeatCtmProperties implements OverlayPropertiesSection.Provider { protected OverlayPropertiesSection overlaySection; - public RandomOverlayCTMProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { + public RepeatOverlayCtmProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { super(properties, id, pack, packPriority, resourceManager, method); overlaySection = new OverlayPropertiesSection(properties, id, packName); } diff --git a/src/main/java/me/pepperbell/continuity/client/properties/overlay/StandardConnectingOverlayCTMProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/overlay/StandardConnectingOverlayCTMProperties.java deleted file mode 100644 index 34001415..00000000 --- a/src/main/java/me/pepperbell/continuity/client/properties/overlay/StandardConnectingOverlayCTMProperties.java +++ /dev/null @@ -1,28 +0,0 @@ -package me.pepperbell.continuity.client.properties.overlay; - -import java.util.Properties; - -import me.pepperbell.continuity.client.properties.StandardConnectingCTMProperties; -import net.minecraft.resource.ResourceManager; -import net.minecraft.resource.ResourcePack; -import net.minecraft.util.Identifier; - -public class StandardConnectingOverlayCTMProperties extends StandardConnectingCTMProperties implements OverlayPropertiesSection.Provider { - protected OverlayPropertiesSection overlaySection; - - public StandardConnectingOverlayCTMProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { - super(properties, id, pack, packPriority, resourceManager, method); - overlaySection = new OverlayPropertiesSection(properties, id, packName); - } - - @Override - public void init() { - super.init(); - overlaySection.init(); - } - - @Override - public OverlayPropertiesSection getOverlayPropertiesSection() { - return overlaySection; - } -} diff --git a/src/main/java/me/pepperbell/continuity/client/properties/overlay/StandardOverlayCTMProperties.java b/src/main/java/me/pepperbell/continuity/client/properties/overlay/StandardOverlayCtmProperties.java similarity index 78% rename from src/main/java/me/pepperbell/continuity/client/properties/overlay/StandardOverlayCTMProperties.java rename to src/main/java/me/pepperbell/continuity/client/properties/overlay/StandardOverlayCtmProperties.java index 8b24ac4e..a20fa438 100644 --- a/src/main/java/me/pepperbell/continuity/client/properties/overlay/StandardOverlayCTMProperties.java +++ b/src/main/java/me/pepperbell/continuity/client/properties/overlay/StandardOverlayCtmProperties.java @@ -6,7 +6,7 @@ import org.jetbrains.annotations.Nullable; -import me.pepperbell.continuity.client.properties.ConnectingCTMProperties; +import me.pepperbell.continuity.client.properties.BasicConnectingCtmProperties; import me.pepperbell.continuity.client.properties.PropertiesParsingHelper; import me.pepperbell.continuity.client.resource.ResourceRedirectHandler; import net.minecraft.block.BlockState; @@ -14,14 +14,14 @@ import net.minecraft.resource.ResourcePack; import net.minecraft.util.Identifier; -public class StandardOverlayCTMProperties extends ConnectingCTMProperties implements OverlayPropertiesSection.Provider { +public class StandardOverlayCtmProperties extends BasicConnectingCtmProperties implements OverlayPropertiesSection.Provider { protected OverlayPropertiesSection overlaySection; @Nullable protected Set connectTilesSet; @Nullable protected Predicate connectBlocksPredicate; - public StandardOverlayCTMProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { + public StandardOverlayCtmProperties(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method) { super(properties, id, pack, packPriority, resourceManager, method); overlaySection = new OverlayPropertiesSection(properties, id, packName); } @@ -40,11 +40,11 @@ public OverlayPropertiesSection getOverlayPropertiesSection() { } protected void parseConnectTiles() { - connectTilesSet = PropertiesParsingHelper.parseMatchTiles(properties, "connectTiles", id, packName, ResourceRedirectHandler.get(resourceManager)); + connectTilesSet = PropertiesParsingHelper.parseMatchTiles(properties, "connectTiles", resourceId, packName, ResourceRedirectHandler.get(resourceManager)); } protected void parseConnectBlocks() { - connectBlocksPredicate = PropertiesParsingHelper.parseBlockStates(properties, "connectBlocks", id, packName); + connectBlocksPredicate = PropertiesParsingHelper.parseBlockStates(properties, "connectBlocks", resourceId, packName); } @Nullable diff --git a/src/main/java/me/pepperbell/continuity/client/resource/AtlasLoaderInitContext.java b/src/main/java/me/pepperbell/continuity/client/resource/AtlasLoaderInitContext.java index 6c5e6eea..0553245a 100644 --- a/src/main/java/me/pepperbell/continuity/client/resource/AtlasLoaderInitContext.java +++ b/src/main/java/me/pepperbell/continuity/client/resource/AtlasLoaderInitContext.java @@ -1,7 +1,6 @@ package me.pepperbell.continuity.client.resource; import java.util.Set; -import java.util.concurrent.CompletableFuture; import org.jetbrains.annotations.Nullable; @@ -10,5 +9,6 @@ public interface AtlasLoaderInitContext { ThreadLocal THREAD_LOCAL = new ThreadLocal<>(); - CompletableFuture<@Nullable Set> getExtraIdsFuture(); + @Nullable + Set getExtraIds(); } diff --git a/src/main/java/me/pepperbell/continuity/client/resource/BakedModelManagerReloadExtension.java b/src/main/java/me/pepperbell/continuity/client/resource/BakedModelManagerReloadExtension.java index 257db208..2419ffef 100644 --- a/src/main/java/me/pepperbell/continuity/client/resource/BakedModelManagerReloadExtension.java +++ b/src/main/java/me/pepperbell/continuity/client/resource/BakedModelManagerReloadExtension.java @@ -6,7 +6,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; import org.jetbrains.annotations.Nullable; @@ -21,17 +20,19 @@ import net.minecraft.util.Identifier; public class BakedModelManagerReloadExtension { - private final CompletableFuture ctmLoadingResultFuture; + private final CompletableFuture ctmLoadingResultFuture; private final AtomicBoolean wrapEmissiveModels = new AtomicBoolean(); + private final SpriteLoaderLoadContextImpl spriteLoaderLoadContext; private volatile List processorHolders; public BakedModelManagerReloadExtension(ResourceManager resourceManager, Executor prepareExecutor) { - ctmLoadingResultFuture = CompletableFuture.supplyAsync(() -> CTMPropertiesLoader.loadAllWithState(resourceManager), prepareExecutor); + ctmLoadingResultFuture = CompletableFuture.supplyAsync(() -> CtmPropertiesLoader.loadAllWithState(resourceManager), prepareExecutor); + spriteLoaderLoadContext = new SpriteLoaderLoadContextImpl(ctmLoadingResultFuture.thenApply(CtmPropertiesLoader.LoadingResult::getTextureDependencies), wrapEmissiveModels); EmissiveSuffixLoader.load(resourceManager); } public void setContext() { - SpriteLoaderLoadContext.THREAD_LOCAL.set(new SpriteLoaderInitContextImpl(ctmLoadingResultFuture.thenApply(CTMPropertiesLoader.LoadingResult::getTextureDependencies), wrapEmissiveModels)); + SpriteLoaderLoadContext.THREAD_LOCAL.set(spriteLoaderLoadContext); } public void clearContext() { @@ -39,7 +40,7 @@ public void clearContext() { } public void beforeBaking(Map preparations, ModelLoader modelLoader) { - CTMPropertiesLoader.LoadingResult result = ctmLoadingResultFuture.join(); + CtmPropertiesLoader.LoadingResult result = ctmLoadingResultFuture.join(); List processorHolders = result.createProcessorHolders(spriteId -> { SpriteAtlasManager.AtlasPreparation preparation = preparations.get(spriteId.getAtlasId()); @@ -52,8 +53,8 @@ public void beforeBaking(Map pr this.processorHolders = processorHolders; - ((ModelLoaderExtension) modelLoader).continuity$setWrapCTM(!processorHolders.isEmpty()); - ((ModelLoaderExtension) modelLoader).continuity$setWrapEmissive(wrapEmissiveModels.get()); + ModelWrappingHandler wrappingHandler = ModelWrappingHandler.create(!processorHolders.isEmpty(), wrapEmissiveModels.get()); + ((ModelLoaderExtension) modelLoader).continuity$setModelWrappingHandler(wrappingHandler); } public void apply() { @@ -63,15 +64,14 @@ public void apply() { } } - private static class SpriteLoaderInitContextImpl implements SpriteLoaderLoadContext { + private static class SpriteLoaderLoadContextImpl implements SpriteLoaderLoadContext { private final CompletableFuture>> allExtraIdsFuture; private final Map>> extraIdsFutures = new Object2ObjectOpenHashMap<>(); private final EmissiveControl blockAtlasEmissiveControl; - private final AtomicReference> emissiveIdMapHolder = new AtomicReference<>(); - public SpriteLoaderInitContextImpl(CompletableFuture>> allExtraIdsFuture, AtomicBoolean blockAtlasHasEmissivesHolder) { + public SpriteLoaderLoadContextImpl(CompletableFuture>> allExtraIdsFuture, AtomicBoolean blockAtlasHasEmissivesHolder) { this.allExtraIdsFuture = allExtraIdsFuture; - blockAtlasEmissiveControl = () -> blockAtlasHasEmissivesHolder.set(true); + blockAtlasEmissiveControl = new EmissiveControlImpl(blockAtlasHasEmissivesHolder); } @Override @@ -88,9 +88,30 @@ public EmissiveControl getEmissiveControl(Identifier atlasId) { return null; } - @Override - public AtomicReference<@Nullable Map> getEmissiveIdMapHolder() { - return emissiveIdMapHolder; + private static class EmissiveControlImpl implements EmissiveControl { + @Nullable + private volatile Map emissiveIdMap; + private final AtomicBoolean hasEmissivesHolder; + + public EmissiveControlImpl(AtomicBoolean hasEmissivesHolder) { + this.hasEmissivesHolder = hasEmissivesHolder; + } + + @Override + @Nullable + public Map getEmissiveIdMap() { + return emissiveIdMap; + } + + @Override + public void setEmissiveIdMap(Map emissiveIdMap) { + this.emissiveIdMap = emissiveIdMap; + } + + @Override + public void markHasEmissives() { + hasEmissivesHolder.set(true); + } } } } diff --git a/src/main/java/me/pepperbell/continuity/client/resource/CTMPropertiesLoader.java b/src/main/java/me/pepperbell/continuity/client/resource/CtmPropertiesLoader.java similarity index 69% rename from src/main/java/me/pepperbell/continuity/client/resource/CTMPropertiesLoader.java rename to src/main/java/me/pepperbell/continuity/client/resource/CtmPropertiesLoader.java index 4178c904..6b4173c1 100644 --- a/src/main/java/me/pepperbell/continuity/client/resource/CTMPropertiesLoader.java +++ b/src/main/java/me/pepperbell/continuity/client/resource/CtmPropertiesLoader.java @@ -14,10 +14,10 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -import me.pepperbell.continuity.api.client.CTMLoader; -import me.pepperbell.continuity.api.client.CTMLoaderRegistry; -import me.pepperbell.continuity.api.client.CTMProperties; import me.pepperbell.continuity.api.client.CachingPredicates; +import me.pepperbell.continuity.api.client.CtmLoader; +import me.pepperbell.continuity.api.client.CtmLoaderRegistry; +import me.pepperbell.continuity.api.client.CtmProperties; import me.pepperbell.continuity.api.client.QuadProcessor; import me.pepperbell.continuity.client.ContinuityClient; import me.pepperbell.continuity.client.model.QuadProcessors; @@ -30,7 +30,15 @@ import net.minecraft.resource.ResourceType; import net.minecraft.util.Identifier; -public final class CTMPropertiesLoader { +public class CtmPropertiesLoader { + private final ResourceManager resourceManager; + private final List> containers = new ObjectArrayList<>(); + private final Map> textureDependencies = new Object2ObjectOpenHashMap<>(); + + private CtmPropertiesLoader(ResourceManager resourceManager) { + this.resourceManager = resourceManager; + } + public static LoadingResult loadAllWithState(ResourceManager resourceManager) { // TODO: move these to the very beginning of resource reload BiomeHolderManager.clearCache(); @@ -44,67 +52,65 @@ public static LoadingResult loadAllWithState(ResourceManager resourceManager) { } public static LoadingResult loadAll(ResourceManager resourceManager) { - LoadingData loadingData = new LoadingData(); + return new CtmPropertiesLoader(resourceManager).loadAll(); + } + private LoadingResult loadAll() { int packPriority = 0; Iterator iterator = resourceManager.streamResourcePacks().iterator(); BooleanState invalidIdentifierState = InvalidIdentifierStateHolder.get(); invalidIdentifierState.enable(); while (iterator.hasNext()) { ResourcePack pack = iterator.next(); - loadAll(pack, packPriority, resourceManager, loadingData); + loadAll(pack, packPriority); packPriority++; } invalidIdentifierState.disable(); - loadingData.containers.sort(Comparator.reverseOrder()); - return new LoadingResult(loadingData.containers, loadingData.textureDependencies); + containers.sort(Comparator.reverseOrder()); + + return new LoadingResult(containers, textureDependencies); } - private static void loadAll(ResourcePack pack, int packPriority, ResourceManager resourceManager, LoadingData loadingData) { + private void loadAll(ResourcePack pack, int packPriority) { for (String namespace : pack.getNamespaces(ResourceType.CLIENT_RESOURCES)) { - pack.findResources(ResourceType.CLIENT_RESOURCES, namespace, "optifine/ctm", (id, inputSupplier) -> { - if (id.getPath().endsWith(".properties")) { + pack.findResources(ResourceType.CLIENT_RESOURCES, namespace, "optifine/ctm", (resourceId, inputSupplier) -> { + if (resourceId.getPath().endsWith(".properties")) { try (InputStream stream = inputSupplier.get()) { Properties properties = new Properties(); properties.load(stream); - load(properties, id, pack, packPriority, resourceManager, loadingData); + load(properties, resourceId, pack, packPriority); } catch (Exception e) { - ContinuityClient.LOGGER.error("Failed to load CTM properties from file '" + id + "' in pack '" + pack.getName() + "'", e); + ContinuityClient.LOGGER.error("Failed to load CTM properties from file '" + resourceId + "' in pack '" + pack.getName() + "'", e); } } }); } } - private static void load(Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, LoadingData loadingData) { + private void load(Properties properties, Identifier resourceId, ResourcePack pack, int packPriority) { String method = properties.getProperty("method", "ctm").trim(); - CTMLoader loader = CTMLoaderRegistry.get().getLoader(method); + CtmLoader loader = CtmLoaderRegistry.get().getLoader(method); if (loader != null) { - load(loader, properties, id, pack, packPriority, resourceManager, method, loadingData); + load(loader, properties, resourceId, pack, packPriority, method); } else { - ContinuityClient.LOGGER.error("Unknown 'method' value '" + method + "' in file '" + id + "' in pack '" + pack.getName() + "'"); + ContinuityClient.LOGGER.error("Unknown 'method' value '" + method + "' in file '" + resourceId + "' in pack '" + pack.getName() + "'"); } } - private static void load(CTMLoader loader, Properties properties, Identifier id, ResourcePack pack, int packPriority, ResourceManager resourceManager, String method, LoadingData loadingData) { - T ctmProperties = loader.getPropertiesFactory().createProperties(properties, id, pack, packPriority, resourceManager, method); + private void load(CtmLoader loader, Properties properties, Identifier resourceId, ResourcePack pack, int packPriority, String method) { + T ctmProperties = loader.getPropertiesFactory().createProperties(properties, resourceId, pack, packPriority, resourceManager, method); if (ctmProperties != null) { LoadingContainer container = new LoadingContainer<>(loader, ctmProperties); - loadingData.containers.add(container); + containers.add(container); for (SpriteIdentifier spriteId : ctmProperties.getTextureDependencies()) { - Set atlasTextureDependencies = loadingData.textureDependencies.computeIfAbsent(spriteId.getAtlasId(), id1 -> new ObjectOpenHashSet<>()); + Set atlasTextureDependencies = textureDependencies.computeIfAbsent(spriteId.getAtlasId(), id -> new ObjectOpenHashSet<>()); atlasTextureDependencies.add(spriteId.getTextureId()); } } } - private static class LoadingData { - public final List> containers = new ObjectArrayList<>(); - public final Map> textureDependencies = new Object2ObjectOpenHashMap<>(); - } - - private record LoadingContainer(CTMLoader loader, T properties) implements Comparable> { + private record LoadingContainer(CtmLoader loader, T properties) implements Comparable> { public QuadProcessors.ProcessorHolder toProcessorHolder(Function textureGetter) { QuadProcessor processor = loader.getProcessorFactory().createProcessor(properties, textureGetter); CachingPredicates predicates = loader.getPredicatesFactory().createPredicates(properties, textureGetter); diff --git a/src/main/java/me/pepperbell/continuity/client/resource/ModelWrappingHandler.java b/src/main/java/me/pepperbell/continuity/client/resource/ModelWrappingHandler.java index 95828e98..53cecc03 100644 --- a/src/main/java/me/pepperbell/continuity/client/resource/ModelWrappingHandler.java +++ b/src/main/java/me/pepperbell/continuity/client/resource/ModelWrappingHandler.java @@ -4,7 +4,7 @@ import com.google.common.collect.ImmutableMap; -import me.pepperbell.continuity.client.model.CTMBakedModel; +import me.pepperbell.continuity.client.model.CtmBakedModel; import me.pepperbell.continuity.client.model.EmissiveBakedModel; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -15,8 +15,24 @@ import net.minecraft.registry.Registries; import net.minecraft.util.Identifier; -public final class ModelWrappingHandler { - private static final ImmutableMap BLOCK_STATE_MODEL_IDS = createBlockStateModelIdMap(); +public class ModelWrappingHandler { + private final boolean wrapCtm; + private final boolean wrapEmissive; + private final ImmutableMap blockStateModelIds; + + private ModelWrappingHandler(boolean wrapCtm, boolean wrapEmissive) { + this.wrapCtm = wrapCtm; + this.wrapEmissive = wrapEmissive; + blockStateModelIds = createBlockStateModelIdMap(); + } + + @Nullable + public static ModelWrappingHandler create(boolean wrapCtm, boolean wrapEmissive) { + if (!wrapCtm && !wrapEmissive) { + return null; + } + return new ModelWrappingHandler(wrapCtm, wrapEmissive); + } private static ImmutableMap createBlockStateModelIdMap() { ImmutableMap.Builder builder = ImmutableMap.builder(); @@ -31,13 +47,13 @@ private static ImmutableMap createBlockStateModelId return builder.build(); } - public static BakedModel wrap(@Nullable BakedModel model, Identifier modelId, boolean wrapCTM, boolean wrapEmissive) { + public BakedModel wrap(@Nullable BakedModel model, Identifier modelId) { if (model != null && !model.isBuiltin() && !modelId.equals(ModelLoader.MISSING_ID)) { - if (wrapCTM) { + if (wrapCtm) { if (modelId instanceof ModelIdentifier) { - BlockState state = BLOCK_STATE_MODEL_IDS.get(modelId); + BlockState state = blockStateModelIds.get(modelId); if (state != null) { - model = new CTMBakedModel(model, state); + model = new CtmBakedModel(model, state); } } } diff --git a/src/main/java/me/pepperbell/continuity/client/resource/SpriteLoaderLoadContext.java b/src/main/java/me/pepperbell/continuity/client/resource/SpriteLoaderLoadContext.java index f97b305e..619e2d25 100644 --- a/src/main/java/me/pepperbell/continuity/client/resource/SpriteLoaderLoadContext.java +++ b/src/main/java/me/pepperbell/continuity/client/resource/SpriteLoaderLoadContext.java @@ -3,7 +3,6 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.atomic.AtomicReference; import org.jetbrains.annotations.Nullable; @@ -17,9 +16,12 @@ public interface SpriteLoaderLoadContext { @Nullable EmissiveControl getEmissiveControl(Identifier atlasId); - AtomicReference<@Nullable Map> getEmissiveIdMapHolder(); - interface EmissiveControl { + @Nullable + Map getEmissiveIdMap(); + + void setEmissiveIdMap(Map emissiveIdMap); + void markHasEmissives(); } } diff --git a/src/main/java/me/pepperbell/continuity/client/util/SpriteCalculator.java b/src/main/java/me/pepperbell/continuity/client/util/SpriteCalculator.java index 697be1a0..7d55dc8b 100644 --- a/src/main/java/me/pepperbell/continuity/client/util/SpriteCalculator.java +++ b/src/main/java/me/pepperbell/continuity/client/util/SpriteCalculator.java @@ -2,7 +2,6 @@ import java.util.EnumMap; import java.util.List; -import java.util.Map; import java.util.concurrent.locks.StampedLock; import java.util.function.Supplier; @@ -61,7 +60,7 @@ public static void clearCache() { private static class SpriteCache { private final Direction face; - private final Map sprites = new Reference2ReferenceOpenHashMap<>(); + private final Reference2ReferenceOpenHashMap sprites = new Reference2ReferenceOpenHashMap<>(); private final Supplier randomSupplier = new Supplier<>() { private final Random random = Random.create(); @@ -80,21 +79,42 @@ public SpriteCache(Direction face) { public Sprite getSprite(BlockState state) { Sprite sprite; + + long optimisticReadStamp = lock.tryOptimisticRead(); + if (optimisticReadStamp != 0L) { + try { + // This map read could happen at the same time as a map write, so catch any exceptions. + // This is safe due to the map implementation used, which is guaranteed to not mutate the map during + // a read. + sprite = sprites.get(state); + if (sprite != null && lock.validate(optimisticReadStamp)) { + return sprite; + } + } catch (Exception e) { + // + } + } + long readStamp = lock.readLock(); try { sprite = sprites.get(state); } finally { lock.unlockRead(readStamp); } + if (sprite == null) { long writeStamp = lock.writeLock(); try { - sprite = calculateSprite(state, face, randomSupplier); - sprites.put(state, sprite); + sprite = sprites.get(state); + if (sprite == null) { + sprite = calculateSprite(state, face, randomSupplier); + sprites.put(state, sprite); + } } finally { lock.unlockWrite(writeStamp); } } + return sprite; } diff --git a/src/main/java/me/pepperbell/continuity/impl/client/CTMLoaderRegistryImpl.java b/src/main/java/me/pepperbell/continuity/impl/client/CTMLoaderRegistryImpl.java deleted file mode 100644 index 21316d4b..00000000 --- a/src/main/java/me/pepperbell/continuity/impl/client/CTMLoaderRegistryImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package me.pepperbell.continuity.impl.client; - -import java.util.Map; - -import org.jetbrains.annotations.Nullable; - -import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import me.pepperbell.continuity.api.client.CTMLoader; -import me.pepperbell.continuity.api.client.CTMLoaderRegistry; - -public final class CTMLoaderRegistryImpl implements CTMLoaderRegistry { - public static final CTMLoaderRegistryImpl INSTANCE = new CTMLoaderRegistryImpl(); - - private final Map> loaderMap = new Object2ObjectOpenHashMap<>(); - - @Override - public void registerLoader(String method, CTMLoader loader) { - loaderMap.put(method, loader); - } - - @Override - @Nullable - public CTMLoader getLoader(String method) { - return loaderMap.get(method); - } -} diff --git a/src/main/java/me/pepperbell/continuity/impl/client/CtmLoaderRegistryImpl.java b/src/main/java/me/pepperbell/continuity/impl/client/CtmLoaderRegistryImpl.java new file mode 100644 index 00000000..c6504f80 --- /dev/null +++ b/src/main/java/me/pepperbell/continuity/impl/client/CtmLoaderRegistryImpl.java @@ -0,0 +1,26 @@ +package me.pepperbell.continuity.impl.client; + +import java.util.Map; + +import org.jetbrains.annotations.Nullable; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import me.pepperbell.continuity.api.client.CtmLoader; +import me.pepperbell.continuity.api.client.CtmLoaderRegistry; + +public final class CtmLoaderRegistryImpl implements CtmLoaderRegistry { + public static final CtmLoaderRegistryImpl INSTANCE = new CtmLoaderRegistryImpl(); + + private final Map> loaderMap = new Object2ObjectOpenHashMap<>(); + + @Override + public void registerLoader(String method, CtmLoader loader) { + loaderMap.put(method, loader); + } + + @Override + @Nullable + public CtmLoader getLoader(String method) { + return loaderMap.get(method); + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index f304287d..a693dd61 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -32,7 +32,8 @@ "depends": { "minecraft": "1.19.3", - "fabric": ">=0.76.1" + "fabricloader": ">=0.15.0", + "fabric-api": ">=0.76.1" }, "custom": {