From 5fe2002a557dcb758b4a0a1a6df237253490d7f2 Mon Sep 17 00:00:00 2001 From: Forstride Date: Wed, 5 Jun 2019 23:04:26 -0400 Subject: [PATCH] Started experimenting with End biomes (Not currently available yet) --- .../biomesoplenty/api/biome/BOPBiomes.java | 1 + .../common/biome/EndBiomeBOP.java | 31 +++ .../common/biome/end/SpectralGardenBiome.java | 28 +++ .../common/block/BlockFoliageBOP.java | 4 + .../common/world/BOPEndBiomeProvider.java | 182 ++++++++++++++++++ .../common/world/WorldTypeBOP.java | 20 ++ .../java/biomesoplenty/init/ModBiomes.java | 3 + 7 files changed, 269 insertions(+) create mode 100644 src/main/java/biomesoplenty/common/biome/EndBiomeBOP.java create mode 100644 src/main/java/biomesoplenty/common/biome/end/SpectralGardenBiome.java create mode 100644 src/main/java/biomesoplenty/common/world/BOPEndBiomeProvider.java diff --git a/src/main/java/biomesoplenty/api/biome/BOPBiomes.java b/src/main/java/biomesoplenty/api/biome/BOPBiomes.java index 84f8ff465..f1f6bd376 100644 --- a/src/main/java/biomesoplenty/api/biome/BOPBiomes.java +++ b/src/main/java/biomesoplenty/api/biome/BOPBiomes.java @@ -60,6 +60,7 @@ public class BOPBiomes public static Optional silkglade = Optional.empty(); public static Optional snowy_coniferous_forest = Optional.empty(); public static Optional snowy_forest = Optional.empty(); + public static Optional spectral_garden = Optional.empty(); public static Optional steppe = Optional.empty(); public static Optional temperate_rainforest = Optional.empty(); public static Optional tropical_rainforest = Optional.empty(); diff --git a/src/main/java/biomesoplenty/common/biome/EndBiomeBOP.java b/src/main/java/biomesoplenty/common/biome/EndBiomeBOP.java new file mode 100644 index 000000000..1abb850ea --- /dev/null +++ b/src/main/java/biomesoplenty/common/biome/EndBiomeBOP.java @@ -0,0 +1,31 @@ +/******************************************************************************* + * Copyright 2014-2019, the Biomes O' Plenty Team + * + * This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License. + * + * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/. + ******************************************************************************/ +package biomesoplenty.common.biome; + +import biomesoplenty.api.enums.BOPClimates; +import net.minecraft.init.Biomes; +import net.minecraft.util.registry.IRegistry; +import net.minecraft.world.biome.Biome; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class EndBiomeBOP extends BiomeBOP +{ + protected Map weightMap = new HashMap(); + public boolean canSpawnInBiome; + public int beachBiomeId = -1; + public int riverBiomeId = -1; + + public EndBiomeBOP(BiomeBuilder builder) + { + super(builder); + this.canSpawnInBiome = false; + } +} diff --git a/src/main/java/biomesoplenty/common/biome/end/SpectralGardenBiome.java b/src/main/java/biomesoplenty/common/biome/end/SpectralGardenBiome.java new file mode 100644 index 000000000..842a0d0bb --- /dev/null +++ b/src/main/java/biomesoplenty/common/biome/end/SpectralGardenBiome.java @@ -0,0 +1,28 @@ +package biomesoplenty.common.biome.end; + +import biomesoplenty.api.block.BOPBlocks; +import biomesoplenty.common.biome.EndBiomeBOP; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.EnumCreatureType; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.gen.GenerationStage; +import net.minecraft.world.gen.feature.BushConfig; +import net.minecraft.world.gen.feature.Feature; +import net.minecraft.world.gen.feature.structure.EndCityConfig; +import net.minecraft.world.gen.placement.FrequencyConfig; +import net.minecraft.world.gen.placement.IPlacementConfig; +import net.minecraft.world.gen.surfacebuilders.CompositeSurfaceBuilder; + +public class SpectralGardenBiome extends EndBiomeBOP +{ + public SpectralGardenBiome() + { + super((new Biome.BiomeBuilder()).surfaceBuilder(new CompositeSurfaceBuilder<>(DEFAULT_SURFACE_BUILDER, END_STONE_SURFACE)).precipitation(Biome.RainType.NONE).category(Biome.Category.THEEND).depth(0.1F).scale(0.2F).temperature(0.5F).downfall(0.5F).waterColor(4159204).waterFogColor(329011).parent((String)null)); + + this.addFeature(GenerationStage.Decoration.SURFACE_STRUCTURES, createCompositeFeature(Feature.END_CITY, new EndCityConfig(), PASSTHROUGH, IPlacementConfig.NO_PLACEMENT_CONFIG)); + + this.addFeature(GenerationStage.Decoration.VEGETAL_DECORATION, createCompositeFeature(Feature.BUSH, new BushConfig(BOPBlocks.spectral_fern), TWICE_SURFACE, new FrequencyConfig(25))); + + this.addSpawn(EnumCreatureType.MONSTER, new Biome.SpawnListEntry(EntityType.ENDERMAN, 10, 4, 4)); + } +} diff --git a/src/main/java/biomesoplenty/common/block/BlockFoliageBOP.java b/src/main/java/biomesoplenty/common/block/BlockFoliageBOP.java index b288c242b..533b23a24 100644 --- a/src/main/java/biomesoplenty/common/block/BlockFoliageBOP.java +++ b/src/main/java/biomesoplenty/common/block/BlockFoliageBOP.java @@ -106,6 +106,10 @@ public class BlockFoliageBOP extends BlockBush implements IPlantable { Block ground = worldIn.getBlockState(pos.down()).getBlock(); + if (this == BOPBlocks.spectral_fern) + { + return ground == Blocks.END_STONE; + } if (this == BOPBlocks.dune_grass) { return ground == Blocks.SAND || ground == Blocks.RED_SAND || ground == BOPBlocks.white_sand; diff --git a/src/main/java/biomesoplenty/common/world/BOPEndBiomeProvider.java b/src/main/java/biomesoplenty/common/world/BOPEndBiomeProvider.java new file mode 100644 index 000000000..02a6a7474 --- /dev/null +++ b/src/main/java/biomesoplenty/common/world/BOPEndBiomeProvider.java @@ -0,0 +1,182 @@ +package biomesoplenty.common.world; + +import java.util.List; +import java.util.Random; +import java.util.Set; + +import javax.annotation.Nullable; + +import com.google.common.collect.Sets; + +import biomesoplenty.api.biome.BOPBiomes; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Biomes; +import net.minecraft.util.SharedSeedRandom; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.provider.BiomeProvider; +import net.minecraft.world.biome.provider.EndBiomeProviderSettings; +import net.minecraft.world.gen.NoiseGeneratorSimplex; +import net.minecraft.world.gen.feature.structure.Structure; + +public class BOPEndBiomeProvider extends BiomeProvider { + private final NoiseGeneratorSimplex field_201546_a; + private final SharedSeedRandom random; + private final Biome[] field_205009_d = new Biome[]{Biomes.THE_END, Biomes.END_HIGHLANDS, Biomes.END_MIDLANDS, Biomes.SMALL_END_ISLANDS, Biomes.END_BARRENS, BOPBiomes.spectral_garden.get()}; + + public BOPEndBiomeProvider(EndBiomeProviderSettings p_i48970_1_) { + this.random = new SharedSeedRandom(p_i48970_1_.getSeed()); + this.random.skip(17292); + this.field_201546_a = new NoiseGeneratorSimplex(this.random); + } + + @Nullable + public Biome getBiome(BlockPos pos, @Nullable Biome defaultBiome) { + return this.func_201545_a(pos.getX() >> 4, pos.getZ() >> 4); + } + + private Biome func_201545_a(int p_201545_1_, int p_201545_2_) { + if ((long)p_201545_1_ * (long)p_201545_1_ + (long)p_201545_2_ * (long)p_201545_2_ <= 4096L) + { + return Biomes.THE_END; + } + else + { + float f = this.getHeightValue(p_201545_1_, p_201545_2_, 1, 1); + double d0 = Biome.INFO_NOISE.getValue((double)p_201545_1_ * 0.005D, (double)p_201545_2_ * 0.005D); + + if (f > 40.0F) + { + if (d0 > 0.01D) + { + return Biomes.END_HIGHLANDS; + } + else + { + return BOPBiomes.spectral_garden.get(); + } + } + else if (f >= 0.0F) + { + return Biomes.END_MIDLANDS; + } + else + { + return f < -20.0F ? Biomes.SMALL_END_ISLANDS : Biomes.END_BARRENS; + } + } + } + + public Biome[] getBiomes(int startX, int startZ, int xSize, int zSize) { + return this.getBiomeBlock(startX, startZ, xSize, zSize); + } + + public Biome[] getBiomes(int x, int z, int width, int length, boolean cacheFlag) { + Biome[] abiome = new Biome[width * length]; + Long2ObjectMap long2objectmap = new Long2ObjectOpenHashMap<>(); + + for(int i = 0; i < width; ++i) { + for(int j = 0; j < length; ++j) { + int k = i + x >> 4; + int l = j + z >> 4; + long i1 = ChunkPos.asLong(k, l); + Biome biome = long2objectmap.get(i1); + if (biome == null) { + biome = this.func_201545_a(k, l); + long2objectmap.put(i1, biome); + } + + abiome[i + j * width] = biome; + } + } + + return abiome; + } + + public Set getBiomesInSquare(int centerX, int centerZ, int sideLength) { + int i = centerX - sideLength >> 2; + int j = centerZ - sideLength >> 2; + int k = centerX + sideLength >> 2; + int l = centerZ + sideLength >> 2; + int i1 = k - i + 1; + int j1 = l - j + 1; + return Sets.newHashSet(this.getBiomeBlock(i, j, i1, j1)); + } + + @Nullable + public BlockPos findBiomePosition(int x, int z, int range, List biomes, Random random) { + int i = x - range >> 2; + int j = z - range >> 2; + int k = x + range >> 2; + int l = z + range >> 2; + int i1 = k - i + 1; + int j1 = l - j + 1; + Biome[] abiome = this.getBiomeBlock(i, j, i1, j1); + BlockPos blockpos = null; + int k1 = 0; + + for(int l1 = 0; l1 < i1 * j1; ++l1) { + int i2 = i + l1 % i1 << 2; + int j2 = j + l1 / i1 << 2; + if (biomes.contains(abiome[l1])) { + if (blockpos == null || random.nextInt(k1 + 1) == 0) { + blockpos = new BlockPos(i2, 0, j2); + } + + ++k1; + } + } + + return blockpos; + } + + public float getHeightValue(int p_201536_1_, int p_201536_2_, int p_201536_3_, int p_201536_4_) { + float f = (float)(p_201536_1_ * 2 + p_201536_3_); + float f1 = (float)(p_201536_2_ * 2 + p_201536_4_); + float f2 = 100.0F - MathHelper.sqrt(f * f + f1 * f1) * 8.0F; + f2 = MathHelper.clamp(f2, -100.0F, 80.0F); + + for(int i = -12; i <= 12; ++i) { + for(int j = -12; j <= 12; ++j) { + long k = (long)(p_201536_1_ + i); + long l = (long)(p_201536_2_ + j); + if (k * k + l * l > 4096L && this.field_201546_a.getValue((double)k, (double)l) < (double)-0.9F) { + float f3 = (MathHelper.abs((float)k) * 3439.0F + MathHelper.abs((float)l) * 147.0F) % 13.0F + 9.0F; + f = (float)(p_201536_3_ - i * 2); + f1 = (float)(p_201536_4_ - j * 2); + float f4 = 100.0F - MathHelper.sqrt(f * f + f1 * f1) * f3; + f4 = MathHelper.clamp(f4, -100.0F, 80.0F); + f2 = Math.max(f2, f4); + } + } + } + + return f2; + } + + public boolean hasStructure(Structure structureIn) { + return this.hasStructureCache.computeIfAbsent(structureIn, (p_205008_1_) -> { + for(Biome biome : this.field_205009_d) { + if (biome.hasStructure(p_205008_1_)) { + return true; + } + } + + return false; + }); + } + + public Set getSurfaceBlocks() { + if (this.topBlocksCache.isEmpty()) { + for(Biome biome : this.field_205009_d) { + this.topBlocksCache.add(biome.getSurfaceBuilderConfig().getTop()); + } + } + + return this.topBlocksCache; + } + } \ No newline at end of file diff --git a/src/main/java/biomesoplenty/common/world/WorldTypeBOP.java b/src/main/java/biomesoplenty/common/world/WorldTypeBOP.java index 8b32e0472..1f31550c7 100644 --- a/src/main/java/biomesoplenty/common/world/WorldTypeBOP.java +++ b/src/main/java/biomesoplenty/common/world/WorldTypeBOP.java @@ -7,10 +7,18 @@ ******************************************************************************/ package biomesoplenty.common.world; +import net.minecraft.init.Blocks; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import net.minecraft.world.WorldType; +import net.minecraft.world.biome.provider.BiomeProviderType; +import net.minecraft.world.biome.provider.EndBiomeProvider; +import net.minecraft.world.biome.provider.EndBiomeProviderSettings; import net.minecraft.world.biome.provider.OverworldBiomeProviderSettings; import net.minecraft.world.dimension.DimensionType; +import net.minecraft.world.dimension.EndDimension; +import net.minecraft.world.gen.ChunkGeneratorType; +import net.minecraft.world.gen.EndGenSettings; import net.minecraft.world.gen.IChunkGenerator; import net.minecraft.world.gen.OverworldGenSettings; @@ -34,6 +42,18 @@ public class WorldTypeBOP extends WorldType return new ChunkGeneratorOverworldBOP(world, new BOPBiomeProvider(biomeProviderSettings), overworldGenSettings); } + /*else if (world.getDimension().getType() == DimensionType.THE_END) + { + BlockPos SPAWN = new BlockPos(100, 50, 0); + + EndGenSettings endgensettings = ChunkGeneratorType.FLOATING_ISLANDS.createSettings(); + EndBiomeProviderSettings endBiomeProviderSettings = new EndBiomeProviderSettings(); + endBiomeProviderSettings.setSeed(world.getSeed()); + endgensettings.setDefautBlock(Blocks.END_STONE.getDefaultState()); + endgensettings.setDefaultFluid(Blocks.AIR.getDefaultState()); + endgensettings.setSpawnPos(SPAWN); + return ChunkGeneratorType.FLOATING_ISLANDS.create(world, new BOPEndBiomeProvider(endBiomeProviderSettings), endgensettings); + }*/ else { return super.createChunkGenerator(world); diff --git a/src/main/java/biomesoplenty/init/ModBiomes.java b/src/main/java/biomesoplenty/init/ModBiomes.java index 0f7060ba5..4dd1014ed 100644 --- a/src/main/java/biomesoplenty/init/ModBiomes.java +++ b/src/main/java/biomesoplenty/init/ModBiomes.java @@ -20,6 +20,7 @@ import com.google.common.collect.Multimap; import biomesoplenty.api.biome.BOPBiomes; import biomesoplenty.api.enums.BOPClimates; import biomesoplenty.common.biome.BiomeBOP; +import biomesoplenty.common.biome.end.SpectralGardenBiome; import biomesoplenty.common.biome.overworld.AlpsBiome; import biomesoplenty.common.biome.overworld.AlpsFoothillsBiome; import biomesoplenty.common.biome.overworld.BayouBiome; @@ -165,6 +166,8 @@ public class ModBiomes wetland = registerBiome(new WetlandBiome(), "wetland"); woodland = registerBiome(new WoodlandBiome(), "woodland"); xeric_shrubland = registerBiome(new XericShrublandBiome(), "xeric_shrubland"); + + spectral_garden = registerBiome(new SpectralGardenBiome(), "spectral_garden"); // Note: Rarity supports two decimal places registerSubBiome(Biomes.DESERT, oasis, 0.1F, 100);