jason13official

Wolves Force Load Chunks

Jul 28th, 2025
24
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 6.92 KB | Help | 0 0
  1. import net.minecraft.server.level.ServerLevel;
  2. import net.minecraft.world.entity.Entity;
  3. import net.minecraft.world.entity.animal.Wolf;
  4. import net.minecraft.world.level.ChunkPos;
  5. import net.minecraftforge.event.entity.EntityLeaveLevelEvent;
  6. import net.minecraftforge.event.entity.living.LivingEvent;
  7. import net.minecraftforge.event.server.ServerStartedEvent;
  8. import net.minecraftforge.event.server.ServerStoppingEvent;
  9. import net.minecraftforge.eventbus.api.SubscribeEvent;
  10. import net.minecraftforge.fml.common.Mod;
  11.  
  12. import java.util.*;
  13.  
  14. @Mod(Constants.MOD_ID) @Mod.EventBusSubscriber
  15. public class ExampleMod {
  16.  
  17.     public ExampleMod() {
  18.         CommonClass.init();
  19.     }
  20.  
  21.     // wolf UUID -> the last known ChunkPos of the wolf
  22.     public static final HashMap<UUID, ChunkPos> WOLF_POSITIONS = new HashMap<>();
  23.  
  24.     // wolf UUID -> the set of chunks the wolf is force-loading
  25.     public static final HashMap<UUID, Set<ChunkPos>> WOLF_CHUNKS = new HashMap<>();
  26.  
  27.     // chunk -> the set of wolves forcibly loading the chunk
  28.     public static final HashMap<ChunkPos, Set<UUID>> CHUNK_WOLVES = new HashMap<>();
  29.  
  30.     @SubscribeEvent
  31.     public static void onLivingTick(LivingEvent.LivingTickEvent event) {
  32.         if (event.getEntity() instanceof Wolf wolf && !wolf.level().isClientSide()) {
  33.             ExampleMod.onWolfTick(wolf);
  34.         }
  35.     }
  36.  
  37.     @SubscribeEvent
  38.     public static void onEntityLeaveWorld(EntityLeaveLevelEvent event) {
  39.         if (event.getEntity() instanceof Wolf wolf && !wolf.level().isClientSide()) {
  40.             ExampleMod.onWolfRemoved(wolf);
  41.         }
  42.     }
  43.  
  44.     @SubscribeEvent
  45.     public static void onWorldLoad(ServerStartedEvent event) {
  46.         event.getServer().getAllLevels().forEach(level -> {
  47.             ExampleMod.initializeForWorld(level);
  48.         });
  49.     }
  50.  
  51.     public static void initializeForWorld(ServerLevel level) {
  52.         for (Entity entity : level.getAllEntities()) {
  53.  
  54.             if (!(entity instanceof Wolf wolf)) return;
  55.  
  56.             Set<ChunkPos> chunks = getChunksAroundWolf(wolf);
  57.             forceLoadChunks(level, chunks);
  58.             WOLF_CHUNKS.put(wolf.getUUID(), chunks);
  59.         }
  60.     }
  61.  
  62.     @SubscribeEvent
  63.     public static void onWorldUnload(ServerStoppingEvent event) {
  64.         event.getServer().getAllLevels().forEach(level -> {
  65.             ExampleMod.cleanupForWorld(level);
  66.         });
  67.     }
  68.  
  69.     public static void cleanupForWorld(ServerLevel level) {
  70.  
  71.         Set<UUID> wolvesToRemove = new HashSet<>();
  72.  
  73.         for (Map.Entry<UUID, Set<ChunkPos>> entry : WOLF_CHUNKS.entrySet()) {
  74.  
  75.             UUID wolfId = entry.getKey();
  76.             Set<ChunkPos> chunks = entry.getValue();
  77.  
  78.             Entity entity = level.getEntity(wolfId);
  79.             if (entity instanceof Wolf && !chunks.isEmpty()) {
  80.  
  81.                 wolvesToRemove.add(wolfId);
  82.  
  83.                 for (ChunkPos chunk : chunks) {
  84.                     try {
  85.                         level.setChunkForced(chunk.x, chunk.z, false);
  86.                     }
  87.                     catch (Exception e) {
  88.                         System.err.println("Failed to unforce chunk " + chunk + ": " + e.getMessage());
  89.                     }
  90.                 }
  91.             }
  92.         }
  93.  
  94.         for (UUID wolfId : wolvesToRemove) {
  95.  
  96.             Set<ChunkPos> chunks = WOLF_CHUNKS.remove(wolfId);
  97.             WOLF_POSITIONS.remove(wolfId);
  98.  
  99.             if (chunks != null) {
  100.                 for (ChunkPos chunk : chunks) {
  101.                     Set<UUID> wolves = CHUNK_WOLVES.get(chunk);
  102.                     if (wolves != null) {
  103.                         wolves.remove(wolfId);
  104.                         if (wolves.isEmpty()) {
  105.                             CHUNK_WOLVES.remove(chunk);
  106.                         }
  107.                     }
  108.                 }
  109.             }
  110.         }
  111.     }
  112.  
  113.     private static Set<ChunkPos> getChunksAroundWolf(Wolf wolf) {
  114.         ChunkPos center = new ChunkPos(wolf.blockPosition());
  115.         Set<ChunkPos> chunkSet = new HashSet<>();
  116.  
  117.         for (int x = -1; x <= 1; ++x) {
  118.             for (int z = -1; z <= 1; ++z) {
  119.                 chunkSet.add(new ChunkPos(center.x + x, center.z + z));
  120.             }
  121.         }
  122.         return chunkSet;
  123.     }
  124.  
  125.     private static void forceLoadChunks(ServerLevel level, Set<ChunkPos> chunks) {
  126.         for (ChunkPos chunk : chunks) {
  127.             level.setChunkForced(chunk.x, chunk.z, true);
  128.         }
  129.     }
  130.  
  131.     public static void onWolfTick(Wolf wolf) {
  132.         UUID wolfId = wolf.getUUID();
  133.         ChunkPos currentChunk = new ChunkPos(wolf.blockPosition());
  134.         ChunkPos lastKnownChunk = WOLF_POSITIONS.get(wolfId);
  135.  
  136.         if (lastKnownChunk == null || !lastKnownChunk.equals(currentChunk)) {
  137.             updateWolfChunkLoading(wolf, currentChunk, lastKnownChunk);
  138.             WOLF_POSITIONS.put(wolfId, currentChunk);
  139.         }
  140.     }
  141.  
  142.     private static void updateWolfChunkLoading(Wolf wolf, ChunkPos newCenter, ChunkPos oldCenter) {
  143.         UUID wolfId = wolf.getUUID();
  144.         ServerLevel level = (ServerLevel) wolf.level();
  145.  
  146.         Set<ChunkPos> newChunks = getChunksAroundWolf(wolf);
  147.         Set<ChunkPos> oldChunks = WOLF_CHUNKS.getOrDefault(wolfId, new HashSet<>());
  148.  
  149.         Set<ChunkPos> chunksToUnload = new HashSet<>(oldChunks);
  150.         chunksToUnload.removeAll(newChunks);
  151.  
  152.         Set<ChunkPos> chunksToLoad = new HashSet<>(newChunks);
  153.         chunksToLoad.removeAll(oldChunks);
  154.  
  155.         for (ChunkPos chunk : chunksToUnload) {
  156.             removeWolfFromChunk(wolfId, chunk);
  157.             if (!CHUNK_WOLVES.containsKey(chunk) || CHUNK_WOLVES.get(chunk).isEmpty()) {
  158.                 level.setChunkForced(chunk.x, chunk.z, false);
  159.                 CHUNK_WOLVES.remove(chunk);
  160.             }
  161.         }
  162.  
  163.         for (ChunkPos chunk : chunksToLoad) {
  164.             addWolfToChunk(wolfId, chunk);
  165.             level.setChunkForced(chunk.x, chunk.z, true);
  166.         }
  167.  
  168.         WOLF_CHUNKS.put(wolfId, newChunks);
  169.     }
  170.  
  171.     private static void addWolfToChunk(UUID wolfId, ChunkPos chunk) {
  172.         CHUNK_WOLVES.computeIfAbsent(chunk, k -> new HashSet<>()).add(wolfId);
  173.     }
  174.  
  175.     private static void removeWolfFromChunk(UUID wolfId, ChunkPos chunk) {
  176.         Set<UUID> wolves = CHUNK_WOLVES.get(chunk);
  177.         if (wolves != null) {
  178.             wolves.remove(wolfId);
  179.         }
  180.     }
  181.  
  182.     public static void onWolfRemoved(Wolf wolf) {
  183.         UUID wolfId = wolf.getUUID();
  184.         Set<ChunkPos> chunks = WOLF_CHUNKS.remove(wolfId);
  185.         WOLF_POSITIONS.remove(wolfId);
  186.  
  187.         if (chunks != null) {
  188.             ServerLevel level = (ServerLevel) wolf.level();
  189.             for (ChunkPos chunk : chunks) {
  190.                 removeWolfFromChunk(wolfId, chunk);
  191.                 if (!CHUNK_WOLVES.containsKey(chunk) || CHUNK_WOLVES.get(chunk).isEmpty()) {
  192.                     level.setChunkForced(chunk.x, chunk.z, false);
  193.                     CHUNK_WOLVES.remove(chunk);
  194.                 }
  195.             }
  196.         }
  197.     }
  198. }
Tags: minecraft Java
Advertisement
Add Comment
Please, Sign In to add comment