blob: 8712319d82a73627a8c9ab2e71c000f2ba36a01e [file] [log] [blame] [raw]
package mekanism.common;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;
import mekanism.common.frequency.FrequencyManager;
import mekanism.common.multiblock.MultiblockManager;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.World;
import net.minecraft.world.gen.ChunkProviderServer;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent.Phase;
import net.minecraftforge.fml.common.gameevent.TickEvent.WorldTickEvent;
import net.minecraftforge.fml.relauncher.Side;
public class CommonWorldTickHandler
{
private static final long maximumDeltaTimeNanoSecs = 16000000; // 16 milliseconds
private HashMap<Integer, Queue<ChunkPos>> chunkRegenMap;
public void addRegenChunk(int dimensionId, ChunkPos chunkCoord)
{
if(chunkRegenMap == null)
{
chunkRegenMap = new HashMap<>();
}
if(!chunkRegenMap.containsKey(dimensionId))
{
LinkedList<ChunkPos> list = new LinkedList<>();
list.add(chunkCoord);
chunkRegenMap.put(dimensionId, list);
}
else {
if(!chunkRegenMap.get(dimensionId).contains(chunkCoord))
{
chunkRegenMap.get(dimensionId).add(chunkCoord);
}
}
}
public void resetRegenChunks()
{
if(chunkRegenMap != null)
{
chunkRegenMap.clear();
}
}
@SubscribeEvent
public void onTick(WorldTickEvent event)
{
if(event.side == Side.SERVER)
{
if(event.phase == Phase.START)
{
tickStart(event.world);
}
else if(event.phase == Phase.END)
{
tickEnd(event.world);
}
}
}
public void tickStart(World world)
{
if(!world.isRemote)
{
if(!FrequencyManager.loaded)
{
FrequencyManager.load(world);
}
}
}
public void tickEnd(World world)
{
if(!world.isRemote)
{
MultiblockManager.tick(world);
FrequencyManager.tick(world);
if(chunkRegenMap == null)
{
return;
}
int dimensionId = world.provider.getDimension();
//Credit to E. Beef
if(chunkRegenMap.containsKey(dimensionId))
{
Queue<ChunkPos> chunksToGen = chunkRegenMap.get(dimensionId);
long startTime = System.nanoTime();
while(System.nanoTime() - startTime < maximumDeltaTimeNanoSecs && !chunksToGen.isEmpty())
{
ChunkPos nextChunk = chunksToGen.poll();
if(nextChunk == null)
{
break;
}
Random fmlRandom = new Random(world.getSeed());
long xSeed = fmlRandom.nextLong() >> 2 + 1L;
long zSeed = fmlRandom.nextLong() >> 2 + 1L;
fmlRandom.setSeed((xSeed*nextChunk.x + zSeed*nextChunk.z) ^ world.getSeed());
Mekanism.genHandler.generate(fmlRandom, nextChunk.x, nextChunk.z, world, ((ChunkProviderServer)world.getChunkProvider()).chunkGenerator, world.getChunkProvider());
Mekanism.logger.info("[Mekanism] Regenerating ores at chunk " + nextChunk);
}
if(chunksToGen.isEmpty())
{
chunkRegenMap.remove(dimensionId);
}
}
}
}
}