diff --git a/src/main/java/ru/betterend/registry/EndBiomes.java b/src/main/java/ru/betterend/registry/EndBiomes.java index 28af2e9d..e9d61013 100644 --- a/src/main/java/ru/betterend/registry/EndBiomes.java +++ b/src/main/java/ru/betterend/registry/EndBiomes.java @@ -41,6 +41,7 @@ import ru.betterend.world.biome.BiomeMegalakeGrove; import ru.betterend.world.biome.BiomePaintedMountains; import ru.betterend.world.biome.BiomeShadowForest; import ru.betterend.world.biome.BiomeSulphurSprings; +import ru.betterend.world.biome.BiomeUmbrellaJungle; import ru.betterend.world.biome.EndBiome; import ru.betterend.world.generator.BELayerRandomSource; import ru.betterend.world.generator.BiomePicker; @@ -58,8 +59,6 @@ public class EndBiomes { private static final JsonObject EMPTY_JSON = new JsonObject(); private static Registry biomeRegistry; - private static Set occupiedIDs = Sets.newHashSet(); - private static int incID = 8196; // Vanilla Land public static final EndBiome END = registerBiome(BiomeKeys.THE_END, BiomeType.LAND, 1F); @@ -82,6 +81,7 @@ public class EndBiomes { public static final EndBiome AMBER_LAND = registerBiome(new BiomeAmberLand(), BiomeType.LAND); public static final EndBiome BLOSSOMING_SPIRES = registerBiome(new BiomeBlossomingSpires(), BiomeType.LAND); public static final EndBiome SULPHUR_SPRINGS = registerBiome(new BiomeSulphurSprings(), BiomeType.LAND); + public static final EndBiome UMBRELLA_JUNGLE = registerBiome(new BiomeUmbrellaJungle(), BiomeType.LAND); // Better End Void public static final EndBiome ICE_STARFIELD = registerBiome(new BiomeIceStarfield(), BiomeType.VOID); @@ -312,28 +312,10 @@ public class EndBiomes { else VOID_BIOMES.addBiome(biome); } - - private static void fillSet() { - if (occupiedIDs.isEmpty()) { - BuiltinRegistries.BIOME.getEntries().forEach((entry) -> { - int id = BuiltinRegistries.BIOME.getRawId(entry.getValue()); - occupiedIDs.add(id); - }); - } - } private static void registerBiomeDirect(EndBiome biome) { - fillSet(); - int possibleID = incID++; - if (occupiedIDs.contains(possibleID)) { - String message = "ID for biome " + biome.getID() + " is already occupied, changing biome ID from " + possibleID + " to "; - while (occupiedIDs.contains(possibleID)) { - possibleID ++; - } - BetterEnd.LOGGER.info(message + possibleID); - } if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { - Registry.register(BuiltinRegistries.BIOME, possibleID, biome.getID().toString(), biome.getBiome()); + Registry.register(BuiltinRegistries.BIOME, biome.getID(), biome.getBiome()); } } diff --git a/src/main/java/ru/betterend/registry/EndFeatures.java b/src/main/java/ru/betterend/registry/EndFeatures.java index 036d141b..bf0fdfd2 100644 --- a/src/main/java/ru/betterend/registry/EndFeatures.java +++ b/src/main/java/ru/betterend/registry/EndFeatures.java @@ -46,6 +46,7 @@ import ru.betterend.world.features.trees.LacugroveFeature; import ru.betterend.world.features.trees.MossyGlowshroomFeature; import ru.betterend.world.features.trees.PythadendronTreeFeature; import ru.betterend.world.features.trees.TenaneaFeature; +import ru.betterend.world.features.trees.UmbrellaTreeFeature; public class EndFeatures { // Trees // @@ -55,6 +56,7 @@ public class EndFeatures { public static final EndFeature DRAGON_TREE = new EndFeature("dragon_tree", new DragonTreeFeature(), 3); public static final EndFeature TENANEA = new EndFeature("tenanea", new TenaneaFeature(), 3); public static final EndFeature HELIX_TREE = new EndFeature("helix_tree", new HelixTreeFeature(), 2); + public static final EndFeature UMBRELLA_TREE = new EndFeature("umbrella_tree", new UmbrellaTreeFeature(), 2); // Bushes // public static final EndFeature PYTHADENDRON_BUSH = new EndFeature("pythadendron_bush", new BushFeature(EndBlocks.PYTHADENDRON_LEAVES, EndBlocks.PYTHADENDRON.bark), 4); diff --git a/src/main/java/ru/betterend/world/biome/BiomeUmbrellaJungle.java b/src/main/java/ru/betterend/world/biome/BiomeUmbrellaJungle.java new file mode 100644 index 00000000..e63ca8b1 --- /dev/null +++ b/src/main/java/ru/betterend/world/biome/BiomeUmbrellaJungle.java @@ -0,0 +1,18 @@ +package ru.betterend.world.biome; + +import ru.betterend.registry.EndBlocks; +import ru.betterend.registry.EndFeatures; + +public class BiomeUmbrellaJungle extends EndBiome { + public BiomeUmbrellaJungle() { + super(new BiomeDefinition("umbrella_jungle") + .setFogColor(87, 223, 221) + .setWaterAndFogColor(119, 198, 253) + .setFoliageColor(27, 183, 194) + .setFogDensity(2.3F) + .setSurface(EndBlocks.END_MOSS) + .addFeature(EndFeatures.UMBRELLA_TREE) + .addFeature(EndFeatures.UMBRELLA_MOSS) + .addFeature(EndFeatures.END_LAKE)); + } +} \ No newline at end of file diff --git a/src/main/java/ru/betterend/world/features/trees/UmbrellaTreeFeature.java b/src/main/java/ru/betterend/world/features/trees/UmbrellaTreeFeature.java new file mode 100644 index 00000000..161e5c8f --- /dev/null +++ b/src/main/java/ru/betterend/world/features/trees/UmbrellaTreeFeature.java @@ -0,0 +1,125 @@ +package ru.betterend.world.features.trees; + +import java.util.List; +import java.util.Random; +import java.util.function.Function; + +import com.google.common.collect.Lists; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Material; +import net.minecraft.client.util.math.Vector3f; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; +import net.minecraft.world.StructureWorldAccess; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.feature.DefaultFeatureConfig; +import ru.betterend.registry.EndBlocks; +import ru.betterend.registry.EndTags; +import ru.betterend.util.MHelper; +import ru.betterend.util.SplineHelper; +import ru.betterend.util.sdf.PosInfo; +import ru.betterend.util.sdf.SDF; +import ru.betterend.util.sdf.operator.SDFUnion; +import ru.betterend.world.features.DefaultFeature; + +public class UmbrellaTreeFeature extends DefaultFeature { + private static final Function REPLACE; + private static final Function POST; + private static final List SPLINE; + private static final List ROOT; + + @Override + public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) { + if (!world.getBlockState(pos.down()).getBlock().isIn(EndTags.END_GROUND)) return false; + + float size = MHelper.randRange(10, 20, random); + int count = (int) (size * 0.15F); + float var = MHelper.PI2 / (float) (count * 3); + float start = MHelper.randRange(0, MHelper.PI2, random); + SDF sdf = null; + int x1 = ((pos.getX() >> 4) << 4) - 16; + int z1 = ((pos.getZ() >> 4) << 4) - 16; + Box limits = new Box(x1, pos.getY() - 5, z1, x1 + 47, pos.getY() + size * 2, z1 + 47); + BlockState wood = EndBlocks.UMBRELLA_TREE.bark.getDefaultState(); + for (int i = 0; i < count; i++) { + float angle = (float) i / (float) count * MHelper.PI2 + MHelper.randRange(0, var, random) + start; + List spline = SplineHelper.copySpline(SPLINE); + float sizeXZ = (size + MHelper.randRange(0, size * 0.5F, random)) * 0.7F; + SplineHelper.scale(spline, sizeXZ, sizeXZ * 1.5F + MHelper.randRange(0, size * 0.5F, random), sizeXZ); + SplineHelper.offset(spline, new Vector3f((20 - size), 0, 0)); + SplineHelper.rotateSpline(spline, angle); + SplineHelper.offsetParts(spline, random, 1F, 0, 1F); + SDF branch = SplineHelper.buildSDF(spline, 2.3F, 1.3F, (bpos) -> { + return wood; + }); + + Vector3f vec = spline.get(spline.size() - 1); + //float radius = (size + MHelper.randRange(0, size * 0.5F, random)) * 0.35F; + vec = SplineHelper.getPos(spline, 0.3F); + + makeRoots(world, pos.add(vec.getX(), vec.getY(), vec.getZ()), size * 0.4F + 5, random, wood); + + sdf = (sdf == null) ? branch : new SDFUnion().setSourceA(sdf).setSourceB(branch); + } + + sdf.setReplaceFunction(REPLACE).setPostProcess(POST).fillArea(world, pos, limits); + + return true; + } + + private void makeRoots(StructureWorldAccess world, BlockPos pos, float radius, Random random, BlockState wood) { + int count = (int) (radius * 1.5F); + for (int i = 0; i < count; i++) { + float angle = (float) i / (float) count * MHelper.PI2; + float scale = radius * MHelper.randRange(0.85F, 1.15F, random); + + List branch = SplineHelper.copySpline(ROOT); + SplineHelper.rotateSpline(branch, angle); + SplineHelper.scale(branch, scale); + Vector3f last = branch.get(branch.size() - 1); + if (world.getBlockState(pos.add(last.getX(), last.getY(), last.getZ())).isIn(EndTags.GEN_TERRAIN)) { + SplineHelper.fillSpline(branch, world, wood, pos, REPLACE); + } + } + } + + static { + SPLINE = Lists.newArrayList( + new Vector3f(0.00F, 0.00F, 0.00F), + new Vector3f(0.10F, 0.35F, 0.00F), + new Vector3f(0.20F, 0.50F, 0.00F), + new Vector3f(0.30F, 0.55F, 0.00F), + new Vector3f(0.42F, 0.70F, 0.00F), + new Vector3f(0.50F, 1.00F, 0.00F) + ); + + ROOT = Lists.newArrayList(new Vector3f(0F, 1F, 0), + new Vector3f(0.1F, 0.70F, 0), + new Vector3f(0.3F, 0.30F, 0), + new Vector3f(0.7F, 0.05F, 0), + new Vector3f(0.8F, -0.20F, 0) + ); + SplineHelper.offset(ROOT, new Vector3f(0, -0.45F, 0)); + + REPLACE = (state) -> { + if (state.isIn(EndTags.END_GROUND)) { + return true; + } + if (state.getBlock() == EndBlocks.DRAGON_TREE_LEAVES) { + return true; + } + if (state.getMaterial().equals(Material.PLANT)) { + return true; + } + return state.getMaterial().isReplaceable(); + }; + + POST = (info) -> { + if (EndBlocks.UMBRELLA_TREE.isTreeLog(info.getStateUp()) && EndBlocks.UMBRELLA_TREE.isTreeLog(info.getStateDown())) { + return EndBlocks.UMBRELLA_TREE.log.getDefaultState(); + } + return info.getState(); + }; + } +}