package choonster.testmod3.world.gen.structure; import choonster.testmod3.Logger; import com.google.common.collect.ImmutableList; import net.minecraft.util.WeightedRandom; import net.minecraft.util.math.BlockPos; 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 java.util.ArrayList; import java.util.List; import java.util.Random; /** * Allows scattered features (jungle/desert temples, witch huts) to spawn in mod biomes equivalent to the vanilla biomes, * i.e. any biome registered as JUNGLE, SANDY or SWAMP * <p> * http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/modification-development/2471489-jungle-and-desert-temple-spawn-biome * * @author Choonster */ public class MapGenScatteredFeatureModBiomes extends MapGenScatteredFeature { private final List<BiomeDictionary.Type> biomeTypes = ImmutableList.of(BiomeDictionary.Type.JUNGLE, BiomeDictionary.Type.SANDY, BiomeDictionary.Type.SWAMP); @Override protected boolean canSpawnStructureAtCoords(int chunkX, int chunkZ) { // These fields are private in the super class and always constant for non-flat worlds so inline them here // Flat worlds don't fire InitMapGenEvent, so this class will never be used in a flat world final int minDistanceBetweenScatteredFeatures = 8; final int maxDistanceBetweenScatteredFeatures = 32; if (chunkX < 0) { chunkX -= maxDistanceBetweenScatteredFeatures - 1; } if (chunkZ < 0) { chunkZ -= maxDistanceBetweenScatteredFeatures - 1; } int i1 = chunkX / maxDistanceBetweenScatteredFeatures; int j1 = chunkZ / maxDistanceBetweenScatteredFeatures; final Random random = world.setRandomSeed(i1, j1, 14357617); i1 *= maxDistanceBetweenScatteredFeatures; j1 *= maxDistanceBetweenScatteredFeatures; i1 += random.nextInt(maxDistanceBetweenScatteredFeatures - minDistanceBetweenScatteredFeatures); j1 += random.nextInt(maxDistanceBetweenScatteredFeatures - minDistanceBetweenScatteredFeatures); if (chunkX == i1 && chunkZ == j1) { final Biome biome = world.getBiomeProvider().getBiome(new BlockPos(chunkX * 16 + 8, 0, chunkZ * 16 + 8)); for (final BiomeDictionary.Type type : biomeTypes) { if (BiomeDictionary.hasType(biome, type)) { return true; } } } return super.canSpawnStructureAtCoords(chunkX, chunkZ); } @Override protected StructureStart getStructureStart(int chunkX, int chunkZ) { return new Start(world, rand, chunkX, chunkZ); } public static class WeightedRandomScatteredFeature extends WeightedRandom.Item { public final StructureComponent feature; public WeightedRandomScatteredFeature(StructureComponent feature, int itemWeightIn) { super(itemWeightIn); this.feature = feature; } } public static class Start extends MapGenScatteredFeature.Start { @SuppressWarnings("unused") public Start() { } public Start(World worldIn, Random random, int chunkX, int chunkZ) { super(worldIn, random, chunkX, chunkZ); this.components.clear(); final Biome biome = worldIn.getBiome(new BlockPos(chunkX * 16 + 8, 0, chunkZ * 16 + 8)); final List<WeightedRandomScatteredFeature> possibleFeatures = new ArrayList<>(); if (BiomeDictionary.hasType(biome, BiomeDictionary.Type.SANDY)) { final ComponentScatteredFeaturePieces.DesertPyramid desertPyramid = new ComponentScatteredFeaturePieces.DesertPyramid(random, chunkX * 16, chunkZ * 16); possibleFeatures.add(new WeightedRandomScatteredFeature(desertPyramid, 100)); } if (BiomeDictionary.hasType(biome, BiomeDictionary.Type.JUNGLE)) { final ComponentScatteredFeaturePieces.JunglePyramid junglePyramid = new ComponentScatteredFeaturePieces.JunglePyramid(random, chunkX * 16, chunkZ * 16); possibleFeatures.add(new WeightedRandomScatteredFeature(junglePyramid, 100)); } if (BiomeDictionary.hasType(biome, BiomeDictionary.Type.SWAMP)) { final ComponentScatteredFeaturePieces.SwampHut swampHut = new ComponentScatteredFeaturePieces.SwampHut(random, chunkX * 16, chunkZ * 16); possibleFeatures.add(new WeightedRandomScatteredFeature(swampHut, 100)); } if (!possibleFeatures.isEmpty()) { final WeightedRandomScatteredFeature featureToGenerate = WeightedRandom.getRandomItem(random, possibleFeatures); this.components.add(featureToGenerate.feature); Logger.info("Scattered feature %s at %d, %d", featureToGenerate.feature.toString(), chunkX * 16, chunkZ * 16); } this.updateBoundingBox(); } } }