package rtg.world.gen.structure;
import java.util.*;
import java.util.Map.Entry;
import net.minecraft.entity.monster.EntityWitch;
import net.minecraft.init.Biomes;
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.gen.structure.ComponentScatteredFeaturePieces;
import net.minecraft.world.gen.structure.MapGenScatteredFeature;
import net.minecraft.world.gen.structure.StructureComponent;
import net.minecraft.world.gen.structure.StructureStart;
import net.minecraftforge.common.BiomeDictionary;
import com.google.common.collect.Lists;
import rtg.api.RTGAPI;
import rtg.util.Logger;
/**
* Author: Choonster (https://github.com/Choonster)
* Source: https://github.com/Choonster/TestMod2/blob/1575b85ad8949381215f3aeb6ca76ea2368074de/src/main/java/com/choonster/testmod2/world/gen/structure/MapGenScatteredFeatureModBiomes.java
* Modified by: WhichOnesPink (https://github.com/whichonespink44)
* <p>
* Allows scattered features (jungle/desert temples, witch huts) to spawn in modded biomes, equivalent to the vanilla biomes,
* i.e. any biome registered as JUNGLE, SANDY or SWAMP
* http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/modification-development/2471489-jungle-and-desert-temple-spawn-biome
* <p>
* This class was modified by WhichOnesPink on 2015-11-05 to allow the spawning of scattered features ONLY
* in biomes that have been registered with multiple BiomeDictionary types that are shared by their vanilla counterparts.
* For example, desert temples don't generate in SANDY biomes - they are only allowed to generate in biomes that
* have been registered as HOT + DRY + SANDY.
* <p>
* This class has also been modified to resolve a very specific use case involving Thaumcraft world gen:
* https://github.com/Team-RTG/Realistic-Terrain-Generation/issues/249
*/
public class MapGenScatteredFeatureRTG extends MapGenScatteredFeature
{
private static final List<Biome> BIOMELIST = Arrays.<Biome>asList(new Biome[] {Biomes.DESERT, Biomes.DESERT_HILLS, Biomes.JUNGLE, Biomes.JUNGLE_HILLS, Biomes.SWAMPLAND, Biomes.ICE_PLAINS, Biomes.COLD_TAIGA});
private final List<Biome.SpawnListEntry> scatteredFeatureSpawnList;
private int maxDistanceBetweenScatteredFeatures;
private final int minDistanceBetweenScatteredFeatures;
public MapGenScatteredFeatureRTG()
{
int minDistance = RTGAPI.config().MIN_DISTANCE_SCATTERED_FEATURES.get();
int maxDistance = RTGAPI.config().MAX_DISTANCE_SCATTERED_FEATURES.get();
if (minDistance > maxDistance) {
minDistance = 8;
maxDistance = 32;
}
this.scatteredFeatureSpawnList = Lists.<Biome.SpawnListEntry>newArrayList();
this.maxDistanceBetweenScatteredFeatures = maxDistance;
this.minDistanceBetweenScatteredFeatures = minDistance;
this.scatteredFeatureSpawnList.add(new Biome.SpawnListEntry(EntityWitch.class, 1, 1, 1));
}
public MapGenScatteredFeatureRTG(Map<String, String> p_i2061_1_)
{
this();
for (Entry<String, String> entry : p_i2061_1_.entrySet())
{
if (((String)entry.getKey()).equals("distance"))
{
this.maxDistanceBetweenScatteredFeatures = MathHelper.getInt((String)entry.getValue(), this.maxDistanceBetweenScatteredFeatures, 9);
}
}
}
@Override
public String getStructureName()
{
return "Temple";
}
@Override
protected boolean canSpawnStructureAtCoords(int chunkX, int chunkZ)
{
int i = chunkX;
int j = chunkZ;
if (chunkX < 0)
{
chunkX -= this.maxDistanceBetweenScatteredFeatures - 1;
}
if (chunkZ < 0)
{
chunkZ -= this.maxDistanceBetweenScatteredFeatures - 1;
}
int k = chunkX / this.maxDistanceBetweenScatteredFeatures;
int l = chunkZ / this.maxDistanceBetweenScatteredFeatures;
Random random = this.world.setRandomSeed(k, l, 14357617);
k *= this.maxDistanceBetweenScatteredFeatures;
l *= this.maxDistanceBetweenScatteredFeatures;
k += random.nextInt(this.maxDistanceBetweenScatteredFeatures - this.minDistanceBetweenScatteredFeatures);
l += random.nextInt(this.maxDistanceBetweenScatteredFeatures - this.minDistanceBetweenScatteredFeatures);
if (i == k && j == l)
{
BlockPos pos = new BlockPos(i * 16 + 8, 0, j * 16 + 8);
Biome biome = this.world.getBiomeProvider().getBiome(pos);
if (null == biome) {
Logger.error("MapGenScatteredFeatureRTG#canSpawnStructureAtCoords received a null biome at %d %d.", pos.getX(), pos.getZ());
return false;
}
//Desert temple.
if (canSpawnDesertTemple(biome)) {
return true;
}
//Jungle temple.
if (canSpawnJungleTemple(biome)) {
return true;
}
//Witch hut.
if (canSpawnWitchHut(biome)) {
return true;
}
//Igloo.
if (canSpawnIgloo(biome)) {
return true;
}
}
return false;
}
@Override
public BlockPos getClosestStrongholdPos(World worldIn, BlockPos pos, boolean findUnexplored)
{
this.world = worldIn;
return findNearestStructurePosBySpacing(worldIn, this, pos, this.maxDistanceBetweenScatteredFeatures, 8, 14357617, false, 100, findUnexplored);
}
@Override
protected StructureStart getStructureStart(int chunkX, int chunkZ)
{
return new MapGenScatteredFeatureRTG.Start(this.world, this.rand, chunkX, chunkZ);
}
@Override
public boolean isSwampHut(BlockPos p_175798_1_)
{
StructureStart structurestart = this.getStructureAt(p_175798_1_);
if (structurestart != null && structurestart instanceof MapGenScatteredFeatureRTG.Start && !structurestart.getComponents().isEmpty())
{
StructureComponent structurecomponent = (StructureComponent)structurestart.getComponents().get(0);
return structurecomponent instanceof ComponentScatteredFeaturePieces.SwampHut;
}
else
{
return false;
}
}
@Override
public List<Biome.SpawnListEntry> getScatteredFeatureSpawnList()
{
return this.scatteredFeatureSpawnList;
}
public static class Start extends StructureStart
{
public Start()
{
}
public Start(World worldIn, Random random, int chunkX, int chunkZ)
{
this(worldIn, random, chunkX, chunkZ, worldIn.getBiome(new BlockPos(chunkX * 16 + 8, 0, chunkZ * 16 + 8)));
}
public Start(World worldIn, Random random, int chunkX, int chunkZ, Biome biomeIn)
{
super(chunkX, chunkZ);
if (null == biomeIn) {
Logger.error("MapGenScatteredFeatureRTG.Start received a null biome at %d %d.", chunkX * 16 + 8, chunkZ * 16 + 8);
return;
}
LinkedList arrComponents = new LinkedList();
if (canSpawnDesertTemple(biomeIn)) {
ComponentScatteredFeaturePieces.DesertPyramid desertpyramid = new ComponentScatteredFeaturePieces.DesertPyramid(random, chunkX * 16, chunkZ * 16);
arrComponents.add(desertpyramid);
}
if (canSpawnJungleTemple(biomeIn)) {
ComponentScatteredFeaturePieces.JunglePyramid junglepyramid = new ComponentScatteredFeaturePieces.JunglePyramid(random, chunkX * 16, chunkZ * 16);
arrComponents.add(junglepyramid);
}
if (canSpawnWitchHut(biomeIn)) {
ComponentScatteredFeaturePieces.SwampHut swamphut = new ComponentScatteredFeaturePieces.SwampHut(random, chunkX * 16, chunkZ * 16);
arrComponents.add(swamphut);
}
if (canSpawnIgloo(biomeIn)) {
ComponentScatteredFeaturePieces.Igloo igloo = new ComponentScatteredFeaturePieces.Igloo(random, chunkX * 16, chunkZ * 16);
arrComponents.add(igloo);
}
this.components.clear();
if (arrComponents.size() > 0) {
this.components.add((StructureComponent) arrComponents.get(random.nextInt(arrComponents.size())));
}
Logger.debug("Scattered feature candidate at %d, %d", chunkX * 16, chunkZ * 16);
this.updateBoundingBox();
}
}
private static boolean canSpawnDesertTemple(Biome b) {
return (BiomeDictionary.hasType(b, BiomeDictionary.Type.HOT) && BiomeDictionary.hasType(b, BiomeDictionary.Type.DRY) && BiomeDictionary.hasType(b, BiomeDictionary.Type.SANDY));
}
private static boolean canSpawnJungleTemple(Biome b) {
return (BiomeDictionary.hasType(b, BiomeDictionary.Type.HOT) && BiomeDictionary.hasType(b, BiomeDictionary.Type.WET) && BiomeDictionary.hasType(b, BiomeDictionary.Type.JUNGLE));
}
private static boolean canSpawnWitchHut(Biome b) {
return (BiomeDictionary.hasType(b, BiomeDictionary.Type.WET) && BiomeDictionary.hasType(b, BiomeDictionary.Type.SWAMP));
}
private static boolean canSpawnIgloo(Biome b) {
return (BiomeDictionary.hasType(b, BiomeDictionary.Type.COLD) && BiomeDictionary.hasType(b, BiomeDictionary.Type.SNOWY) && BiomeDictionary.hasType(b, BiomeDictionary.Type.PLAINS));
}
}