Refactored chunk and world generation handling
- common world generator class - load default chunk date during generation - prevent loading chunk with invalid data - add a few logs to catch bad transitions
This commit is contained in:
parent
9bd098bd4f
commit
aa3d1b665e
7 changed files with 171 additions and 92 deletions
|
@ -118,6 +118,7 @@ import cr0s.warpdrive.data.JumpgatesRegistry;
|
||||||
import cr0s.warpdrive.data.StarMapRegistry;
|
import cr0s.warpdrive.data.StarMapRegistry;
|
||||||
import cr0s.warpdrive.event.ChunkHandler;
|
import cr0s.warpdrive.event.ChunkHandler;
|
||||||
import cr0s.warpdrive.event.ClientHandler;
|
import cr0s.warpdrive.event.ClientHandler;
|
||||||
|
import cr0s.warpdrive.event.CommonWorldGenerator;
|
||||||
import cr0s.warpdrive.event.LivingHandler;
|
import cr0s.warpdrive.event.LivingHandler;
|
||||||
import cr0s.warpdrive.event.WorldHandler;
|
import cr0s.warpdrive.event.WorldHandler;
|
||||||
import cr0s.warpdrive.item.ItemAirTank;
|
import cr0s.warpdrive.item.ItemAirTank;
|
||||||
|
@ -141,9 +142,7 @@ import cr0s.warpdrive.render.RenderOverlayAir;
|
||||||
import cr0s.warpdrive.render.RenderOverlayCamera;
|
import cr0s.warpdrive.render.RenderOverlayCamera;
|
||||||
import cr0s.warpdrive.render.RenderOverlayLocation;
|
import cr0s.warpdrive.render.RenderOverlayLocation;
|
||||||
import cr0s.warpdrive.world.BiomeSpace;
|
import cr0s.warpdrive.world.BiomeSpace;
|
||||||
import cr0s.warpdrive.world.HyperSpaceWorldGenerator;
|
|
||||||
import cr0s.warpdrive.world.HyperSpaceWorldProvider;
|
import cr0s.warpdrive.world.HyperSpaceWorldProvider;
|
||||||
import cr0s.warpdrive.world.SpaceWorldGenerator;
|
|
||||||
import cr0s.warpdrive.world.SpaceWorldProvider;
|
import cr0s.warpdrive.world.SpaceWorldProvider;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
@ -274,9 +273,7 @@ public class WarpDrive implements LoadingCallback {
|
||||||
|
|
||||||
public static BiomeGenBase spaceBiome;
|
public static BiomeGenBase spaceBiome;
|
||||||
@SuppressWarnings("FieldCanBeLocal")
|
@SuppressWarnings("FieldCanBeLocal")
|
||||||
private SpaceWorldGenerator spaceWorldGenerator;
|
private CommonWorldGenerator commonWorldGenerator;
|
||||||
@SuppressWarnings("FieldCanBeLocal")
|
|
||||||
private HyperSpaceWorldGenerator hyperSpaceWorldGenerator;
|
|
||||||
|
|
||||||
public static Field fieldBlockHardness = null;
|
public static Field fieldBlockHardness = null;
|
||||||
|
|
||||||
|
@ -683,10 +680,8 @@ public class WarpDrive implements LoadingCallback {
|
||||||
|
|
||||||
ForgeChunkManager.setForcedChunkLoadingCallback(instance, instance);
|
ForgeChunkManager.setForcedChunkLoadingCallback(instance, instance);
|
||||||
|
|
||||||
spaceWorldGenerator = new SpaceWorldGenerator();
|
commonWorldGenerator = new CommonWorldGenerator();
|
||||||
GameRegistry.registerWorldGenerator(spaceWorldGenerator, 0);
|
GameRegistry.registerWorldGenerator(commonWorldGenerator, 0);
|
||||||
hyperSpaceWorldGenerator = new HyperSpaceWorldGenerator();
|
|
||||||
GameRegistry.registerWorldGenerator(hyperSpaceWorldGenerator, 0);
|
|
||||||
|
|
||||||
spaceBiome = (new BiomeSpace(WarpDriveConfig.G_SPACE_BIOME_ID)).setColor(0).setDisableRain().setBiomeName("Space");
|
spaceBiome = (new BiomeSpace(WarpDriveConfig.G_SPACE_BIOME_ID)).setColor(0).setDisableRain().setBiomeName("Space");
|
||||||
BiomeDictionary.registerBiomeType(spaceBiome, BiomeDictionary.Type.DEAD, BiomeDictionary.Type.WASTELAND);
|
BiomeDictionary.registerBiomeType(spaceBiome, BiomeDictionary.Type.DEAD, BiomeDictionary.Type.WASTELAND);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package cr0s.warpdrive.compat;
|
package cr0s.warpdrive.compat;
|
||||||
|
|
||||||
|
|
||||||
|
import cr0s.warpdrive.WarpDrive;
|
||||||
import cr0s.warpdrive.api.IBlockTransformer;
|
import cr0s.warpdrive.api.IBlockTransformer;
|
||||||
import cr0s.warpdrive.api.ITransformation;
|
import cr0s.warpdrive.api.ITransformation;
|
||||||
import cr0s.warpdrive.block.breathing.BlockAirFlow;
|
import cr0s.warpdrive.block.breathing.BlockAirFlow;
|
||||||
|
@ -8,6 +9,7 @@ import cr0s.warpdrive.block.breathing.BlockAirSource;
|
||||||
import cr0s.warpdrive.block.energy.TileEntityEnergyBank;
|
import cr0s.warpdrive.block.energy.TileEntityEnergyBank;
|
||||||
import cr0s.warpdrive.block.hull.BlockHullSlab;
|
import cr0s.warpdrive.block.hull.BlockHullSlab;
|
||||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||||
|
import cr0s.warpdrive.data.ChunkData;
|
||||||
import cr0s.warpdrive.data.StateAir;
|
import cr0s.warpdrive.data.StateAir;
|
||||||
import cr0s.warpdrive.event.ChunkHandler;
|
import cr0s.warpdrive.event.ChunkHandler;
|
||||||
|
|
||||||
|
@ -15,7 +17,6 @@ import net.minecraft.block.Block;
|
||||||
import net.minecraft.nbt.NBTBase;
|
import net.minecraft.nbt.NBTBase;
|
||||||
import net.minecraft.nbt.NBTTagCompound;
|
import net.minecraft.nbt.NBTTagCompound;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.world.IWorldAccess;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class CompatWarpDrive implements IBlockTransformer {
|
public class CompatWarpDrive implements IBlockTransformer {
|
||||||
|
@ -39,7 +40,14 @@ public class CompatWarpDrive implements IBlockTransformer {
|
||||||
public NBTBase saveExternals(final World world, final int x, final int y, final int z,
|
public NBTBase saveExternals(final World world, final int x, final int y, final int z,
|
||||||
final Block block, final int blockMeta, final TileEntity tileEntity) {
|
final Block block, final int blockMeta, final TileEntity tileEntity) {
|
||||||
if (block instanceof BlockAirFlow || block instanceof BlockAirSource) {
|
if (block instanceof BlockAirFlow || block instanceof BlockAirSource) {
|
||||||
final int dataAir = ChunkHandler.getChunkData(world, x, y, z).getDataAir(x, y, z);
|
final ChunkData chunkData = ChunkHandler.getChunkData(world, x, y, z, false);
|
||||||
|
if (chunkData == null) {
|
||||||
|
WarpDrive.logger.error(String.format("CompatWarpDrive trying to get data from an non-loaded chunk in %s @ (%d %d %d)",
|
||||||
|
world.provider.getDimensionName(), x, y, z));
|
||||||
|
assert(false);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
final int dataAir = chunkData.getDataAir(x, y, z);
|
||||||
if (dataAir == StateAir.AIR_DEFAULT) {
|
if (dataAir == StateAir.AIR_DEFAULT) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -115,7 +123,14 @@ public class CompatWarpDrive implements IBlockTransformer {
|
||||||
}
|
}
|
||||||
if (((NBTTagCompound) nbtBase).hasKey("dataAir")) {
|
if (((NBTTagCompound) nbtBase).hasKey("dataAir")) {
|
||||||
final int dataAir = ((NBTTagCompound) nbtBase).getInteger("dataAir");
|
final int dataAir = ((NBTTagCompound) nbtBase).getInteger("dataAir");
|
||||||
ChunkHandler.getChunkData(world, x, y, z).setDataAir(x, y, z, dataAir);
|
final ChunkData chunkData = ChunkHandler.getChunkData(world, x, y, z, false);
|
||||||
|
if (chunkData == null) {
|
||||||
|
WarpDrive.logger.error(String.format("CompatWarpDrive trying to set data from an non-loaded chunk in %s @ (%d %d %d)",
|
||||||
|
world.provider.getDimensionName(), x, y, z));
|
||||||
|
assert(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chunkData.setDataAir(x, y, z, dataAir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,21 +63,21 @@ public class ChunkData {
|
||||||
&& time - timeUnloaded < RELOAD_DELAY_MIN_MS ) {
|
&& time - timeUnloaded < RELOAD_DELAY_MIN_MS ) {
|
||||||
WarpDrive.logger.warn(String.format("Chunk %s (%d %d %d) is reloading after only %d ms",
|
WarpDrive.logger.warn(String.format("Chunk %s (%d %d %d) is reloading after only %d ms",
|
||||||
chunkCoordIntPair,
|
chunkCoordIntPair,
|
||||||
getChunkPosition().chunkPosX, getChunkPosition().chunkPosY, getChunkPosition().chunkPosZ,
|
getChunkPosition().chunkPosX, getChunkPosition().chunkPosY, getChunkPosition().chunkPosZ,
|
||||||
time - timeUnloaded));
|
time - timeUnloaded));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load defaults
|
||||||
|
Arrays.fill(dataAirSegments, null);
|
||||||
|
Arrays.fill(tickAirSegments, null);
|
||||||
|
isModified = false;
|
||||||
|
|
||||||
// check version
|
// check version
|
||||||
if (nbtTagCompoundChunk.hasKey(TAG_CHUNK_MOD_DATA)) {
|
if (nbtTagCompoundChunk.hasKey(TAG_CHUNK_MOD_DATA)) {
|
||||||
final NBTTagCompound nbtTagCompound = nbtTagCompoundChunk.getCompoundTag(TAG_CHUNK_MOD_DATA);
|
final NBTTagCompound nbtTagCompound = nbtTagCompoundChunk.getCompoundTag(TAG_CHUNK_MOD_DATA);
|
||||||
final int version = nbtTagCompound.getInteger(TAG_VERSION);
|
final int version = nbtTagCompound.getInteger(TAG_VERSION);
|
||||||
assert (version == 0 || version == 1);
|
assert (version == 0 || version == 1);
|
||||||
|
|
||||||
// load defaults
|
|
||||||
Arrays.fill(dataAirSegments, null);
|
|
||||||
Arrays.fill(tickAirSegments, null);
|
|
||||||
isModified = false;
|
|
||||||
|
|
||||||
// load from NBT data
|
// load from NBT data
|
||||||
if (version == 1) {
|
if (version == 1) {
|
||||||
final NBTTagList nbtTagList = nbtTagCompound.getTagList(TAG_AIR, Constants.NBT.TAG_COMPOUND);
|
final NBTTagList nbtTagList = nbtTagCompound.getTagList(TAG_AIR, Constants.NBT.TAG_COMPOUND);
|
||||||
|
@ -142,7 +142,7 @@ public class ChunkData {
|
||||||
// mark as loaded
|
// mark as loaded
|
||||||
timeLoaded = time;
|
timeLoaded = time;
|
||||||
isLoaded = true;
|
isLoaded = true;
|
||||||
if (WarpDrive.isDev && WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
||||||
WarpDrive.logger.info(String.format("Chunk %s (%d %d %d) is now loaded",
|
WarpDrive.logger.info(String.format("Chunk %s (%d %d %d) is now loaded",
|
||||||
chunkCoordIntPair,
|
chunkCoordIntPair,
|
||||||
getChunkPosition().chunkPosX, getChunkPosition().chunkPosY, getChunkPosition().chunkPosZ));
|
getChunkPosition().chunkPosX, getChunkPosition().chunkPosY, getChunkPosition().chunkPosZ));
|
||||||
|
@ -496,10 +496,10 @@ public class ChunkData {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final ChunkPosition chunkPosition = getChunkPosition();
|
final ChunkPosition chunkPosition = getChunkPosition();
|
||||||
return String.format("%s (%d %d @ %d %d %d) hasAir %s isNotEmpty %s )",
|
return String.format("%s (%d %d @ %d %d %d) isLoaded %s hasAir %s isNotEmpty %s )",
|
||||||
getClass().getSimpleName(),
|
getClass().getSimpleName(),
|
||||||
chunkCoordIntPair.chunkXPos, chunkCoordIntPair.chunkZPos,
|
chunkCoordIntPair.chunkXPos, chunkCoordIntPair.chunkZPos,
|
||||||
chunkPosition.chunkPosX, chunkPosition.chunkPosY, chunkPosition.chunkPosZ,
|
chunkPosition.chunkPosX, chunkPosition.chunkPosY, chunkPosition.chunkPosZ,
|
||||||
hasAir(), isNotEmpty());
|
isLoaded, hasAir(), isNotEmpty());
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -91,7 +91,12 @@ public class StateAir {
|
||||||
private void refresh(final World world) {
|
private void refresh(final World world) {
|
||||||
// update chunk cache
|
// update chunk cache
|
||||||
if (chunkData == null || !chunkData.isInside(x, y, z)) {
|
if (chunkData == null || !chunkData.isInside(x, y, z)) {
|
||||||
chunkData = ChunkHandler.getChunkData(world, x, y, z);
|
chunkData = ChunkHandler.getChunkData(world, x, y, z, false);
|
||||||
|
if (chunkData == null) {
|
||||||
|
WarpDrive.logger.error(String.format("State air trying to get data from an non-loaded chunk in %s @ (%d %d %d)",
|
||||||
|
world.provider.getDimensionName(), x, y, z));
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
chunk = null;
|
chunk = null;
|
||||||
}
|
}
|
||||||
if (chunk == null) {
|
if (chunk == null) {
|
||||||
|
|
|
@ -23,7 +23,6 @@ import cpw.mods.fml.common.gameevent.TickEvent.WorldTickEvent;
|
||||||
import cpw.mods.fml.relauncher.Side;
|
import cpw.mods.fml.relauncher.Side;
|
||||||
import net.minecraftforge.event.world.ChunkDataEvent;
|
import net.minecraftforge.event.world.ChunkDataEvent;
|
||||||
import net.minecraftforge.event.world.ChunkEvent;
|
import net.minecraftforge.event.world.ChunkEvent;
|
||||||
import net.minecraftforge.event.world.ChunkWatchEvent;
|
|
||||||
import net.minecraftforge.event.world.WorldEvent;
|
import net.minecraftforge.event.world.WorldEvent;
|
||||||
|
|
||||||
public class ChunkHandler {
|
public class ChunkHandler {
|
||||||
|
@ -40,48 +39,72 @@ public class ChunkHandler {
|
||||||
/* event catchers */
|
/* event catchers */
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onLoadWorld(WorldEvent.Load event) {
|
public void onLoadWorld(WorldEvent.Load event) {
|
||||||
if (event.world.isRemote || event.world.provider.dimensionId != 0) {
|
if (event.world.isRemote || event.world.provider.dimensionId == 0) {
|
||||||
return;
|
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
||||||
}
|
WarpDrive.logger.info(String.format("%s world %s load.",
|
||||||
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
event.world.isRemote ? "Client" : "Server",
|
||||||
WarpDrive.logger.info(String.format("World %s load.",
|
event.world.provider.getDimensionName()));
|
||||||
event.world.provider.getDimensionName()));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// load star map
|
if ( !event.world.isRemote
|
||||||
final String filename = String.format("%s/%s.dat", event.world.getSaveHandler().getWorldDirectory().getPath(), WarpDrive.MODID);
|
&& event.world.provider.dimensionId == 0 ) {
|
||||||
final NBTTagCompound tagCompound = Commons.readNBTFromFile(filename);
|
// load star map
|
||||||
WarpDrive.starMap.readFromNBT(tagCompound);
|
final String filename = String.format("%s/%s.dat", event.world.getSaveHandler().getWorldDirectory().getPath(), WarpDrive.MODID);
|
||||||
|
final NBTTagCompound tagCompound = Commons.readNBTFromFile(filename);
|
||||||
|
WarpDrive.starMap.readFromNBT(tagCompound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// new chunks aren't loaded
|
||||||
|
public static void onGenerated(final World world, final int chunkX, final int chunkZ) {
|
||||||
|
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
||||||
|
WarpDrive.logger.info(String.format("%s world %s chunk [%d, %d] generating",
|
||||||
|
world.isRemote ? "Client" : "Server",
|
||||||
|
world.provider.getDimensionName(),
|
||||||
|
chunkX, chunkZ));
|
||||||
|
}
|
||||||
|
|
||||||
|
final ChunkData chunkData = getChunkData(world.isRemote, world.provider.dimensionId, chunkX, chunkZ, true);
|
||||||
|
assert(chunkData != null);
|
||||||
|
// (world can load a non-generated chunk, or the chunk be regenerated, so we reset only as needed)
|
||||||
|
if (!chunkData.isLoaded()) {
|
||||||
|
chunkData.load(new NBTTagCompound());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// (server side only)
|
// (server side only)
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onLoadChunkData(ChunkDataEvent.Load event) {
|
public void onLoadChunkData(ChunkDataEvent.Load event) {
|
||||||
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
||||||
WarpDrive.logger.info(String.format("World %s chunk %s loading data",
|
WarpDrive.logger.info(String.format("%s world %s chunk %s loading data (1)",
|
||||||
|
event.world.isRemote ? "Client" : "Server",
|
||||||
event.world.provider.getDimensionName(),
|
event.world.provider.getDimensionName(),
|
||||||
event.getChunk().getChunkCoordIntPair()));
|
event.getChunk().getChunkCoordIntPair()));
|
||||||
}
|
}
|
||||||
|
|
||||||
final ChunkData chunkData = getChunkData(event.world.isRemote, event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition);
|
final ChunkData chunkData = getChunkData(event.world.isRemote, event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition, true);
|
||||||
|
assert(chunkData != null);
|
||||||
chunkData.load(event.getData());
|
chunkData.load(event.getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
// (called after data loading, only useful client side)
|
// (called after data loading, only useful client side)
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onLoadChunk(ChunkEvent.Load event) {
|
public void onLoadChunk(ChunkEvent.Load event) {
|
||||||
if (event.world.isRemote) {
|
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
||||||
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
WarpDrive.logger.info(String.format("%s world %s chunk %s loaded (2)",
|
||||||
WarpDrive.logger.info(String.format("World %s chunk %s loaded",
|
event.world.isRemote ? "Client" : "Server",
|
||||||
event.world.provider.getDimensionName(),
|
event.world.provider.getDimensionName(),
|
||||||
event.getChunk().getChunkCoordIntPair()));
|
event.getChunk().getChunkCoordIntPair()));
|
||||||
}
|
}
|
||||||
|
|
||||||
final ChunkData chunkData = getChunkData(event.world.isRemote, event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition);
|
if (event.world.isRemote) {
|
||||||
|
final ChunkData chunkData = getChunkData(event.world.isRemote, event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition, true);
|
||||||
|
assert(chunkData != null);
|
||||||
chunkData.load(new NBTTagCompound());
|
chunkData.load(new NBTTagCompound());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
// (server side only)
|
// (server side only)
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onWatchChunk(ChunkWatchEvent.Watch event) {
|
public void onWatchChunk(ChunkWatchEvent.Watch event) {
|
||||||
|
@ -92,31 +115,44 @@ public class ChunkHandler {
|
||||||
event.player));
|
event.player));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**/
|
||||||
// (server side only)
|
// (server side only)
|
||||||
// not called when chunk wasn't changed since last save?
|
// not called when chunk wasn't changed since last save?
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onSaveChunkData(ChunkDataEvent.Save event) {
|
public void onSaveChunkData(ChunkDataEvent.Save event) {
|
||||||
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
||||||
WarpDrive.logger.info(String.format("World %s chunk %s save data",
|
WarpDrive.logger.info(String.format("%s world %s chunk %s save data",
|
||||||
|
event.world.isRemote ? "Client" : "Server",
|
||||||
event.world.provider.getDimensionName(),
|
event.world.provider.getDimensionName(),
|
||||||
event.getChunk().getChunkCoordIntPair()));
|
event.getChunk().getChunkCoordIntPair()));
|
||||||
}
|
}
|
||||||
final ChunkData chunkData = getChunkData(event.world.isRemote, event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition);
|
final ChunkData chunkData = getChunkData(event.world.isRemote, event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition, false);
|
||||||
chunkData.save(event.getData());
|
if (chunkData != null) {
|
||||||
|
chunkData.save(event.getData());
|
||||||
|
} else {
|
||||||
|
WarpDrive.logger.error(String.format("%s world %s chunk %s is saving data without loading it first!",
|
||||||
|
event.world.isRemote ? "Client" : "Server",
|
||||||
|
event.world.provider.getDimensionName(),
|
||||||
|
event.getChunk().getChunkCoordIntPair()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// (server side only)
|
// (server side only)
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onSaveWorld(WorldEvent.Save event) {
|
public void onSaveWorld(WorldEvent.Save event) {
|
||||||
if (event.world.isRemote || event.world.provider.dimensionId != 0) {
|
if (event.world.provider.dimensionId != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
||||||
WarpDrive.logger.info(String.format("World %s saved.",
|
WarpDrive.logger.info(String.format("%s world %s saved.",
|
||||||
|
event.world.isRemote ? "Client" : "Server",
|
||||||
event.world.provider.getDimensionName()));
|
event.world.provider.getDimensionName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (event.world.isRemote) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// save star map
|
// save star map
|
||||||
final String filename = String.format("%s/%s.dat", event.world.getSaveHandler().getWorldDirectory().getPath(), WarpDrive.MODID);
|
final String filename = String.format("%s/%s.dat", event.world.getSaveHandler().getWorldDirectory().getPath(), WarpDrive.MODID);
|
||||||
final NBTTagCompound tagCompound = new NBTTagCompound();
|
final NBTTagCompound tagCompound = new NBTTagCompound();
|
||||||
|
@ -127,7 +163,8 @@ public class ChunkHandler {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onUnloadWorld(WorldEvent.Unload event) {
|
public void onUnloadWorld(WorldEvent.Unload event) {
|
||||||
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
||||||
WarpDrive.logger.info(String.format("World %s unload",
|
WarpDrive.logger.info(String.format("%s world %s unload",
|
||||||
|
event.world.isRemote ? "Client" : "Server",
|
||||||
event.world.provider.getDimensionName()));
|
event.world.provider.getDimensionName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,10 +181,6 @@ public class ChunkHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.world.isRemote || event.world.provider.dimensionId != 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// @TODO unload star map
|
// @TODO unload star map
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,25 +189,36 @@ public class ChunkHandler {
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onUnloadChunk(ChunkEvent.Unload event) {
|
public void onUnloadChunk(ChunkEvent.Unload event) {
|
||||||
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
||||||
WarpDrive.logger.info(String.format("World %s chunk %s unload",
|
WarpDrive.logger.info(String.format("%s world %s chunk %s unload",
|
||||||
|
event.world.isRemote ? "Client" : "Server",
|
||||||
event.world.provider.getDimensionName(),
|
event.world.provider.getDimensionName(),
|
||||||
event.getChunk().getChunkCoordIntPair()));
|
event.getChunk().getChunkCoordIntPair()));
|
||||||
}
|
}
|
||||||
|
|
||||||
getChunkData(event.world.isRemote, event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition).unload();
|
final ChunkData chunkData = getChunkData(event.world.isRemote, event.world.provider.dimensionId, event.getChunk().xPosition, event.getChunk().zPosition, false);
|
||||||
|
if (chunkData != null) {
|
||||||
|
chunkData.unload();
|
||||||
|
} else {
|
||||||
|
WarpDrive.logger.error(String.format("%s world %s chunk %s is unloading without loading it first!",
|
||||||
|
event.world.isRemote ? "Client" : "Server",
|
||||||
|
event.world.provider.getDimensionName(),
|
||||||
|
event.getChunk().getChunkCoordIntPair()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
// (not called when closing SSP game)
|
// (not called when closing SSP game)
|
||||||
|
// warning: will return invalid world when switching dimensions
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onUnwatchChunk(ChunkWatchEvent.UnWatch event) {
|
public void onUnwatchChunk(ChunkWatchEvent.UnWatch event) {
|
||||||
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
||||||
WarpDrive.logger.info(String.format("World %s chunk %s unwatch by %s",
|
WarpDrive.logger.info(String.format("%s world %s chunk %s unwatch by %s",
|
||||||
|
event.player.worldObj.isRemote ? "Client" : "Server",
|
||||||
event.player.worldObj.provider.getDimensionName(),
|
event.player.worldObj.provider.getDimensionName(),
|
||||||
event.chunk,
|
event.chunk,
|
||||||
event.player));
|
event.player));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**/
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void onWorldTick(WorldTickEvent event) {
|
public void onWorldTick(WorldTickEvent event) {
|
||||||
if (event.side != Side.SERVER || event.phase != Phase.END) {
|
if (event.side != Side.SERVER || event.phase != Phase.END) {
|
||||||
|
@ -186,21 +230,29 @@ public class ChunkHandler {
|
||||||
|
|
||||||
public static void onBlockUpdated(final World world, final int x, final int y, final int z) {
|
public static void onBlockUpdated(final World world, final int x, final int y, final int z) {
|
||||||
if (!world.isRemote) {
|
if (!world.isRemote) {
|
||||||
getChunkData(world, x, y, z).onBlockUpdated(x, y, z);
|
final ChunkData chunkData = getChunkData(world, x, y, z, false);
|
||||||
|
if (chunkData != null) {
|
||||||
|
chunkData.onBlockUpdated(x, y, z);
|
||||||
|
} else {
|
||||||
|
WarpDrive.logger.error(String.format("%s world %s block updating at (%d %d %d), while chunk isn't loaded!",
|
||||||
|
world.isRemote ? "Client" : "Server",
|
||||||
|
world.provider.getDimensionName(),
|
||||||
|
x, y, z));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* internal access */
|
/* internal access */
|
||||||
public static ChunkData getChunkData(final World world, final int x, final int y, final int z) {
|
public static ChunkData getChunkData(final World world, final int x, final int y, final int z, final boolean doCreate) {
|
||||||
return getChunkData(world.isRemote, world.provider.dimensionId, x, y, z);
|
return getChunkData(world.isRemote, world.provider.dimensionId, x, y, z, doCreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ChunkData getChunkData(final boolean isRemote, final int dimensionId, final int x, final int y, final int z) {
|
private static ChunkData getChunkData(final boolean isRemote, final int dimensionId, final int x, final int y, final int z, final boolean doCreate) {
|
||||||
assert (y >= 0 && y <= 255);
|
assert (y >= 0 && y <= 255);
|
||||||
return getChunkData(isRemote, dimensionId, x >> 4, z >> 4);
|
return getChunkData(isRemote, dimensionId, x >> 4, z >> 4, doCreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ChunkData getChunkData(final boolean isRemote, final int dimensionId, final int xChunk, final int zChunk) {
|
private static ChunkData getChunkData(final boolean isRemote, final int dimensionId, final int xChunk, final int zChunk, final boolean doCreate) {
|
||||||
// get dimension data
|
// get dimension data
|
||||||
LocalProfiler.updateCallStat("getChunkData");
|
LocalProfiler.updateCallStat("getChunkData");
|
||||||
final Map<Integer, Map<Long, ChunkData>> registry = isRemote ? registryClient : registryServer;
|
final Map<Integer, Map<Long, ChunkData>> registry = isRemote ? registryClient : registryServer;
|
||||||
|
@ -208,6 +260,9 @@ public class ChunkHandler {
|
||||||
// (lambda expressions are forcing synchronisation, so we don't use them here)
|
// (lambda expressions are forcing synchronisation, so we don't use them here)
|
||||||
//noinspection Java8MapApi
|
//noinspection Java8MapApi
|
||||||
if (mapRegistryItems == null) {
|
if (mapRegistryItems == null) {
|
||||||
|
if (!doCreate) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
// TLongObjectMap<ChunkData> m = TCollections.synchronizedMap(new TLongObjectHashMap<ChunkData>(2048) );
|
// TLongObjectMap<ChunkData> m = TCollections.synchronizedMap(new TLongObjectHashMap<ChunkData>(2048) );
|
||||||
// @TODO: http://trove4j.sourceforge.net/javadocs/gnu/trove/TCollections.html#synchronizedMap(gnu.trove.map.TLongObjectMap)
|
// @TODO: http://trove4j.sourceforge.net/javadocs/gnu/trove/TCollections.html#synchronizedMap(gnu.trove.map.TLongObjectMap)
|
||||||
mapRegistryItems = new LinkedHashMap<>(2048); // Collections.synchronizedMap(new LinkedHashMap<>(2048));
|
mapRegistryItems = new LinkedHashMap<>(2048); // Collections.synchronizedMap(new LinkedHashMap<>(2048));
|
||||||
|
@ -219,7 +274,16 @@ public class ChunkHandler {
|
||||||
// (lambda expressions are forcing synchronisation, so we don't use them here)
|
// (lambda expressions are forcing synchronisation, so we don't use them here)
|
||||||
//noinspection Java8MapApi
|
//noinspection Java8MapApi
|
||||||
if (chunkData == null) {
|
if (chunkData == null) {
|
||||||
|
if (!doCreate) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
chunkData = new ChunkData(xChunk, zChunk);
|
chunkData = new ChunkData(xChunk, zChunk);
|
||||||
|
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
||||||
|
WarpDrive.logger.info(String.format("%s world DIM%d chunk %s is being added to the registry",
|
||||||
|
isRemote ? "Client" : "Server",
|
||||||
|
dimensionId,
|
||||||
|
chunkData.getChunkCoords()));
|
||||||
|
}
|
||||||
mapRegistryItems.put(index, chunkData);
|
mapRegistryItems.put(index, chunkData);
|
||||||
}
|
}
|
||||||
return chunkData;
|
return chunkData;
|
||||||
|
@ -234,12 +298,13 @@ public class ChunkHandler {
|
||||||
|
|
||||||
/* commons */
|
/* commons */
|
||||||
public static boolean isLoaded(final World world, final int x, final int y, final int z) {
|
public static boolean isLoaded(final World world, final int x, final int y, final int z) {
|
||||||
return getChunkData(world, x, y, z).isLoaded();
|
final ChunkData chunkData = getChunkData(world, x, y, z, false);
|
||||||
|
return chunkData != null && chunkData.isLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* air handling */
|
/* air handling */
|
||||||
public static StateAir getStateAir(final World world, final int x, final int y, final int z) {
|
public static StateAir getStateAir(final World world, final int x, final int y, final int z) {
|
||||||
return getChunkData(world, x, y, z).getStateAir(world, x, y, z);
|
return getChunkData(world, x, y, z, true).getStateAir(world, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void updateTick(final World world) {
|
public static void updateTick(final World world) {
|
||||||
|
@ -251,15 +316,25 @@ public class ChunkHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int countLoaded = 0;
|
int countLoaded = 0;
|
||||||
final long time = System.currentTimeMillis() - CHUNK_HANDLER_UNLOADED_CHUNK_MAX_AGE_MS;
|
final long timeForRemoval = System.currentTimeMillis() - CHUNK_HANDLER_UNLOADED_CHUNK_MAX_AGE_MS;
|
||||||
for(Iterator<Entry<Long, ChunkData>> entryIterator = mapRegistryItems.entrySet().iterator(); entryIterator.hasNext(); ) {
|
final long timeForThrottle = System.currentTimeMillis() + 200;
|
||||||
|
for(final Iterator<Entry<Long, ChunkData>> entryIterator = mapRegistryItems.entrySet().iterator(); entryIterator.hasNext(); ) {
|
||||||
final Map.Entry<Long, ChunkData> entryChunkData = entryIterator.next();
|
final Map.Entry<Long, ChunkData> entryChunkData = entryIterator.next();
|
||||||
final ChunkData chunkData = entryChunkData.getValue();
|
final ChunkData chunkData = entryChunkData.getValue();
|
||||||
// update loaded chunks, remove old unloaded chunks
|
// update loaded chunks, remove old unloaded chunks
|
||||||
if (chunkData.isLoaded()) {
|
if (chunkData.isLoaded()) {
|
||||||
updateTickLoopStep(world, mapRegistryItems, entryChunkData.getValue());
|
|
||||||
countLoaded++;
|
countLoaded++;
|
||||||
} else if (chunkData.timeUnloaded < time) {
|
if (System.currentTimeMillis() < timeForThrottle) {
|
||||||
|
updateTickLoopStep(world, mapRegistryItems, entryChunkData.getValue());
|
||||||
|
}
|
||||||
|
} else if (chunkData.timeUnloaded < timeForRemoval) {
|
||||||
|
if (WarpDriveConfig.LOGGING_CHUNK_HANDLER) {
|
||||||
|
WarpDrive.logger.info(String.format("%s world %s chunk %s is being removed from updateTick (size is %d)",
|
||||||
|
world.isRemote ? "Client" : "Server",
|
||||||
|
world.provider.getDimensionName(),
|
||||||
|
chunkData.getChunkCoords(),
|
||||||
|
mapRegistryItems.size()));
|
||||||
|
}
|
||||||
entryIterator.remove();
|
entryIterator.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cr0s.warpdrive.world;
|
package cr0s.warpdrive.event;
|
||||||
|
|
||||||
import cr0s.warpdrive.data.CelestialObjectManager;
|
import cr0s.warpdrive.data.CelestialObjectManager;
|
||||||
import cr0s.warpdrive.config.WarpDriveConfig;
|
import cr0s.warpdrive.config.WarpDriveConfig;
|
||||||
|
@ -7,6 +7,7 @@ import cr0s.warpdrive.config.structures.Orb.OrbShell;
|
||||||
import cr0s.warpdrive.config.structures.OrbInstance;
|
import cr0s.warpdrive.config.structures.OrbInstance;
|
||||||
import cr0s.warpdrive.config.structures.StructureGroup;
|
import cr0s.warpdrive.config.structures.StructureGroup;
|
||||||
import cr0s.warpdrive.data.CelestialObject;
|
import cr0s.warpdrive.data.CelestialObject;
|
||||||
|
import cr0s.warpdrive.event.ChunkHandler;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
@ -15,10 +16,14 @@ import net.minecraft.world.chunk.IChunkProvider;
|
||||||
|
|
||||||
import cpw.mods.fml.common.IWorldGenerator;
|
import cpw.mods.fml.common.IWorldGenerator;
|
||||||
|
|
||||||
public class SpaceWorldGenerator implements IWorldGenerator {
|
public class CommonWorldGenerator implements IWorldGenerator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
|
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
|
||||||
|
// chunk data creation
|
||||||
|
ChunkHandler.onGenerated(world, chunkX, chunkZ);
|
||||||
|
|
||||||
|
// actual structure generation
|
||||||
try {
|
try {
|
||||||
final int x = (chunkX * 16) + (5 - random.nextInt(10));
|
final int x = (chunkX * 16) + (5 - random.nextInt(10));
|
||||||
final int z = (chunkZ * 16) + (5 - random.nextInt(10));
|
final int z = (chunkZ * 16) + (5 - random.nextInt(10));
|
||||||
|
@ -45,6 +50,7 @@ public class SpaceWorldGenerator implements IWorldGenerator {
|
||||||
exception.printStackTrace();
|
exception.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @deprecated reference design for EntitySphereGenerator
|
* @deprecated reference design for EntitySphereGenerator
|
|
@ -1,17 +0,0 @@
|
||||||
package cr0s.warpdrive.world;
|
|
||||||
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import net.minecraft.world.World;
|
|
||||||
import net.minecraft.world.chunk.IChunkProvider;
|
|
||||||
|
|
||||||
import cpw.mods.fml.common.IWorldGenerator;
|
|
||||||
|
|
||||||
public class HyperSpaceWorldGenerator implements IWorldGenerator {
|
|
||||||
@Override
|
|
||||||
public void generate(Random random, int chunkX, int chunkZ, World world, IChunkProvider chunkGenerator, IChunkProvider chunkProvider) {
|
|
||||||
if (world.provider.dimensionId != 0) {
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue