From 664c27da2b2ba6adbe3f282a486a1f472d4cb04b Mon Sep 17 00:00:00 2001 From: WarperSan Date: Fri, 5 Sep 2025 18:36:35 -0400 Subject: [PATCH 1/7] Added gamerule for default rename --- .../ScriptsChunkLoadersMod.java | 21 +++++++++++++++++++ .../mixin/AbstractMinecartEntityMixin.java | 5 +++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersMod.java b/src/main/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersMod.java index 84810be..55fa3a6 100644 --- a/src/main/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersMod.java +++ b/src/main/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersMod.java @@ -2,6 +2,13 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.fabricmc.fabric.api.gamerule.v1.GameRuleFactory; +import net.fabricmc.fabric.api.gamerule.v1.GameRuleRegistry; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.world.BlockView; +import net.minecraft.world.ChunkRegion; +import net.minecraft.world.GameRules; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,6 +21,8 @@ public class ScriptsChunkLoadersMod implements ModInitializer { public static final Logger LOGGER = LoggerFactory.getLogger(MODID); public static final ChunkLoaderManager CHUNK_LOADER_MANAGER = new ChunkLoaderManager(); + public static final GameRules.Key SHOULD_DEFAULT_RENAME_LOADERS = GameRuleRegistry.register("shouldDefaultRenameLoaders", GameRules.Category.MISC, GameRuleFactory.createBooleanRule(true)); + @Override public void onInitialize() { // This code runs as soon as Minecraft is in a mod-load-ready state. @@ -22,4 +31,16 @@ public void onInitialize() { ServerLifecycleEvents.SERVER_STARTED.register(CHUNK_LOADER_MANAGER::initialize); } + + public static boolean shouldDefaultRenameLoaders(BlockView world) { + if (world instanceof ServerWorld serverWorld) { + return serverWorld.getGameRules().getBoolean(SHOULD_DEFAULT_RENAME_LOADERS); + } + else if (world instanceof ChunkRegion chunkRegion) { + MinecraftServer server = chunkRegion.getServer(); + return server != null && server.getGameRules().getBoolean(SHOULD_DEFAULT_RENAME_LOADERS); + } + + return true; + } } diff --git a/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java b/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java index 9351e5c..23a5823 100644 --- a/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java +++ b/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java @@ -4,7 +4,6 @@ import net.minecraft.entity.vehicle.*; import net.minecraft.world.TeleportTarget; 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; @@ -73,7 +72,9 @@ private void injectConstructor(CallbackInfo callbackInfo) { } }; - scripts_chunk_loaders$setChunkLoaderName("Chunk Loader"); + if (ScriptsChunkLoadersMod.shouldDefaultRenameLoaders(getWorld())) { + scripts_chunk_loaders$setChunkLoaderName("Chunk Loader"); + } } public void scripts_chunk_loaders$setChunkLoaderName(String name) { From 4ec26487174592366fc91b966eedbe18fbd7225e Mon Sep 17 00:00:00 2001 From: WarperSan Date: Fri, 5 Sep 2025 19:34:50 -0400 Subject: [PATCH 2/7] Added sculk sensor resonance --- .../mixin/DispenserBlockMixin.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java b/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java index 99df91c..8c3d5b4 100644 --- a/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java +++ b/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java @@ -13,6 +13,7 @@ import net.minecraft.server.world.ServerWorld; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Box; +import net.minecraft.world.event.GameEvent; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; @@ -61,15 +62,31 @@ private void toggleMinecraftChunkLoader(ServerWorld world, BlockState state, Blo BlockPos blockPos = pos.offset(state.get(DispenserBlock.FACING)); List list = world.getEntitiesByClass(AbstractMinecartEntity.class, new Box(blockPos), EntityPredicates.VALID_ENTITY); + boolean stoppedLoader = false; + boolean startedLoader = false; + for (AbstractMinecartEntity entity : list) { MinecartEntityExt cart = (MinecartEntityExt)entity; if (cart.scripts_chunk_loaders$isChunkLoader()) { cart.scripts_chunk_loaders$stopChunkLoader(); + world.emitGameEvent(GameEvent.RESONATE_1, entity.getPos(), GameEvent.Emitter.of(entity)); + + stoppedLoader = true; } else { cart.scripts_chunk_loaders$startChunkLoader(); cart.scripts_chunk_loaders$setChunkLoaderNameFromInventory(); + + startedLoader = true; } } + + if (startedLoader) { + world.emitGameEvent(GameEvent.RESONATE_6, pos, GameEvent.Emitter.of(state)); + } + + if (stoppedLoader) { + world.emitGameEvent(GameEvent.RESONATE_5, pos, GameEvent.Emitter.of(state)); + } } } From 1cc2e3374a60b57c5f4a5cfc6b970cb12377c058 Mon Sep 17 00:00:00 2001 From: WarperSan Date: Fri, 5 Sep 2025 19:36:31 -0400 Subject: [PATCH 3/7] Fixed warnings (based of the IDE suggestions) --- .../mixin/AbstractMinecartEntityMixin.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java b/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java index 23a5823..3b9bd05 100644 --- a/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java +++ b/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java @@ -27,9 +27,7 @@ public abstract class AbstractMinecartEntityMixin extends Entity implements Mine private boolean isChunkLoader = false; @Unique private int particleTicker = 0; - @Unique - private final int particleInterval = 3; - @Unique + @Unique private ChunkPos lastChunkPos = null; public AbstractMinecartEntityMixin(EntityType type, World world) { @@ -61,7 +59,7 @@ private void injectConstructor(CallbackInfo callbackInfo) { if (minecartType == EntityType.CHEST_MINECART) { //noinspection DataFlowIssue - We're sure this is a chest because of the if statement. var entity = (ChestMinecartEntity)(Object)this; - var firstSlot = entity.getInventory().get(0); + var firstSlot = entity.getInventory().getFirst(); var hasCustomName = firstSlot.get(DataComponentTypes.CUSTOM_NAME) != null; @@ -70,7 +68,7 @@ private void injectConstructor(CallbackInfo callbackInfo) { scripts_chunk_loaders$setChunkLoaderName(name); return; } - }; + } if (ScriptsChunkLoadersMod.shouldDefaultRenameLoaders(getWorld())) { scripts_chunk_loaders$setChunkLoaderName("Chunk Loader"); @@ -87,6 +85,8 @@ 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; @@ -148,7 +148,7 @@ public Entity teleportTo(TeleportTarget teleportTarget) { @Unique private void tickParticles() { this.particleTicker += 1; - if (this.particleTicker >= particleInterval) { + if (this.particleTicker >= 3) { this.particleTicker = 0; this.spawnParticles(); } From 25392807c7785dba525970fa8fe7b4eacabb4a45 Mon Sep 17 00:00:00 2001 From: WarperSan Date: Fri, 5 Sep 2025 20:40:10 -0400 Subject: [PATCH 4/7] Removed undesired game event --- .../io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java b/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java index 8c3d5b4..c41573a 100644 --- a/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java +++ b/src/main/java/io/nihlen/scriptschunkloaders/mixin/DispenserBlockMixin.java @@ -70,7 +70,6 @@ private void toggleMinecraftChunkLoader(ServerWorld world, BlockState state, Blo if (cart.scripts_chunk_loaders$isChunkLoader()) { cart.scripts_chunk_loaders$stopChunkLoader(); - world.emitGameEvent(GameEvent.RESONATE_1, entity.getPos(), GameEvent.Emitter.of(entity)); stoppedLoader = true; } else { From a85ba5973f2ec3e4a1db9ea310697fdc5c870805 Mon Sep 17 00:00:00 2001 From: WarperSan Date: Fri, 5 Sep 2025 20:43:26 -0400 Subject: [PATCH 5/7] Added sculk tests --- .../ScriptsChunkLoadersGameTest.java | 77 ++++++++++++++++++ .../scl_tests/structure/sculk_activate.nbt | Bin 0 -> 647 bytes 2 files changed, 77 insertions(+) create mode 100644 src/gametest/resources/data/scl_tests/structure/sculk_activate.nbt diff --git a/src/gametest/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersGameTest.java b/src/gametest/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersGameTest.java index 819b992..1d7d433 100644 --- a/src/gametest/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersGameTest.java +++ b/src/gametest/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersGameTest.java @@ -2,11 +2,14 @@ import net.fabricmc.fabric.api.gametest.v1.GameTest; +import net.minecraft.block.entity.SculkSensorBlockEntity; import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; +import net.minecraft.state.property.IntProperty; +import net.minecraft.state.property.Properties; import net.minecraft.test.TestContext; import net.minecraft.text.Text; import net.minecraft.util.math.BlockPos; @@ -40,11 +43,17 @@ * - Minecart registers, unregisters and registers again * * - Minecart does not register with empty dispenser +* +* - Minecart registers with sculk sensor +* +* - Minecart unregisters with sculk sensor * */ public class ScriptsChunkLoadersGameTest { String defaultName = "Chunk Loader"; String customItemName = "My Custom Item"; + Integer startLoaderFrequency = 6; + Integer stopLoaderFrequency = 5; Function getCustomName = entity -> { var customName = entity.getCustomName(); @@ -351,4 +360,72 @@ public void doesNotRegisterWithEmptyDispenser(TestContext context) { context.complete(); }); } + + @GameTest(structure = "scl_tests:sculk_activate") + public void registerWithResonance(TestContext context) { + clearTest(context); + + context.spawnEntity(EntityType.MINECART, 2, 1, 2); + context.removeBlock(new BlockPos(3, 1, 2)); + context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); + + context.waitAndRun(15, () -> { + BlockPos pos = new BlockPos( 4, 1, 2); + SculkSensorBlockEntity sensor = context.getBlockEntity(pos, SculkSensorBlockEntity.class); + + if (sensor.getLastVibrationFrequency() != startLoaderFrequency) { + throw context.createError(pos, String.format( + "Expected a vibration frequency of %s, instead got %s", + startLoaderFrequency, + sensor.getLastVibrationFrequency() + )); + } + + context.expectEntityWithData( + new BlockPos(2, 1, 2), + EntityType.MINECART, + getCustomName, + defaultName + ); + context.complete(); + }); + } + + @GameTest(structure = "scl_tests:sculk_activate") + public void unregisterWithResonance(TestContext context) { + clearTest(context); + + context.spawnEntity(EntityType.MINECART, 2, 1, 2); + context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); + + context.waitAndRun(4, () -> { + context.expectEntityWithData(new BlockPos(2, 1, 2), EntityType.MINECART, getCustomName, defaultName); + context.removeBlock(new BlockPos(3, 1, 2)); + + context.waitAndRun(4, () -> { + context.putAndRemoveRedstoneBlock(new BlockPos(1, 1, 1), 1); + + context.waitAndRun(8, () -> { + BlockPos pos = new BlockPos( 4, 1, 2); + SculkSensorBlockEntity sensor = context.getBlockEntity(pos, SculkSensorBlockEntity.class); + + if (sensor.getLastVibrationFrequency() != stopLoaderFrequency) { + throw context.createError(pos, String.format( + "Expected a vibration frequency of %s, instead got %s", + stopLoaderFrequency, + sensor.getLastVibrationFrequency() + )); + } + + context.expectEntityWithData( + new BlockPos(2, 1, 2), + EntityType.MINECART, + getCustomName, + null + ); + context.complete(); + }); + }); + }); + } } \ No newline at end of file diff --git a/src/gametest/resources/data/scl_tests/structure/sculk_activate.nbt b/src/gametest/resources/data/scl_tests/structure/sculk_activate.nbt new file mode 100644 index 0000000000000000000000000000000000000000..75aba9493aaa83fd05f2b1b47b96f011f1e9c5ae GIT binary patch literal 647 zcmb2|=3oGW|8uY3?z?3m!1myy;%>$(tJFh(OYD7Dn!m~`bg9?gULT2$*3RJD4cp$| zex5N`m#>2@eal3F1%HhHB_&Th!{m(_tFEBq)RTmSZJSCu-#`)&3`kL}a$jg3SK@8 z&-KsV?o3O5bCLb_qli5f#{|9yoBkIJyH$Rps>J-?3O#YRd1@gCngcgJb=05Bb!*$z zTMy6MZu^@2fAS3H%q{#k7In+pO08)w6-v4A_1pQE9nCr)1m6E&Eh_ajr2Noc`^PnV z&2OJ_pTGCpNx^tQL!ky2-fn;)%L`1Fx6+mhh-=a%>N@nBe~NnGDF%oWUS@(efrkU#CiAh=VgAG z#dq_?=Jf5oWmu89NIPwc9Oz?S63Y&N&xXWlwR}C|&((0sr2;n~&e@%3 literal 0 HcmV?d00001 From cf3eba9679b3df3225baf6a11df267e51e4c2c7c Mon Sep 17 00:00:00 2001 From: WarperSan Date: Fri, 5 Sep 2025 20:45:15 -0400 Subject: [PATCH 6/7] Cleaned up file (a little) --- .../scriptschunkloaders/ScriptsChunkLoadersGameTest.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/gametest/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersGameTest.java b/src/gametest/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersGameTest.java index 1d7d433..4577a69 100644 --- a/src/gametest/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersGameTest.java +++ b/src/gametest/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersGameTest.java @@ -1,19 +1,15 @@ package io.nihlen.scriptschunkloaders; import net.fabricmc.fabric.api.gametest.v1.GameTest; - import net.minecraft.block.entity.SculkSensorBlockEntity; import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; -import net.minecraft.state.property.IntProperty; -import net.minecraft.state.property.Properties; import net.minecraft.test.TestContext; import net.minecraft.text.Text; import net.minecraft.util.math.BlockPos; - import java.util.Objects; import java.util.function.Function; @@ -49,6 +45,7 @@ * - Minecart unregisters with sculk sensor * */ +@SuppressWarnings("unused") public class ScriptsChunkLoadersGameTest { String defaultName = "Chunk Loader"; String customItemName = "My Custom Item"; From 3896bd1a9f0b0bfb7303cc94f9879484b6fed532 Mon Sep 17 00:00:00 2001 From: WarperSan Date: Fri, 5 Sep 2025 20:58:47 -0400 Subject: [PATCH 7/7] Revamped the gamerule 'shouldDefaultRenameLoaders' to only affect the visibility of the name --- .../ScriptsChunkLoadersMod.java | 23 +++++++++++++------ .../mixin/AbstractMinecartEntityMixin.java | 6 ++--- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/main/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersMod.java b/src/main/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersMod.java index 55fa3a6..70b4018 100644 --- a/src/main/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersMod.java +++ b/src/main/java/io/nihlen/scriptschunkloaders/ScriptsChunkLoadersMod.java @@ -21,7 +21,7 @@ public class ScriptsChunkLoadersMod implements ModInitializer { public static final Logger LOGGER = LoggerFactory.getLogger(MODID); public static final ChunkLoaderManager CHUNK_LOADER_MANAGER = new ChunkLoaderManager(); - public static final GameRules.Key SHOULD_DEFAULT_RENAME_LOADERS = GameRuleRegistry.register("shouldDefaultRenameLoaders", GameRules.Category.MISC, GameRuleFactory.createBooleanRule(true)); + public static final GameRules.Key ALWAYS_SHOW_LOADER_NAME = GameRuleRegistry.register("alwaysShowLoaderName", GameRules.Category.MISC, GameRuleFactory.createBooleanRule(true)); @Override public void onInitialize() { @@ -32,13 +32,22 @@ public void onInitialize() { ServerLifecycleEvents.SERVER_STARTED.register(CHUNK_LOADER_MANAGER::initialize); } - public static boolean shouldDefaultRenameLoaders(BlockView world) { - if (world instanceof ServerWorld serverWorld) { - return serverWorld.getGameRules().getBoolean(SHOULD_DEFAULT_RENAME_LOADERS); - } - else if (world instanceof ChunkRegion chunkRegion) { + public static boolean isCustomNameVisible(BlockView world) { + GameRules rules = null; + + if (world instanceof ServerWorld serverWorld) + rules = serverWorld.getGameRules(); + else if (world instanceof ChunkRegion chunkRegion) + { MinecraftServer server = chunkRegion.getServer(); - return server != null && server.getGameRules().getBoolean(SHOULD_DEFAULT_RENAME_LOADERS); + + if (server != null) { + rules = server.getGameRules(); + } + } + + if (rules != null) { + return rules.getBoolean(ALWAYS_SHOW_LOADER_NAME); } return true; diff --git a/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java b/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java index 3b9bd05..c979a5c 100644 --- a/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java +++ b/src/main/java/io/nihlen/scriptschunkloaders/mixin/AbstractMinecartEntityMixin.java @@ -70,15 +70,13 @@ private void injectConstructor(CallbackInfo callbackInfo) { } } - if (ScriptsChunkLoadersMod.shouldDefaultRenameLoaders(getWorld())) { - scripts_chunk_loaders$setChunkLoaderName("Chunk Loader"); - } + scripts_chunk_loaders$setChunkLoaderName("Chunk Loader"); } public void scripts_chunk_loaders$setChunkLoaderName(String name) { var nameText = Text.literal(name); this.setCustomName(nameText); - this.setCustomNameVisible(true); + this.setCustomNameVisible(ScriptsChunkLoadersMod.isCustomNameVisible(getWorld())); } public void scripts_chunk_loaders$stopChunkLoader() {