Simple chunkloading implementation
This commit is contained in:
parent
a9e3a4dbb9
commit
d21e3ae218
6 changed files with 199 additions and 1 deletions
|
@ -1,8 +1,13 @@
|
|||
package net.minecraftforge.common;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.ListMultimap;
|
||||
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
|
||||
import net.minecraft.src.*;
|
||||
import net.minecraftforge.event.entity.item.ItemTossEvent;
|
||||
|
@ -354,4 +359,55 @@ public class ForgeHooks
|
|||
player.joinEntityItemWithWorld(event.entityItem);
|
||||
return event.entityItem;
|
||||
}
|
||||
public static void dumpPersistentChunks(WorldInfo worldInfo, ListMultimap<ChunkCoordIntPair, String> persistentChunks)
|
||||
{
|
||||
worldInfo.forgeWorldData = new NBTTagCompound();
|
||||
|
||||
NBTTagList chunkDataList = new NBTTagList();
|
||||
for (Entry<ChunkCoordIntPair, Collection<String>> entry : persistentChunks.asMap().entrySet())
|
||||
{
|
||||
NBTTagCompound dataList = new NBTTagCompound();
|
||||
dataList.setIntArray("Chunk", new int[] { entry.getKey().chunkXPos, entry.getKey().chunkZPos });
|
||||
NBTTagList modList = new NBTTagList();
|
||||
for (String modId : entry.getValue())
|
||||
{
|
||||
modList.appendTag(new NBTTagString(modId, ""));
|
||||
}
|
||||
dataList.setTag("Mods", modList);
|
||||
chunkDataList.appendTag(dataList);
|
||||
}
|
||||
worldInfo.forgeWorldData.setTag("PersistentChunks", chunkDataList);
|
||||
}
|
||||
|
||||
public static ListMultimap<ChunkCoordIntPair, String> loadPersistentChunkData(WorldInfo worldInfo)
|
||||
{
|
||||
ArrayListMultimap<ChunkCoordIntPair, String> chunkList = ArrayListMultimap.<ChunkCoordIntPair, String>create();
|
||||
|
||||
if (worldInfo == null || worldInfo.forgeWorldData == null)
|
||||
{
|
||||
return chunkList;
|
||||
}
|
||||
|
||||
NBTTagList chunkDataList = worldInfo.forgeWorldData.getTagList("PersistentChunks");
|
||||
for (int i = 0; i < chunkDataList.tagCount(); i++)
|
||||
{
|
||||
NBTTagCompound dataList = (NBTTagCompound) chunkDataList.tagAt(i);
|
||||
int[] ccpairint = dataList.getIntArray("Chunk");
|
||||
ChunkCoordIntPair ccpair = new ChunkCoordIntPair(ccpairint[0], ccpairint[1]);
|
||||
NBTTagList modList = dataList.getTagList("Mods");
|
||||
for (int j = 0; j < modList.tagCount(); j++)
|
||||
{
|
||||
String modId = modList.tagAt(j).getName();
|
||||
if (Loader.isModLoaded(modId))
|
||||
{
|
||||
chunkList.put(ccpair, modId);
|
||||
}
|
||||
else
|
||||
{
|
||||
FMLLog.warning("The mod %s is not present - it's chunks will not be persisted any longer", modId);
|
||||
}
|
||||
}
|
||||
}
|
||||
return chunkList;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,10 @@ package net.minecraftforge.common;
|
|||
import java.lang.reflect.Constructor;
|
||||
import java.util.*;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Mod;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
import net.minecraft.src.*;
|
||||
import net.minecraftforge.common.ForgeHooks.GrassEntry;
|
||||
|
@ -199,4 +202,42 @@ public class MinecraftForge
|
|||
{
|
||||
return "Minecraft Forge "+ ForgeVersion.getVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a chunk to remain loaded by the supplied mod
|
||||
*
|
||||
* @param chunk the chunk to keep loaded
|
||||
* @param world the world holding the chunk
|
||||
* @param mod the mod (either {@link Mod} or {@link BaseMod}) that wishes to force the load
|
||||
*/
|
||||
public static void forceChunkLoaded(ChunkCoordIntPair chunk, World world, Object mod)
|
||||
{
|
||||
ModContainer mc = FMLCommonHandler.instance().findContainerFor(mod);
|
||||
if (mc == null)
|
||||
{
|
||||
FMLLog.warning("Attempt to force chunk load for a non-existent mod %s", mod.getClass().getName());
|
||||
return;
|
||||
}
|
||||
String modId = mc.getModId();
|
||||
world.getPersistentChunks().put(chunk, modId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop forcing the chunk to remain loaded by the supplied mod (other mods may still
|
||||
* keep the chunk loaded, however)
|
||||
* @param chunk the chunk to keep loaded
|
||||
* @param world the world holding the chunk
|
||||
* @param mod the mod (either {@link Mod} or {@link BaseMod}) that wishes to unforce the load
|
||||
*/
|
||||
public static void unforceChunkLoaded(ChunkCoordIntPair chunk, World world, Object mod)
|
||||
{
|
||||
ModContainer mc = FMLCommonHandler.instance().findContainerFor(mod);
|
||||
if (mc == null)
|
||||
{
|
||||
FMLLog.warning("Attempt to unforce chunk load for a non-existent mod %s", mod.getClass().getName());
|
||||
return;
|
||||
}
|
||||
String modId = mc.getModId();
|
||||
world.getPersistentChunks().remove(chunk, modId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
--- ../src_base/common/net/minecraft/src/ChunkProviderServer.java
|
||||
+++ ../src_work/common/net/minecraft/src/ChunkProviderServer.java
|
||||
@@ -274,6 +274,11 @@
|
||||
{
|
||||
if (!this.currentServer.canNotSave)
|
||||
{
|
||||
+ for (ChunkCoordIntPair forced : currentServer.persistentChunks.keySet())
|
||||
+ {
|
||||
+ this.chunksToUnload.remove(ChunkCoordIntPair.chunkXZ2Int(forced.chunkXPos, forced.chunkZPos));
|
||||
+ }
|
||||
+
|
||||
for (int var1 = 0; var1 < 100; ++var1)
|
||||
{
|
||||
if (!this.chunksToUnload.isEmpty())
|
|
@ -4,6 +4,10 @@
|
|||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
+import com.google.common.collect.ArrayListMultimap;
|
||||
+import com.google.common.collect.ListMultimap;
|
||||
+
|
||||
+import net.minecraftforge.common.ForgeHooks;
|
||||
+import net.minecraftforge.common.MinecraftForge;
|
||||
+import net.minecraftforge.common.ForgeDirection;
|
||||
+import net.minecraftforge.event.entity.EntityEvent;
|
||||
|
@ -23,6 +27,12 @@
|
|||
/**
|
||||
* boolean; if true updates scheduled by scheduleBlockUpdate happen immediately
|
||||
*/
|
||||
@@ -128,6 +145,7 @@
|
||||
*/
|
||||
public boolean isRemote;
|
||||
|
||||
+ protected ListMultimap<ChunkCoordIntPair, String> persistentChunks;
|
||||
/**
|
||||
@@ -132,6 +146,11 @@
|
||||
* Gets the biome for a given set of x/z coordinates
|
||||
*/
|
||||
|
@ -47,6 +57,9 @@
|
|||
|
||||
this.calculateInitialSkylight();
|
||||
this.calculateInitialWeather();
|
||||
+
|
||||
+ persistentChunks = ForgeHooks.loadPersistentChunkData(this.worldInfo);
|
||||
+
|
||||
+ MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(this));
|
||||
}
|
||||
|
||||
|
@ -226,9 +239,11 @@
|
|||
@@ -1974,8 +2030,14 @@
|
||||
int var3 = MathHelper.floor_double(par1Entity.posX);
|
||||
int var4 = MathHelper.floor_double(par1Entity.posZ);
|
||||
byte var5 = 32;
|
||||
- byte var5 = 32;
|
||||
-
|
||||
- if (!par2 || this.checkChunksExist(var3 - var5, 0, var4 - var5, var3 + var5, 0, var4 + var5))
|
||||
+ boolean isForced = persistentChunks.containsKey(new ChunkCoordIntPair(var3 >> 4, var4 >> 4));
|
||||
+ byte var5 = isForced ? (byte)0 : 32;
|
||||
+ boolean canUpdate = !par2 || this.checkChunksExist(var3 - var5, 0, var4 - var5, var3 + var5, 0, var4 + var5);
|
||||
+ if (!canUpdate)
|
||||
+ {
|
||||
|
@ -658,5 +673,10 @@
|
|||
+ }
|
||||
+
|
||||
+ return block.isBlockSolidOnSide(this, X, Y, Z, side);
|
||||
+ }
|
||||
+
|
||||
+ public ListMultimap<ChunkCoordIntPair, String> getPersistentChunks()
|
||||
+ {
|
||||
+ return persistentChunks;
|
||||
+ }
|
||||
}
|
||||
|
|
38
patches/common/net/minecraft/src/WorldInfo.java.patch
Normal file
38
patches/common/net/minecraft/src/WorldInfo.java.patch
Normal file
|
@ -0,0 +1,38 @@
|
|||
--- ../src_base/common/net/minecraft/src/WorldInfo.java
|
||||
+++ ../src_work/common/net/minecraft/src/WorldInfo.java
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.minecraft.src;
|
||||
|
||||
+import net.minecraftforge.common.ForgeHooks;
|
||||
import cpw.mods.fml.common.Side;
|
||||
import cpw.mods.fml.common.asm.SideOnly;
|
||||
|
||||
@@ -59,6 +60,8 @@
|
||||
private boolean hardcore;
|
||||
private boolean allowCommands;
|
||||
private boolean initialized;
|
||||
+
|
||||
+ public NBTTagCompound forgeWorldData;
|
||||
|
||||
protected WorldInfo()
|
||||
{
|
||||
@@ -139,6 +142,10 @@
|
||||
{
|
||||
this.playerTag = par1NBTTagCompound.getCompoundTag("Player");
|
||||
this.dimension = this.playerTag.getInteger("Dimension");
|
||||
+ }
|
||||
+ if (par1NBTTagCompound.hasKey("ForgeData"))
|
||||
+ {
|
||||
+ this.forgeWorldData = par1NBTTagCompound.getCompoundTag("ForgeData");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,6 +235,8 @@
|
||||
{
|
||||
par1NBTTagCompound.setCompoundTag("Player", par2NBTTagCompound);
|
||||
}
|
||||
+
|
||||
+ par1NBTTagCompound.setCompoundTag("ForgeData", forgeWorldData);
|
||||
}
|
||||
|
||||
/**
|
|
@ -50,6 +50,26 @@
|
|||
{
|
||||
this.updateLCG = this.updateLCG * 3 + 1013904223;
|
||||
var8 = this.updateLCG >> 2;
|
||||
@@ -362,7 +367,8 @@
|
||||
public void scheduleBlockUpdate(int par1, int par2, int par3, int par4, int par5)
|
||||
{
|
||||
NextTickListEntry var6 = new NextTickListEntry(par1, par2, par3, par4);
|
||||
- byte var7 = 8;
|
||||
+ boolean isForced = persistentChunks.containsKey(new ChunkCoordIntPair(var6.xCoord >> 4, var6.zCoord >> 4));
|
||||
+ byte var7 = isForced ? (byte)0 : 8;
|
||||
|
||||
if (this.scheduledUpdatesAreImmediate)
|
||||
{
|
||||
@@ -462,7 +468,8 @@
|
||||
|
||||
this.pendingTickListEntries.remove(var4);
|
||||
this.field_73064_N.remove(var4);
|
||||
- byte var5 = 8;
|
||||
+ boolean isForced = persistentChunks.containsKey(new ChunkCoordIntPair(var4.xCoord >> 4, var4.zCoord >> 4));
|
||||
+ byte var5 = isForced ? (byte)0 : 8;
|
||||
|
||||
if (this.checkChunksExist(var4.xCoord - var5, var4.yCoord - var5, var4.zCoord - var5, var4.xCoord + var5, var4.yCoord + var5, var4.zCoord + var5))
|
||||
{
|
||||
@@ -559,15 +562,27 @@
|
||||
public List getAllTileEntityInBox(int par1, int par2, int par3, int par4, int par5, int par6)
|
||||
{
|
||||
|
@ -117,6 +137,15 @@
|
|||
|
||||
for (int var2 = 0; var2 < 10; ++var2)
|
||||
{
|
||||
@@ -702,6 +721,8 @@
|
||||
par2IProgressUpdate.displayProgressMessage("Saving level");
|
||||
}
|
||||
|
||||
+ ForgeHooks.dumpPersistentChunks(worldInfo, persistentChunks);
|
||||
+
|
||||
this.saveLevel();
|
||||
|
||||
if (par2IProgressUpdate != null)
|
||||
@@ -713,6 +733,7 @@
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue