XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

MyDimension-Lord

【我的世界】我的维度附属模组:维度之主

公开
关注 0 Fork 0 Star 0
UTF-8
package com.xfestudio.mydimensionlord.builder.anchor;

import com.xfestudio.mydimensionlord.MyDimension;
import com.xfestudio.mydimensionlord.config.BuilderConfig;
import com.xfestudio.mydimensionlord.registry.ModBlocks;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.event.level.ChunkEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

/** Precise, non-scanning wake-up for anchors whose target container chunk loads later. */
@Mod.EventBusSubscriber(modid = MyDimension.MOD_ID, bus = Mod.EventBusSubscriber.Bus.FORGE)
public final class ResonantSupplyAnchorLifecycle {
    private ResonantSupplyAnchorLifecycle() {
    }

    @SubscribeEvent
    public static void chunkLoaded(ChunkEvent.Load event) {
        if (!(event.getLevel() instanceof ServerLevel level) || !BuilderConfig.isEnabled()) {
            return;
        }
        ChunkPos loadedChunk = event.getChunk().getPos();
        MinecraftServer server = level.getServer();
        // Load can fire on the server thread before the chunk's FULL future
        // completes. Querying its blocks inline waits on that same callback.
        // tell always queues; execute may run immediately on the server thread.
        server.tell(new net.minecraft.server.TickTask(server.getTickCount(),
                () -> wakeAnchorsTargeting(level, loadedChunk)));
    }

    static void wakeAnchorsTargeting(ServerLevel level, ChunkPos loadedChunk) {
        if (!BuilderConfig.isEnabled() || !level.getChunkSource().hasChunk(loadedChunk.x, loadedChunk.z)) {
            return;
        }
        MinecraftServer server = level.getServer();
        if (server.getLevel(Level.OVERWORLD) == null) {
            return;
        }
        for (AnchorIndexSavedData.AnchorLocation location : AnchorIndexSavedData.get(server)
                .findTargetingChunk(level.dimension(), loadedChunk)) {
            // Never load the adjacent anchor chunk merely to validate it.
            var position = location.position();
            var anchorChunk = level.getChunkSource().getChunkNow(position.getX() >> 4, position.getZ() >> 4);
            if (anchorChunk == null) {
                continue;
            }
            BlockState state = anchorChunk.getBlockState(position);
            if (state.is(ModBlocks.RESONANT_SUPPLY_ANCHOR.get())
                    && state.getValue(ResonantSupplyAnchorBlock.FACING) == location.facing()) {
                level.scheduleTick(location.position(), ModBlocks.RESONANT_SUPPLY_ANCHOR.get(), 1);
            }
        }
    }
}