diff --git a/build.gradle b/build.gradle index 1722e02..3a2b194 100644 --- a/build.gradle +++ b/build.gradle @@ -3,13 +3,13 @@ plugins { id "com.modrinth.minotaur" version "2.+" } -sourceCompatibility = JavaVersion.VERSION_21 -targetCompatibility = JavaVersion.VERSION_21 - -archivesBaseName = project.archives_base_name version = "mc${project.minecraft_version}-${project.mod_version}" group = project.maven_group +base { + archivesName = project.archives_base_name +} + repositories { // Add repositories to retrieve artifacts from in here. // You should only use this when depending on other mods because @@ -60,7 +60,7 @@ dependencies { modImplementation "net.fabricmc:fabric-loader:${project.loader_version}" // Fabric API. This is technically optional, but you probably want it anyway. - modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}" // Uncomment the following line to enable the deprecated Fabric API modules. // These are included in the Fabric API production distribution and allow you to update your mod to the latest modules at a later more convenient time. @@ -85,6 +85,9 @@ java { // if it is present. // If you remove this line, sources will not be generated. withSourcesJar() + + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 } jar { diff --git a/gradle.properties b/gradle.properties index 14c31c5..b3639f3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,10 +4,10 @@ org.gradle.parallel=true # Fabric Properties # check these on https://fabricmc.net/develop -minecraft_version=1.21.5 -yarn_mappings=1.21.5+build.1 -loader_version=0.16.14 -loom_version=1.11-SNAPSHOT +minecraft_version=1.21.11 +yarn_mappings=1.21.11+build.4 +loader_version=0.18.4 +loom_version=1.15-SNAPSHOT # Mod Properties mod_version=0.0.0 @@ -15,4 +15,4 @@ maven_group=io.nihlen.scriptschunkloaders archives_base_name=scripts-chunk-loaders # Dependencies -fabric_version=0.128.1+1.21.5 +fabric_api_version=0.141.3+1.21.11 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b9..1b33c55 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 ca025c8..dbc3ce4 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.14-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f5feea6..23d15a9 100755 --- a/gradlew +++ b/gradlew @@ -86,8 +86,7 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s -' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -115,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -206,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_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. @@ -214,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9b42019..5eed7ee 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell diff --git a/src/main/java/io/nihlen/scriptschunkloaders/ChunkLoaderManager.java b/src/main/java/io/nihlen/scriptschunkloaders/ChunkLoaderManager.java index fa2f7c2..229f5c6 100644 --- a/src/main/java/io/nihlen/scriptschunkloaders/ChunkLoaderManager.java +++ b/src/main/java/io/nihlen/scriptschunkloaders/ChunkLoaderManager.java @@ -44,19 +44,19 @@ public void registerChunkLoader(Entity entity) { var chunkPos = entity.getChunkPos(); removeChunkLoader(entity); - ScriptsChunkLoadersMod.LOGGER.info("Adding {} to {}", entity, entity.getWorld().getRegistryKey().getValue()); + ScriptsChunkLoadersMod.LOGGER.info("Adding {} to {}", entity, entity.getEntityWorld().getRegistryKey().getValue()); - var worldRegistryKey = entity.getWorld().getRegistryKey(); + var worldRegistryKey = entity.getEntityWorld().getRegistryKey(); var worldChunks = forceLoadedChunks.computeIfAbsent(worldRegistryKey, s -> new HashMap<>()); var list = worldChunks.computeIfAbsent(chunkPos.toLong(), s -> new ArrayList<>()); list.add(entity.getUuid()); } public void removeChunkLoader(Entity entity) { - ScriptsChunkLoadersMod.LOGGER.info("Removing {} from {}", entity, entity.getWorld().getRegistryKey().getValue()); + ScriptsChunkLoadersMod.LOGGER.info("Removing {} from {}", entity, entity.getEntityWorld().getRegistryKey().getValue()); var uuid = entity.getUuid(); - var worldRegistryKey = entity.getWorld().getRegistryKey(); + var worldRegistryKey = entity.getEntityWorld().getRegistryKey(); var worldChunks = forceLoadedChunks.get(worldRegistryKey); ScriptsChunkLoadersMod.LOGGER.info("worldChunks {}", worldChunks); diff --git a/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java b/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java index 9351e5c..f45110a 100644 --- a/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java +++ b/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java @@ -2,6 +2,8 @@ import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.vehicle.*; +import net.minecraft.storage.ReadView; +import net.minecraft.storage.WriteView; import net.minecraft.world.TeleportTarget; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -49,11 +51,11 @@ private void injectConstructor(CallbackInfo callbackInfo) { } public void scripts_chunk_loaders$startChunkLoader() { - if (this.getWorld().isClient) return; + if (this.getEntityWorld().isClient()) return; this.isChunkLoader = true; - ScriptsChunkLoadersMod.LOGGER.info("Starting chunk loader in {}", this.getWorld().getRegistryKey().getValue()); + ScriptsChunkLoadersMod.LOGGER.info("Starting chunk loader in {}", this.getEntityWorld().getRegistryKey().getValue()); } public void scripts_chunk_loaders$setChunkLoaderNameFromInventory() { @@ -86,6 +88,7 @@ private void injectConstructor(CallbackInfo callbackInfo) { scripts_chunk_loaders$stopChunkLoader(false); this.lastChunkPos = null; } + @Unique public void scripts_chunk_loaders$stopChunkLoader(Boolean keepName) { this.isChunkLoader = false; @@ -97,14 +100,14 @@ private void injectConstructor(CallbackInfo callbackInfo) { } } - @Inject(method = "writeCustomDataToNbt", at = @At("RETURN")) - public void writeCustomDataToNbt(NbtCompound nbt, CallbackInfo ci) { - nbt.putBoolean("chunkLoader", this.isChunkLoader); + @Inject(method = "writeCustomData", at = @At("RETURN")) + public void writeCustomData(WriteView view, CallbackInfo ci) { + view.putBoolean("chunkLoader", this.isChunkLoader); } - @Inject(method = "readCustomDataFromNbt", at = @At("RETURN")) - public void readCustomDataFromNbt(NbtCompound nbt, CallbackInfo ci) { - this.isChunkLoader = nbt.getBoolean("chunkLoader").orElse(false); + @Inject(method = "readCustomData", at = @At("RETURN")) + public void readCustomData(ReadView view, CallbackInfo ci) { + this.isChunkLoader = view.getBoolean("chunkLoader", false); } @Inject(method = "tick", at = @At("TAIL")) @@ -156,7 +159,7 @@ private void tickParticles() { @Unique private void spawnParticles() { AbstractMinecartEntity entity = (AbstractMinecartEntity)(Object)this; - ServerWorld world = (ServerWorld)entity.getWorld(); + ServerWorld world = (ServerWorld)entity.getEntityWorld(); world.spawnParticles(ParticleTypes.HAPPY_VILLAGER, entity.getX(), entity.getY(), entity.getZ(), 1, 0.25, 0.25, 0.25, 0.15f); } } diff --git a/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java b/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java index 99df91c..c3169c4 100644 --- a/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java +++ b/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java @@ -13,7 +13,10 @@ import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; +import org.slf4j.Logger; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -23,6 +26,8 @@ @Mixin(DispenserBlock.class) public class DispenserBlockMixin { + @Shadow @Final private static Logger LOGGER; + @Inject( at = @At("HEAD"), method = "dispense(Lnet/minecraft/server/world/ServerWorld;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;)V", @@ -30,46 +35,98 @@ public class DispenserBlockMixin { ) private void dispense(ServerWorld world, BlockState state, BlockPos pos, CallbackInfo info) { - if (world.isClient) return; + if (world.isClient()) return; DispenserBlockEntity dispenserBlockEntity = world.getBlockEntity(pos, BlockEntityType.DISPENSER).orElse(null); if (dispenserBlockEntity == null) return; + String action = this.getAction(dispenserBlockEntity); + if (action == null) return; + + this.applyChunkLoaderAction(world, state, pos, action); + + info.cancel(); + } + + @Unique + private String getAction(DispenserBlockEntity dispenserBlockEntity) { // This can't be a property because the items aren't registered when we try to access them. The constructor is // also too early because it's called before Minecraft is even fully loaded. I don't know if there is a good // "on block created in world" or "after item registrations" event or similar that we can hook into. So for now // it will have to be defined here. - Item[] pattern = { + Item toggleItem = Items.GLOWSTONE; + Item startItem = Items.SHROOMLIGHT; + Item stopItem = Items.MAGMA_BLOCK; + + if (this.patternMatches(dispenserBlockEntity, this.getPattern(toggleItem))) { + return "toggle"; + } + + if (this.patternMatches(dispenserBlockEntity, this.getPattern(startItem))) { + return "start"; + } + + if (this.patternMatches(dispenserBlockEntity, this.getPattern(stopItem))) { + return "stop"; + } + + return null; + } + + @Unique + private Item[] getPattern(Item centerItem) { + return new Item[]{ Items.AIR, Items.AMETHYST_SHARD, Items.AIR, - Items.AMETHYST_SHARD, Items.GLOWSTONE, Items.AMETHYST_SHARD, + Items.AMETHYST_SHARD, centerItem, Items.AMETHYST_SHARD, Items.AIR, Items.AMETHYST_SHARD, Items.AIR }; + } + @Unique + private boolean patternMatches(DispenserBlockEntity dispenserBlockEntity, Item[] pattern) { for (int i = 0; i < 9; i++) { ItemStack itemStack = dispenserBlockEntity.getStack(i); if (!itemStack.isOf(pattern[i])) { - return ; + return false; } } - this.toggleMinecraftChunkLoader(world, state, pos); - info.cancel(); + return true; } @Unique - private void toggleMinecraftChunkLoader(ServerWorld world, BlockState state, BlockPos pos) { + private void applyChunkLoaderAction(ServerWorld world, BlockState state, BlockPos pos, String action) { BlockPos blockPos = pos.offset(state.get(DispenserBlock.FACING)); List list = world.getEntitiesByClass(AbstractMinecartEntity.class, new Box(blockPos), EntityPredicates.VALID_ENTITY); for (AbstractMinecartEntity entity : list) { MinecartEntityExt cart = (MinecartEntityExt)entity; - if (cart.scripts_chunk_loaders$isChunkLoader()) { - cart.scripts_chunk_loaders$stopChunkLoader(); - } else { - cart.scripts_chunk_loaders$startChunkLoader(); - cart.scripts_chunk_loaders$setChunkLoaderNameFromInventory(); + switch (action) { + case "toggle" -> this.toggleCart(cart); + case "start" -> this.startCart(cart); + case "stop" -> this.stopCart(cart); } } } + + @Unique + private void toggleCart(MinecartEntityExt cart) { + if (cart.scripts_chunk_loaders$isChunkLoader()) { + this.stopCart(cart); + } else { + this.startCart(cart); + } + } + + @Unique + private void startCart(MinecartEntityExt cart) { + cart.scripts_chunk_loaders$startChunkLoader(); + cart.scripts_chunk_loaders$setChunkLoaderNameFromInventory(); + } + + @Unique + private void stopCart(MinecartEntityExt cart) { + cart.scripts_chunk_loaders$stopChunkLoader(); + } } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 314a555..317d277 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -23,8 +23,8 @@ "scripts-chunk-loaders.mixins.json" ], "depends": { - "fabricloader": ">=0.16.14", - "minecraft": "1.21.5", + "fabricloader": ">=0.18.4", + "minecraft": "1.21.11", "java": ">=21", "fabric-api": "*" }