Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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 {
Expand Down
10 changes: 5 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ 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
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
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -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
Expand Down
9 changes: 4 additions & 5 deletions gradlew

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions gradlew.bat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Comment on lines +5 to 9
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file now uses ReadView/WriteView for custom data, but some imports are no longer referenced (org.spongepowered.asm.mixin.Shadow and net.minecraft.nbt.NbtCompound). Please remove unused imports to keep the mixin clean and avoid stricter compiler/lint failures.

Copilot uses AI. Check for mistakes.
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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) {
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scripts_chunk_loaders$stopChunkLoader(Boolean keepName) takes a boxed Boolean. Since callers pass primitives and null isn’t meaningful here, this should be a primitive boolean to avoid accidental NullPointerException and unnecessary boxing.

Suggested change
public void scripts_chunk_loaders$stopChunkLoader(Boolean keepName) {
public void scripts_chunk_loaders$stopChunkLoader(boolean keepName) {

Copilot uses AI. Check for mistakes.
this.isChunkLoader = false;

Expand All @@ -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"))
Expand Down Expand Up @@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -23,53 +26,107 @@

@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",
cancellable = true
)

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<AbstractMinecartEntity> 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();
}
}
4 changes: 2 additions & 2 deletions src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": "*"
}
Expand Down