blusunrize.immersiveengineering.common.world.IEWorldGen.java Source code

Java tutorial

Introduction

Here is the source code for blusunrize.immersiveengineering.common.world.IEWorldGen.java

Source

/*
 * BluSunrize
 * Copyright (c) 2017
 *
 * This code is licensed under "Blu's License of Common Sense"
 * Details can be found in the license file in the root folder of this project
 */

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.IChunkProvider;
import net.minecraft.world.gen.IChunkGenerator;
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().getPos() + " has been flagged for Ore RetroGeneration by IE.");
            retrogenChunks.put(dimension, event.getChunk().getPos());
        }
    }

    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.x + zSeed * loc.z ^ worldSeed);
                this.generateOres(fmlRandom, loc.x, loc.z, 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");
    }
}