package joshie.harvest.mining.gen;
import com.google.common.collect.Lists;
import gnu.trove.map.TIntObjectMap;
import gnu.trove.map.hash.TIntObjectHashMap;
import joshie.harvest.api.HFApi;
import joshie.harvest.api.calendar.Season;
import joshie.harvest.core.HFCore;
import joshie.harvest.core.HFTrackers;
import joshie.harvest.mining.HFMining;
import joshie.harvest.mining.MiningHelper;
import joshie.harvest.mining.MiningRegistry;
import joshie.harvest.mining.block.BlockStone.Type;
import joshie.harvest.mining.entity.EntityDarkChick;
import joshie.harvest.mining.entity.EntityDarkChicken;
import joshie.harvest.mining.entity.EntityDarkCow;
import joshie.harvest.mining.entity.EntityDarkSheep;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EnumCreatureType;
import net.minecraft.entity.passive.EntityBat;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.Rotation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.World;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkPrimer;
import net.minecraft.world.chunk.IChunkGenerator;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import java.util.Random;
import static joshie.harvest.mining.MiningHelper.*;
import static joshie.harvest.mining.gen.MineManager.CHUNK_BOUNDARY;
@SuppressWarnings("synthetic-access")
public class MiningChunk implements IChunkGenerator {
private final Random rand;
private static final IBlockState WALLS = HFMining.STONE.getDefaultState();
private static final IBlockState FLOORS = HFMining.DIRT.getDefaultState();
private static final IBlockState LADDER = HFMining.LADDER.getDefaultState();
private static final IBlockState AIR = Blocks.AIR.getDefaultState();
private static final IBlockState PORTAL = HFMining.PORTAL.getDefaultState();
private static final IBlockState ORE = HFMining.ORE.getDefaultState();
private static final IBlockState LADDER_HOLE = HFMining.STONE.getStateFromEnum(Type.LADDER_HOLE);
private static final List<Biome.SpawnListEntry> MONSTERS = Lists.newArrayList();
private static final List<Block> IRREPLACABLE = Lists.newArrayList();
private static final int NUM_X_BITS = 1 + MathHelper.calculateLogBaseTwo(MathHelper.roundUpToPowerOfTwo(30000000));
private static final int NUM_Z_BITS = NUM_X_BITS;
private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS;
private static final int Y_SHIFT = 0 + NUM_Z_BITS;
private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS;
private static final long X_MASK = (1L << NUM_X_BITS) - 1L;
private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L;
private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L;
static {
MONSTERS.add(new Biome.SpawnListEntry(EntityDarkChick.class, 26, 1, 1));
MONSTERS.add(new Biome.SpawnListEntry(EntityDarkChicken.class, 25, 1, 1));
MONSTERS.add(new Biome.SpawnListEntry(EntityDarkSheep.class, 24, 1, 1));
MONSTERS.add(new Biome.SpawnListEntry(EntityDarkCow.class, 23, 1, 1));
MONSTERS.add(new Biome.SpawnListEntry(EntityBat.class, 2, 1, 1));
IRREPLACABLE.add(ORE.getBlock());
IRREPLACABLE.add(HFCore.FLOWERS);
IRREPLACABLE.add(HFMining.PORTAL);
}
private final World worldObj;
private Biome[] biomesForGeneration;
private Season season;
public MiningChunk(World world, long seed) {
this.worldObj = world;
this.rand = new Random(seed);
}
public void setBlockState(ChunkPrimer primer, int x, int y, int z, IBlockState state, int chunkX) {
x = Math.min(15, Math.max(0, x));
y = Math.min(MAX_Y, Math.max(0, y));
z = Math.min(15, Math.max(0, z));
if (state.getBlock() == PORTAL.getBlock()) {
primer.setBlockState(x, y, z, state);
} else if (state.getBlock() == ORE.getBlock()) {
if (primer.getBlockState(x, y, z).getBlock() != Blocks.LADDER && primer.getBlockState(x, y, z).getBlock() != PORTAL.getBlock()) {
primer.setBlockState(x, y, z, FLOORS);
if (primer.getBlockState(x, y + 1, z).getBlock() != Blocks.LADDER) {
IBlockState theState = MiningRegistry.INSTANCE.getRandomStateForSeason(worldObj, MiningHelper.getFloor(chunkX, y), season);
if (theState != null) {
primer.setBlockState(x, y + 1, z, theState);
}
}
}
} else {
Block block = primer.getBlockState(x, y, z).getBlock();
if ((!IRREPLACABLE.contains(block) && state == AIR) || state != AIR) {
primer.setBlockState(x, y, z, state);
}
}
}
public IBlockState getBlockState(ChunkPrimer primer, int x, int y, int z) {
x = Math.min(15, Math.max(0, x));
y = Math.min(MAX_Y, Math.max(0, y));
z = Math.min(15, Math.max(0, z));
return primer.getBlockState(x, y, z);
}
private boolean isFloorWithPortal(int floor) {
return floor % MiningHelper.MAX_FLOORS == 1 || floor % MiningHelper.MAX_FLOORS == 0;
}
private void setBlocksInChunk(int chunkX, int chunkZ, ChunkPrimer primer) {
//Set the chunk to wall blocks
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
for (int k = 0; k < MAX_Y; k++) {
setBlockState(primer, i, k, j, WALLS, chunkX);
}
}
}
if (chunkX >= 0 && chunkZ >= 0) {
boolean up = true;
int been = 0;
for (int chunkY = 0; chunkY < MAX_LOOP; chunkY += MiningHelper.FLOOR_HEIGHT) {
IBlockState[][] states = getMineGeneration(chunkX, chunkY, chunkZ);
rand.setSeed(getIndex(chunkX, chunkY, chunkZ) * worldObj.getSeed());
//Set the floor blocks
int height = rand.nextInt(3);
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
if (states[i][j] == FLOORS || states[i][j] == ORE) {
setBlockState(primer, i, chunkY, j, states[i][j], chunkX);
if (been >= 10 + rand.nextInt(16) && rand.nextInt(8) == 0) {
if (up) height++;
else height--;
if (height > 2) {
height = 2;
up = false;
} else if (height < 0) {
height = 0;
up = true;
}
been = 0;
} else been++;
for (int k = 0; k < 3; k++) {
int width = 1 + rand.nextInt(1);
int length = 1 + rand.nextInt(1);
for (int x4 = -width; x4 <= width; x4++) {
for (int z4 = -length; z4 < length; z4++) {
for (EnumFacing enumFacing: EnumFacing.HORIZONTALS) {
if (enumFacing == EnumFacing.DOWN || enumFacing == EnumFacing.UP) continue;
BlockPos pos = new BlockPos(i + x4, chunkY, j + z4);
BlockPos offset = pos.offset(enumFacing);
if (x4 != z4 && getBlockState(primer, offset.getX(), offset.getY(), offset.getZ()) == states[i][j] && rand.nextBoolean()) {
setBlockState(primer, pos.getX(), chunkY, pos.getZ(), states[i][j], chunkX);
for (int y = 1; y <= MiningHelper.FLOOR_HEIGHT - 4; y++) {
setBlockState(primer, pos.getX(), chunkY + y, pos.getZ(), AIR, chunkX);
}
break;
}
}
}
}
}
for (int y = 1; y <= MiningHelper.FLOOR_HEIGHT - 1 - height; y++) {
setBlockState(primer, i, chunkY + y, j, AIR, chunkX);
}
}
}
}
//Set the ladders, On the floor below
int belowY = chunkY - MiningHelper.FLOOR_HEIGHT;
IBlockState[][] below = chunkY == 0 ? null : getMineGeneration(chunkX, belowY, chunkZ);
if (below != null) {
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
if (below[i][j] == LADDER) {
Rotation rotation = Rotation.values()[rand.nextInt(Rotation.values().length)];
IBlockState theState = HFMining.LADDER.withRotation(LADDER, rotation);
if (getBlockState(primer, i, belowY, j).getBlock() != LADDER.getBlock() && getBlockState(primer, i, belowY, j) != LADDER_HOLE)
setBlockState(primer, i, belowY, j, FLOORS, chunkX);
for (int y = 1; y <= MiningHelper.FLOOR_HEIGHT; y++) {
setBlockState(primer, i, belowY + y, j, theState, chunkX);
setBlockState(primer, i, belowY + y + 4, j, AIR, chunkX);
}
int floor = MiningHelper.getFloor(chunkX, belowY + MiningHelper.FLOOR_HEIGHT);
if (MiningHelper.HOLE_FLOORS.contains(floor) || (floor > MYSTRIL_FLOOR && rand.nextInt(4) == 0)) {
setBlockState(primer, i, belowY + MiningHelper.FLOOR_HEIGHT, j, LADDER_HOLE, chunkX);
}
}
}
}
}
}
}
//Fix the ceiling
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
for (int k = 0; k < MAX_Y; k++) {
setBlockState(primer, i, 251, j, WALLS, chunkX);
}
}
}
//Place the Spawn Portals
for (int chunkY = 0; chunkY < MAX_LOOP; chunkY += MiningHelper.FLOOR_HEIGHT) {
int mineID = MiningHelper.getMineID(chunkZ);
int floor = MiningHelper.getFloor(chunkX, chunkY);
if (floor != 0 && isFloorWithPortal(floor) && !MineManager.areCoordinatesGenerated(worldObj, mineID, floor)) {
placePortals(primer, mineID, floor, chunkX, chunkY, chunkZ);
}
}
}
private void placePortals(ChunkPrimer primer, int mineID, int floor, int chunkX, int chunkY, int chunkZ) {
if (isFloorWithPortal(floor) && !MineManager.areCoordinatesGenerated(worldObj, mineID, floor)) {
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
if (isXLineWall(primer, x, chunkY + 1, z) && isXLineAir(primer, x, chunkY + 1, z)) {
setXSpawn(floor, primer, x, chunkY + 1, z, chunkX, chunkZ);
return;
} else if (isZLineWall(primer, x, chunkY + 1, z) && isZLineAir(primer, x, chunkY + 1, z)) {
setZSpawn(floor, primer, x, chunkY + 1, z, chunkX, chunkZ);
return;
}
}
}
}
}
private void setXSpawn(int floor, ChunkPrimer primer, int x, int y, int z, int chunkX, int chunkZ) {
int realX = (chunkX * 16) + x;
int realZ = (chunkZ * 16) + z;
setBlockState(primer, x, y, z, PORTAL, chunkX);
setBlockState(primer, x - 1, y, z, PORTAL, chunkX);
setBlockState(primer, x + 1, y, z, PORTAL, chunkX);
setBlockState(primer, x, y + 1, z, PORTAL, chunkX);
setBlockState(primer, x - 1, y + 1, z, PORTAL, chunkX);
setBlockState(primer, x + 1, y + 1, z, PORTAL, chunkX);
/** Torches
for (int r = -2; r <= 2; r++) {
for (int s = -2; s <= 2; s++) {
for (int t = 0; t <= 2; t++) {
if (getBlockState(primer, x + r, y + t, z + s).getBlock() == Blocks.TORCH) {
setBlockState(primer, x + r, y + t, z + s, AIR, chunkX);
}
}
}
} **/
HFTrackers.getMineManager(worldObj).setSpawnForMine(MiningHelper.getMineID(chunkZ), floor, realX, y, realZ);
}
private void setZSpawn(int floor, ChunkPrimer primer, int x, int y, int z, int chunkX, int chunkZ) {
int realX = (chunkX * 16) + x;
int realZ = (chunkZ * 16) + z;
setBlockState(primer, x, y, z, PORTAL, chunkX);
setBlockState(primer, x, y, z - 1, PORTAL, chunkX);
setBlockState(primer, x, y, z + 1, PORTAL, chunkX);
setBlockState(primer, x, y + 1, z, PORTAL, chunkX);
setBlockState(primer, x, y + 1, z - 1, PORTAL, chunkX);
setBlockState(primer, x, y + 1, z + 1, PORTAL, chunkX);
/** Torches
for (int r = -2; r <= 2; r++) {
for (int s = -2; s <= 2; s++) {
for (int t = 0; t <= 2; t++) {
if (getBlockState(primer, x + r, y + t, z + s).getBlock() == Blocks.TORCH) {
setBlockState(primer, x + r, y + t, z + s, AIR, chunkX);
}
}
}
} */
HFTrackers.getMineManager(worldObj).setSpawnForMine(MiningHelper.getMineID(chunkZ), floor, realX, y, realZ);
}
private boolean isXLineWall(ChunkPrimer primer, int x, int y, int z) {
return x + 1 < 16 && x - 1 >= 0 && getBlockState(primer, x, y, z) == WALLS && getBlockState(primer, x + 1, y, z) == WALLS && getBlockState(primer, x - 1, y, z) == WALLS;
}
private boolean isXLineAir(ChunkPrimer primer, int x, int y, int z) {
return (z + 1 < 16 && getBlockState(primer, x, y, z + 1) == AIR && getBlockState(primer, x + 1, y, z + 1) == AIR && getBlockState(primer, x - 1, y, z + 1) == AIR)
|| (z - 1 >= 0 && getBlockState(primer, x, y, z - 1) == AIR && getBlockState(primer, x + 1, y, z - 1) == AIR && getBlockState(primer, x - 1, y, z - 1) == AIR);
}
private boolean isZLineWall(ChunkPrimer primer, int x, int y, int z) {
return z + 1 < 16 && z - 1 >= 0 && getBlockState(primer, x, y, z) == WALLS && getBlockState(primer, x, y, z + 1) == WALLS && getBlockState(primer, x, y, z - 1) == WALLS;
}
private boolean isZLineAir(ChunkPrimer primer, int x, int y, int z) {
return (x + 1 < 16 && getBlockState(primer, x + 1, y, z) == AIR && getBlockState(primer, x + 1, y, z + 1) == AIR && getBlockState(primer, x + 1, y, z - 1) == AIR)
|| (x - 1 >= 16 && getBlockState(primer, x - 1, y, z) == AIR && getBlockState(primer, x - 1, y, z + 1) == AIR && getBlockState(primer, x - 1, y, z - 1) == AIR);
}
private int clamp(int number) {
return Math.max(0, Math.min((CHUNK_BOUNDARY * 16) - 1, number));
}
private int getChunkIndexFromCoordinates(int chunkXIndex, int chunkZIndex) {
return chunkXIndex + (chunkZIndex * CHUNK_BOUNDARY);
}
private IBlockState[][] getBooleanFromMap(TIntObjectMap<IBlockState[][]> map, int index) {
map.putIfAbsent(index, new IBlockState[16][16]);
return map.get(index);
}
private long getIndex(int chunkX, int chunkY, int chunkZ) {
int x = (int) Math.floor(chunkX / CHUNK_BOUNDARY); //3x3 Chunks
int y = (int) Math.floor(chunkY / MiningHelper.FLOOR_HEIGHT); // Height
int z = (int) Math.floor(chunkZ / CHUNK_BOUNDARY); //3x3 Chunks
return new BlockPos(x, y, z).toLong();
}
@SuppressWarnings("complexity")
@Nonnull
private IBlockState[][] getMineGeneration(int chunkX, int chunkY, int chunkZ) {
long mapIndex = getIndex(chunkX, chunkY, chunkZ);
//Put if absent
if (!MineManager.containsStateKey(mapIndex)) {
IBlockState[][] blockStateMap = new IBlockState[CHUNK_BOUNDARY * 16][CHUNK_BOUNDARY * 16];
boolean first = true;
rand.setSeed(mapIndex * worldObj.getSeed());
int startX = 15 + rand.nextInt(75);
int endX = 15 + rand.nextInt(75);
int startZ = 15 + rand.nextInt(75);
int endZ = 15 + rand.nextInt(75);
int ladderDistance = 5 + rand.nextInt(20);
int differenceMin = 5 + rand.nextInt(15);
int endDistance = (differenceMin * 3) - 1;
int maxLoop = 1 + rand.nextInt(5);
int endChangeChanceX = 10 + rand.nextInt(15);
int endChangeChanceZ = 10 + rand.nextInt(15);
int changeMinX = 10 + rand.nextInt(25);
int changeMinZ = 10 + rand.nextInt(25);
int randXChange = 5 + rand.nextInt(30);
int randZChange = 5 + rand.nextInt(30);
int randXTime = 7 + rand.nextInt(10);
int randZTime = 7 + rand.nextInt(10);
int radius = 1 + rand.nextInt(3);
int oreChance = MiningHelper.getOreChance(season, MiningHelper.getFloor(chunkX, chunkY), rand);
for (int k = 0; k < maxLoop; k++) {
if (first) {
first = false;
} else {
startX = endX;
startZ = endZ;
}
int differenceX = startX > endX ? startX - endX : endX - startX;
int differenceZ = startZ > endZ ? startZ - endZ : endZ - startZ;
while (endX == endZ || differenceX < differenceMin || differenceZ < differenceMin) {
endX = rand.nextInt(endDistance);
endZ = rand.nextInt(endDistance);
differenceX = startX > endX ? startX - endX : endX - startX;
differenceZ = startZ > endZ ? startZ - endZ : endZ - startZ;
}
if (chunkY != 0 && MineManager.containsCoordinatesKey(getIndex(chunkX, chunkY - MiningHelper.FLOOR_HEIGHT, chunkZ))) {
long below = getIndex(chunkX, chunkY - MiningHelper.FLOOR_HEIGHT, chunkZ);
startX = MineManager.getCoordinates(below, 0);
startZ = MineManager.getCoordinates(below, 1);
}
if (!(startX == -1 || endX == -1 || startZ == -1 || endZ == -1)) {
//Fill in the starting position with a true boolean
blockStateMap[startX][startZ] = FLOORS; //Mark as floor
//Mark a random circle radius around
for (int i = -radius; i <= radius; i++) {
for (int l = -radius; l <= radius; l++) {
if (i * i + l * l >= (radius + 0.50f) * (radius + 0.50f)) {
continue;
}
int x = startX + i;
int z = startZ + l;
int x2 = clamp(x);
int z2 = clamp(z);
IBlockState state = rand.nextInt(oreChance) == 0 ? ORE: FLOORS;
blockStateMap[x2][z2] = state; //Force it in
}
}
int x = startX;
int z = startZ;
//Let's try this 20 times
int sameXTime = 0;
int sameZTime = 0;
while (x != endX || z != endZ) {
int option = rand.nextInt(4);
if (option == 0) {
if (x < endX) x++;
} else if (option == 1) {
if (x > endX) x--;
} else if (option == 2) {
if (z < endZ) z++;
} else if (option == 3) {
if (z > endZ) z--;
}
if (blockStateMap[clamp(x)][clamp(z)] != LADDER) {
IBlockState state = rand.nextInt(oreChance) == 0 ? ORE: FLOORS;
blockStateMap[clamp(x)][clamp(z)] = state; //Force it in
}
option = rand.nextInt(16);
if (option == 0) {
if (x > endX) x++;
} else if (option == 1) {
if (x < endX) x--;
} else if (option == 2) {
if (z > endZ) z++;
} else if (option == 3) {
if (z < endZ) z--;
}
if (blockStateMap[clamp(x)][clamp(z)] != LADDER) {
IBlockState state = rand.nextInt(oreChance) == 0 ? ORE: FLOORS;
blockStateMap[clamp(x)][clamp(z)] = state; //Force it in
}
boolean regenEndX = false;
boolean regenEndZ = false;
if (x == endX) {
sameXTime++;
if (sameXTime >= randXTime) {
sameXTime = 0;
regenEndX = true;
}
}
if (z == endZ) {
sameZTime++;
if (sameZTime >= randZTime) {
sameZTime = 0;
regenEndZ = true;
}
}
if (regenEndX || rand.nextInt(endChangeChanceX) == 0) {
endX = changeMinX + rand.nextInt(randXChange);
}
if (regenEndZ || rand.nextInt(endChangeChanceZ) == 0) {
endZ = changeMinZ + rand.nextInt(randZChange);
}
int x2 = clamp(x);
int z2 = clamp(z);
for (EnumFacing enumfacing : EnumFacing.values()) {
if (enumfacing == EnumFacing.DOWN || enumfacing == EnumFacing.UP) continue;
BlockPos pos = new BlockPos(x, chunkY, z).offset(enumfacing);
int x3 = clamp(pos.getX());
int z3 = clamp(pos.getZ());
if (pos.getX() < 0 || pos.getX() >= blockStateMap.length) continue;
if (pos.getZ() < 0 || pos.getZ() >= blockStateMap[pos.getX()].length) continue;
if (blockStateMap[x3][z3] == FLOORS || blockStateMap[x3][z3] == ORE) {
int wStart = rand.nextInt(2);
int wEnd = rand.nextInt(2);
int lStart = rand.nextInt(2);
int lEnd = rand.nextInt(2);
for (int x4 = -wStart; x4 <= wEnd; x4++) {
for (int z4 = -lStart; z4 <= lEnd; z4++) {
if (x4 != z4 && blockStateMap[clamp(x2 + x4)][clamp(z2 + z4)] != LADDER) {
IBlockState state = rand.nextInt(oreChance) == 0 ? ORE: FLOORS;
blockStateMap[clamp(x2 + x4)][clamp(z2 + z4)] = state;
differenceX = startX > x ? startX - x : x - startX;
differenceZ = startZ > z ? startZ - z : z - startZ;
if ((differenceX >= ladderDistance || differenceZ >= ladderDistance) && !MineManager.containsCoordinatesKey(mapIndex)) {
int clampedX = clamp(x2 + x4);
int clampedZ = clamp(z2 + z4);
blockStateMap[clampedX][clampedZ] = LADDER;
for (int x5 = -1; x5 <= 1; x5++) {
for (int z5 = -1; z5<= 1; z5++) {
int clampedX5 = clamp(clampedX + x5);
int clampedZ5 = clamp(clampedZ + z5);
if (blockStateMap[clampedX5][clampedZ5] != LADDER) {
blockStateMap[clampedX5][clampedZ5] = FLOORS;
}
}
}
MineManager.putCoordinates(mapIndex, new int[]{ clampedX, clampedZ });
}
}
}
}
break;
}
}
}
if (!MineManager.containsCoordinatesKey(mapIndex) && k == maxLoop - 1) {
blockStateMap[startX][startZ] = LADDER;
MineManager.putCoordinates(mapIndex, new int[]{ startX, startZ });
}
}
}
//Convert the full map to individual maps
TIntObjectMap<IBlockState[][]> stateMap = new TIntObjectHashMap<>();
for (int cX = 0; cX < blockStateMap.length; cX++) {
for (int cZ = 0; cZ < blockStateMap[cX].length; cZ++) {
int chunkIndexX = (int) Math.floor(cX / 16);
int chunkIndexZ = (int) Math.floor(cZ / 16);
int chunkIndex = getChunkIndexFromCoordinates(chunkIndexX, chunkIndexZ);
IBlockState[][] air = getBooleanFromMap(stateMap, chunkIndex);
air[cX % 16][cZ % 16] = blockStateMap[cX][cZ];
stateMap.put(chunkIndex, air);
}
}
MineManager.putStateMap(mapIndex, stateMap);
}
TIntObjectMap<IBlockState[][]> map = MineManager.getStateMap(mapIndex);
int chunkXIndex = chunkX % CHUNK_BOUNDARY;
int chunkZIndex = chunkZ % CHUNK_BOUNDARY;
int checkIndex = getChunkIndexFromCoordinates(chunkXIndex, chunkZIndex);
return map.get(checkIndex);
}
@Override
@Nonnull
public Chunk provideChunk(int x, int z) {
rand.setSeed((long) x * 341873128712L + (long) z * 132897987541L);
ChunkPrimer chunkprimer = new ChunkPrimer();
biomesForGeneration = this.worldObj.getBiomeProvider().getBiomes(biomesForGeneration, x * 16, z * 16, 16, 16);
season = HFApi.calendar.getDate(worldObj).getSeason();
if (season == null) season = Season.SPRING;
setBlocksInChunk(x, z, chunkprimer);
Chunk chunk = new Chunk(worldObj, chunkprimer, x, z);
byte[] abyte = chunk.getBiomeArray();
for (int i = 0; i < abyte.length; ++i) {
abyte[i] = (byte) Biome.getIdForBiome(biomesForGeneration[i]);
}
chunk.generateSkylightMap();
return chunk;
}
@Override
public void populate(int x, int z) {}
@Override
public boolean generateStructures(@Nonnull Chunk chunkIn, int x, int z) {
return true;
}
@Override
@Nonnull
public List<Biome.SpawnListEntry> getPossibleCreatures(@Nonnull EnumCreatureType creatureType, @Nonnull BlockPos pos) {
if (creatureType == EnumCreatureType.MONSTER) {
return MONSTERS;
} else return this.worldObj.getBiome(pos).getSpawnableList(creatureType);
}
@Nullable
public BlockPos getStrongholdGen(@Nonnull World worldIn, @Nonnull String structureName, @Nonnull BlockPos position) {
return null;
}
@Override
public void recreateStructures(@Nonnull Chunk chunkIn, int x, int z) {}
}