package blusunrize.immersiveengineering.common.world; import blusunrize.immersiveengineering.common.Config.IEConfig; import blusunrize.immersiveengineering.common.util.IELogger; import com.google.common.collect.ArrayListMultimap; import net.minecraft.block.Block; import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.pattern.BlockMatcher; import net.minecraft.init.Blocks; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.ChunkPos; import net.minecraft.world.World; import net.minecraft.world.chunk.IChunkGenerator; import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.feature.WorldGenMinable; import net.minecraftforge.event.world.ChunkDataEvent; import net.minecraftforge.fml.common.IWorldGenerator; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; import net.minecraftforge.fml.relauncher.Side; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Random; public class IEWorldGen implements IWorldGenerator { public static class OreGen { String name; WorldGenMinable mineableGen; int minY; int maxY; int chunkOccurence; int weight; public OreGen(String name, IBlockState state, int maxVeinSize, Block replaceTarget, int minY, int maxY,int chunkOccurence, int weight) { this.name = name; this.mineableGen = new WorldGenMinable(state, maxVeinSize, BlockMatcher.forBlock(replaceTarget)); this.minY=minY; this.maxY=maxY; this.chunkOccurence=chunkOccurence; this.weight=weight; } public void generate(World world, Random rand, int x, int z) { BlockPos pos; for(int i=0; i<chunkOccurence; i++) if(rand.nextInt(100)<weight) { pos = new BlockPos(x + rand.nextInt(16), minY + rand.nextInt(maxY - minY), z + rand.nextInt(16)); mineableGen.generate(world, rand, pos); } } } public static ArrayList<OreGen> orespawnList = new ArrayList(); public static ArrayList<Integer> oreDimBlacklist = new ArrayList(); public static HashMap<String, Boolean> retrogenMap = new HashMap(); public static OreGen addOreGen(String name, IBlockState state, int maxVeinSize, int minY, int maxY,int chunkOccurence,int weight) { OreGen gen = new OreGen(name, state, maxVeinSize, Blocks.STONE, minY, maxY, chunkOccurence, weight); orespawnList.add(gen); return gen; } @Override public void generate(Random random, int chunkX, int chunkZ, World world, IChunkGenerator chunkGenerator, IChunkProvider chunkProvider) { this.generateOres(random, chunkX, chunkZ, world, true); } public void generateOres(Random random, int chunkX, int chunkZ, World world, boolean newGeneration) { if(!oreDimBlacklist.contains(world.provider.getDimension())) for(OreGen gen : orespawnList) if(newGeneration || retrogenMap.get("retrogen_"+gen.name)) gen.generate(world, random, chunkX*16, chunkZ*16); } @SubscribeEvent public void chunkSave(ChunkDataEvent.Save event) { NBTTagCompound nbt = new NBTTagCompound(); event.getData().setTag("ImmersiveEngineering", nbt); nbt.setBoolean(IEConfig.Ores.retrogen_key, true); } @SubscribeEvent public void chunkLoad(ChunkDataEvent.Load event) { int dimension = event.getWorld().provider.getDimension(); if((!event.getData().getCompoundTag("ImmersiveEngineering").hasKey(IEConfig.Ores.retrogen_key)) && (IEConfig.Ores.retrogen_copper|| IEConfig.Ores.retrogen_bauxite|| IEConfig.Ores.retrogen_lead|| IEConfig.Ores.retrogen_silver|| IEConfig.Ores.retrogen_nickel|| IEConfig.Ores.retrogen_uranium)) { if(IEConfig.Ores.retrogen_log_flagChunk) IELogger.info("Chunk "+event.getChunk().getChunkCoordIntPair()+" has been flagged for Ore RetroGeneration by IE."); retrogenChunks.put(dimension, event.getChunk().getChunkCoordIntPair()); } } public static ArrayListMultimap<Integer, ChunkPos> retrogenChunks = ArrayListMultimap.create(); @SubscribeEvent public void serverWorldTick(TickEvent.WorldTickEvent event) { if(event.side==Side.CLIENT || event.phase==TickEvent.Phase.START) return; int dimension = event.world.provider.getDimension(); int counter = 0; List<ChunkPos> chunks = retrogenChunks.get(dimension); if(chunks!=null && chunks.size()>0) for(int i=0; i<2; i++) { chunks = retrogenChunks.get(dimension); if(chunks == null || chunks.size()<= 0) break; counter++; ChunkPos loc = chunks.get(0); long worldSeed = event.world.getSeed(); Random fmlRandom = new Random(worldSeed); long xSeed = (fmlRandom.nextLong()>>3); long zSeed = (fmlRandom.nextLong()>>3); fmlRandom.setSeed(xSeed * loc.chunkXPos + zSeed * loc.chunkZPos ^ worldSeed); this.generateOres(fmlRandom, loc.chunkXPos, loc.chunkZPos, event.world, false); chunks.remove(0); } if(counter>0 && IEConfig.Ores.retrogen_log_remaining) IELogger.info("Retrogen was performed on "+counter+" Chunks, "+Math.max(0,chunks.size())+" chunks remaining"); } }