diff --git a/src/main/java/ru/betterend/interfaces/IBiomeArray.java b/src/main/java/ru/betterend/interfaces/IBiomeArray.java new file mode 100644 index 00000000..8916cd5c --- /dev/null +++ b/src/main/java/ru/betterend/interfaces/IBiomeArray.java @@ -0,0 +1,8 @@ +package ru.betterend.interfaces; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.biome.Biome; + +public interface IBiomeArray { + public void setBiome(Biome biome, BlockPos pos); +} diff --git a/src/main/java/ru/betterend/mixin/common/BiomeArrayMixin.java b/src/main/java/ru/betterend/mixin/common/BiomeArrayMixin.java new file mode 100644 index 00000000..deb834e7 --- /dev/null +++ b/src/main/java/ru/betterend/mixin/common/BiomeArrayMixin.java @@ -0,0 +1,46 @@ +package ru.betterend.mixin.common; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.biome.Biome; +import net.minecraft.world.biome.source.BiomeArray; +import ru.betterend.interfaces.IBiomeArray; + +@Mixin(BiomeArray.class) +public class BiomeArrayMixin implements IBiomeArray { + @Final + @Shadow + private Biome[] data; + + @Final + @Shadow + private static int HORIZONTAL_SECTION_COUNT; + + @Final + @Shadow + public static int HORIZONTAL_BIT_MASK; + + @Final + @Shadow + public static int VERTICAL_BIT_MASK; + + @Override + public void setBiome(Biome biome, BlockPos pos) { + int biomeX = pos.getX() >> 2; + int biomeY = pos.getY() >> 2; + int biomeZ = pos.getZ() >> 2; + int index = be_getArrayIndex(biomeX, biomeY, biomeZ); + data[index] = biome; + } + + private int be_getArrayIndex(int biomeX, int biomeY, int biomeZ) { + int i = biomeX & HORIZONTAL_BIT_MASK; + int j = MathHelper.clamp(biomeY, 0, VERTICAL_BIT_MASK); + int k = biomeZ & HORIZONTAL_BIT_MASK; + return j << HORIZONTAL_SECTION_COUNT + HORIZONTAL_SECTION_COUNT | k << HORIZONTAL_SECTION_COUNT | i; + } +} diff --git a/src/main/java/ru/betterend/registry/EndBiomes.java b/src/main/java/ru/betterend/registry/EndBiomes.java index a21fbd92..f961837a 100644 --- a/src/main/java/ru/betterend/registry/EndBiomes.java +++ b/src/main/java/ru/betterend/registry/EndBiomes.java @@ -4,6 +4,7 @@ import java.io.InputStream; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Random; import java.util.Set; import com.google.common.collect.Lists; @@ -45,7 +46,9 @@ import ru.betterend.world.biome.BiomeSulphurSprings; import ru.betterend.world.biome.BiomeUmbrellaJungle; import ru.betterend.world.biome.DragonGraveyardsBiome; import ru.betterend.world.biome.DryShrublandBiome; +import ru.betterend.world.biome.EmptyEndCaveBiome; import ru.betterend.world.biome.EndBiome; +import ru.betterend.world.biome.EndCaveBiome; import ru.betterend.world.biome.GlowingGrasslandsBiome; import ru.betterend.world.generator.BELayerRandomSource; import ru.betterend.world.generator.BiomePicker; @@ -59,6 +62,7 @@ public class EndBiomes { public static final BiomePicker LAND_BIOMES = new BiomePicker(); public static final BiomePicker VOID_BIOMES = new BiomePicker(); + public static final BiomePicker CAVE_BIOMES = new BiomePicker(); public static final List SUBBIOMES = Lists.newArrayList(); private static final JsonObject EMPTY_JSON = new JsonObject(); @@ -93,6 +97,9 @@ public class EndBiomes { // Better End Void public static final EndBiome ICE_STARFIELD = registerBiome(new BiomeIceStarfield(), BiomeType.VOID); + // Better End Caves + public static final EndCaveBiome EMPTY_CAVE = registerCaveBiome(new EmptyEndCaveBiome()); + public static void register() {} public static void mutateRegistry(Registry biomeRegistry) { @@ -100,6 +107,7 @@ public class EndBiomes { LAND_BIOMES.clearMutables(); VOID_BIOMES.clearMutables(); + CAVE_BIOMES.clearMutables(); if (FABRIC_VOID.isEmpty()) { loadFabricAPIBiomes(); @@ -144,16 +152,9 @@ public class EndBiomes { Integrations.addBiomes(); Configs.BIOME_CONFIG.saveChanges(); - LAND_BIOMES.rebuild(); - VOID_BIOMES.rebuild(); - - LAND_BIOMES.getBiomes().forEach((endBiome) -> { - endBiome.updateActualBiomes(biomeRegistry); - }); - - VOID_BIOMES.getBiomes().forEach((endBiome) -> { - endBiome.updateActualBiomes(biomeRegistry); - }); + rebuildPicker(LAND_BIOMES, biomeRegistry); + rebuildPicker(VOID_BIOMES, biomeRegistry); + rebuildPicker(CAVE_BIOMES, biomeRegistry); SUBBIOMES.forEach((endBiome) -> { endBiome.updateActualBiomes(biomeRegistry); @@ -162,6 +163,13 @@ public class EndBiomes { CLIENT.clear(); } + private static void rebuildPicker(BiomePicker picker, Registry biomeRegistry) { + picker.rebuild(); + picker.getBiomes().forEach((endBiome) -> { + endBiome.updateActualBiomes(biomeRegistry); + }); + } + private static void loadFabricAPIBiomes() { WeightedBiomePicker picker = InternalBiomeData.getEndBiomesMap().get(BiomeKeys.SMALL_END_ISLANDS); LayerRandomnessSource random = new BELayerRandomSource(); @@ -343,10 +351,12 @@ public class EndBiomes { } private static void addToPicker(EndBiome biome, BiomeType type) { - if (type == BiomeType.LAND) + if (type == BiomeType.LAND) { LAND_BIOMES.addBiome(biome); - else + } + else { VOID_BIOMES.addBiome(biome); + } } private static void registerBiomeDirectly(EndBiome biome) { @@ -400,4 +410,21 @@ public class EndBiomes { result.addAll(SUBBIOMES); return result; } + + public static EndCaveBiome registerCaveBiome(EndCaveBiome biome) { + registerBiomeDirectly(biome); + if (Configs.BIOME_CONFIG.getBoolean(biome.getID(), "enabled", true)) { + CAVE_BIOMES.addBiome(biome); + ID_MAP.put(biome.getID(), biome); + } + return biome; + } + + public static EndCaveBiome getCaveBiome(Random random) { + return (EndCaveBiome) CAVE_BIOMES.getBiome(random); + } + + public static boolean hasBiome(Identifier biomeID) { + return ID_MAP.containsKey(biomeID); + } } diff --git a/src/main/java/ru/betterend/registry/EndFeatures.java b/src/main/java/ru/betterend/registry/EndFeatures.java index c0f693f2..060799e6 100644 --- a/src/main/java/ru/betterend/registry/EndFeatures.java +++ b/src/main/java/ru/betterend/registry/EndFeatures.java @@ -13,7 +13,6 @@ import ru.betterend.BetterEnd; import ru.betterend.world.biome.BiomeDefinition; import ru.betterend.world.biome.EndBiome; import ru.betterend.world.features.BlueVineFeature; -import ru.betterend.world.features.CavePlantFeature; import ru.betterend.world.features.CharniaFeature; import ru.betterend.world.features.CrashedShipFeature; import ru.betterend.world.features.DoublePlantFeature; @@ -44,12 +43,12 @@ import ru.betterend.world.features.terrain.GeyserFeature; import ru.betterend.world.features.terrain.IceStarFeature; import ru.betterend.world.features.terrain.ObsidianBoulderFeature; import ru.betterend.world.features.terrain.ObsidianPillarBasementFeature; -import ru.betterend.world.features.terrain.RoundCaveFeature; import ru.betterend.world.features.terrain.SpireFeature; import ru.betterend.world.features.terrain.SulphurHillFeature; import ru.betterend.world.features.terrain.SulphuricCaveFeature; import ru.betterend.world.features.terrain.SulphuricLakeFeature; import ru.betterend.world.features.terrain.SurfaceVentFeature; +import ru.betterend.world.features.terrain.caves.RoundCaveFeature; import ru.betterend.world.features.trees.DragonTreeFeature; import ru.betterend.world.features.trees.GiganticAmaranitaFeature; import ru.betterend.world.features.trees.HelixTreeFeature; @@ -85,7 +84,6 @@ public class EndFeatures { public static final EndFeature CREEPING_MOSS = new EndFeature("creeping_moss", new SinglePlantFeature(EndBlocks.CREEPING_MOSS, 5), 5); public static final EndFeature BLUE_VINE = new EndFeature("blue_vine", new BlueVineFeature(), 1); public static final EndFeature CHORUS_GRASS = new EndFeature("chorus_grass", new SinglePlantFeature(EndBlocks.CHORUS_GRASS, 4), 5); - public static final EndFeature CAVE_GRASS = new EndFeature("cave_grass", new CavePlantFeature(EndBlocks.CAVE_GRASS, 7), 7); public static final EndFeature CRYSTAL_GRASS = new EndFeature("crystal_grass", new SinglePlantFeature(EndBlocks.CRYSTAL_GRASS, 8, false), 5); public static final EndFeature SHADOW_PLANT = new EndFeature("shadow_plant", new SinglePlantFeature(EndBlocks.SHADOW_PLANT, 6), 9); public static final EndFeature MURKWEED = new EndFeature("murkweed", new SinglePlantFeature(EndBlocks.MURKWEED, 3), 2); @@ -161,7 +159,6 @@ public class EndFeatures { public static final EndFeature END_LAKE = EndFeature.makeLakeFeature("end_lake", new EndLakeFeature(), 4); public static final EndFeature END_LAKE_RARE = EndFeature.makeLakeFeature("end_lake_rare", new EndLakeFeature(), 40); public static final EndFeature ROUND_CAVE = EndFeature.makeRawGenFeature("round_cave", new RoundCaveFeature(), 2); - public static final EndFeature ROUND_CAVE_RARE = EndFeature.makeRawGenFeature("round_cave_rare", new RoundCaveFeature(), 25); public static final EndFeature SPIRE = EndFeature.makeRawGenFeature("spire", new SpireFeature(), 2); public static final EndFeature FLOATING_SPIRE = EndFeature.makeRawGenFeature("floating_spire", new FloatingSpireFeature(), 8); public static final EndFeature GEYSER = EndFeature.makeRawGenFeature("geyser", new GeyserFeature(), 8); @@ -215,8 +212,7 @@ public class EndFeatures { addFeature(CRASHED_SHIP, features); if (EndBiomes.getBiome(id).hasCaves()) { - addFeature(ROUND_CAVE_RARE, features); - addFeature(CAVE_GRASS, features); + addFeature(ROUND_CAVE, features); } EndBiome endBiome = EndBiomes.getBiome(id); @@ -233,8 +229,7 @@ public class EndFeatures { def.addFeature(CRASHED_SHIP); if (def.hasCaves()) { - def.addFeature(ROUND_CAVE_RARE); - def.addFeature(CAVE_GRASS); + def.addFeature(ROUND_CAVE); } } diff --git a/src/main/java/ru/betterend/world/biome/BiomeDefinition.java b/src/main/java/ru/betterend/world/biome/BiomeDefinition.java index a9547b37..a3ce12fa 100644 --- a/src/main/java/ru/betterend/world/biome/BiomeDefinition.java +++ b/src/main/java/ru/betterend/world/biome/BiomeDefinition.java @@ -67,13 +67,19 @@ public class BiomeDefinition { private final Identifier id; private float genChance = 1F; private boolean hasCaves = true; + private boolean isCaveBiome = false; private ConfiguredSurfaceBuilder surface; public BiomeDefinition(String name) { this.id = BetterEnd.makeID(name); } - + + public BiomeDefinition setCaveBiome() { + isCaveBiome = true; + return this; + } + public BiomeDefinition setSurface(Block block) { setSurface(SurfaceBuilder.DEFAULT.withConfig(new TernarySurfaceConfig( block.getDefaultState(), @@ -249,7 +255,7 @@ public class BiomeDefinition { return new Biome.Builder() .precipitation(Precipitation.NONE) - .category(Category.THEEND) + .category(isCaveBiome ? Category.NONE : Category.THEEND) .depth(0.1F) .scale(0.2F) .temperature(2.0F) diff --git a/src/main/java/ru/betterend/world/biome/EmptyEndCaveBiome.java b/src/main/java/ru/betterend/world/biome/EmptyEndCaveBiome.java new file mode 100644 index 00000000..6ebe900a --- /dev/null +++ b/src/main/java/ru/betterend/world/biome/EmptyEndCaveBiome.java @@ -0,0 +1,18 @@ +package ru.betterend.world.biome; + +import ru.betterend.registry.EndBlocks; +import ru.betterend.registry.EndParticles; +import ru.betterend.registry.EndSounds; + +public class EmptyEndCaveBiome extends EndCaveBiome { + public EmptyEndCaveBiome() { + super(new BiomeDefinition("empty_end_cave") + .setFogColor(255, 184, 71) + .setFogDensity(2.0F) + .setPlantsColor(219, 115, 38) + .setWaterAndFogColor(145, 108, 72) + .setMusic(EndSounds.MUSIC_FOREST) + .setParticles(EndParticles.AMBER_SPHERE, 0.001F) + .setSurface(EndBlocks.AMBER_MOSS)); + } +} diff --git a/src/main/java/ru/betterend/world/biome/EndBiome.java b/src/main/java/ru/betterend/world/biome/EndBiome.java index 8c57c4e8..478bc398 100644 --- a/src/main/java/ru/betterend/world/biome/EndBiome.java +++ b/src/main/java/ru/betterend/world/biome/EndBiome.java @@ -190,8 +190,7 @@ public class EndBiome { if (edge != null) { edge.updateActualBiomes(biomeRegistry); } - Biome biome = biomeRegistry.get(mcID); - this.actualBiome = biome; + this.actualBiome = biomeRegistry.get(mcID); } @Override diff --git a/src/main/java/ru/betterend/world/biome/EndCaveBiome.java b/src/main/java/ru/betterend/world/biome/EndCaveBiome.java new file mode 100644 index 00000000..769398bd --- /dev/null +++ b/src/main/java/ru/betterend/world/biome/EndCaveBiome.java @@ -0,0 +1,33 @@ +package ru.betterend.world.biome; + +import java.util.List; +import java.util.Random; + +import com.google.common.collect.Lists; + +import net.minecraft.world.gen.feature.Feature; + +public class EndCaveBiome extends EndBiome { + private List> floorFeatures = Lists.newArrayList(); + private List> ceilFeatures = Lists.newArrayList(); + + public EndCaveBiome(BiomeDefinition definition) { + super(definition.setCaveBiome()); + } + + public void addFloorFeature(Feature feature) { + floorFeatures.add(feature); + } + + public void addCeilFeature(Feature feature) { + ceilFeatures.add(feature); + } + + public Feature getFloorFeature(Random random) { + return floorFeatures.isEmpty() ? null : floorFeatures.get(random.nextInt(floorFeatures.size())); + } + + public Feature getCeilFeature(Random random) { + return ceilFeatures.isEmpty() ? null : ceilFeatures.get(random.nextInt(ceilFeatures.size())); + } +} diff --git a/src/main/java/ru/betterend/world/features/terrain/RoundCaveFeature.java b/src/main/java/ru/betterend/world/features/terrain/RoundCaveFeature.java index 6c2d53a3..0416f267 100644 --- a/src/main/java/ru/betterend/world/features/terrain/RoundCaveFeature.java +++ b/src/main/java/ru/betterend/world/features/terrain/RoundCaveFeature.java @@ -32,6 +32,7 @@ import ru.betterend.util.sdf.primitive.SDFSphere; import ru.betterend.world.features.DefaultFeature; import ru.betterend.world.generator.GeneratorOptions; +@Deprecated public class RoundCaveFeature extends DefaultFeature { private static final BlockState CAVE_AIR = Blocks.CAVE_AIR.getDefaultState(); diff --git a/src/main/java/ru/betterend/world/features/terrain/caves/EndCaveFeature.java b/src/main/java/ru/betterend/world/features/terrain/caves/EndCaveFeature.java new file mode 100644 index 00000000..a8d59265 --- /dev/null +++ b/src/main/java/ru/betterend/world/features/terrain/caves/EndCaveFeature.java @@ -0,0 +1,134 @@ +package ru.betterend.world.features.terrain.caves; + +import java.util.Random; +import java.util.Set; + +import com.google.common.collect.Sets; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockPos.Mutable; +import net.minecraft.world.Heightmap; +import net.minecraft.world.StructureWorldAccess; +import net.minecraft.world.gen.chunk.ChunkGenerator; +import net.minecraft.world.gen.feature.DefaultFeatureConfig; +import ru.betterend.interfaces.IBiomeArray; +import ru.betterend.registry.EndBiomes; +import ru.betterend.registry.EndTags; +import ru.betterend.util.BlocksHelper; +import ru.betterend.util.MHelper; +import ru.betterend.world.biome.EndCaveBiome; +import ru.betterend.world.features.DefaultFeature; +import ru.betterend.world.generator.GeneratorOptions; + +public abstract class EndCaveFeature extends DefaultFeature { + protected static final BlockState CAVE_AIR = Blocks.CAVE_AIR.getDefaultState(); + protected static final BlockState END_STONE = Blocks.END_STONE.getDefaultState(); + protected static final BlockState WATER = Blocks.WATER.getDefaultState(); + + @Override + public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) { + if (!(GeneratorOptions.useNewGenerator() && GeneratorOptions.noRingVoid()) || pos.getX() * pos.getX() + pos.getZ() * pos.getZ() <= 22500) { + return false; + } + + int radius = MHelper.randRange(10, 30, random); + BlockPos center = findPos(world, pos, radius, random); + + if (center == null) { + return false; + } + + EndCaveBiome biome = EndBiomes.getCaveBiome(random); + Set caveBlocks = generate(world, center, radius, random); + if (biome != null && !caveBlocks.isEmpty()) { + setBiomes(world, biome, caveBlocks); + Set floorPositions = Sets.newHashSet(); + Set ceilPositions = Sets.newHashSet(); + Mutable mut = new Mutable(); + caveBlocks.forEach((bpos) -> { + mut.set(bpos); + if (world.getBlockState(mut).getMaterial().isReplaceable()) { + mut.setY(bpos.getY() - 1); + if (world.getBlockState(mut).isIn(EndTags.GEN_TERRAIN)) { + floorPositions.add(mut.toImmutable()); + } + mut.setY(bpos.getY() + 1); + if (world.getBlockState(mut).isIn(EndTags.GEN_TERRAIN)) { + ceilPositions.add(mut.toImmutable()); + } + } + }); + BlockState surfaceBlock = biome.getBiome().getGenerationSettings().getSurfaceConfig().getTopMaterial(); + placeFloor(world, biome, floorPositions, random, surfaceBlock); + placeCeil(world, biome, ceilPositions, random); + } + fixBlocks(world, center, radius); + + return true; + } + + protected abstract Set generate(StructureWorldAccess world, BlockPos center, int radius, Random random); + + protected void placeFloor(StructureWorldAccess world, EndCaveBiome biome, Set floorPositions, Random random, BlockState surfaceBlock) { + floorPositions.forEach((pos) -> { + BlocksHelper.setWithoutUpdate(world, pos, surfaceBlock); + }); + } + + protected void placeCeil(StructureWorldAccess world, EndCaveBiome biome, Set ceilPositions, Random random) { + + } + + protected void setBiomes(StructureWorldAccess world, EndCaveBiome biome, Set blocks) { + blocks.forEach((pos) -> setBiome(world, pos, biome)); + } + + private void setBiome(StructureWorldAccess world, BlockPos pos, EndCaveBiome biome) { + IBiomeArray array = (IBiomeArray) world.getChunk(pos).getBiomeArray(); + if (array != null) { + array.setBiome(biome.getActualBiome(), pos); + } + } + + private BlockPos findPos(StructureWorldAccess world, BlockPos pos, int radius, Random random) { + int top = world.getTopY(Heightmap.Type.WORLD_SURFACE_WG, pos.getX(), pos.getZ()); + Mutable bpos = new Mutable(); + bpos.setX(pos.getX()); + bpos.setZ(pos.getZ()); + bpos.setY(top - 1); + + BlockState state = world.getBlockState(bpos); + while (!state.isIn(EndTags.GEN_TERRAIN) && bpos.getY() > 5) { + bpos.setY(bpos.getY() - 1); + state = world.getBlockState(bpos); + } + if (bpos.getY() < 10) { + return null; + } + top = (int) (bpos.getY() - (radius * 1.3F + 5)); + + while (state.isIn(EndTags.GEN_TERRAIN) || !state.getFluidState().isEmpty() && bpos.getY() > 5) { + bpos.setY(bpos.getY() - 1); + state = world.getBlockState(bpos); + } + int bottom = (int) (bpos.getY() + radius * 1.3F + 5); + + if (top <= bottom) { + return null; + } + + return new BlockPos(pos.getX(), MHelper.randRange(bottom, top, random), pos.getZ()); + } + + private void fixBlocks(StructureWorldAccess world, BlockPos pos, int radius) { + int x1 = pos.getX() - radius - 5; + int y1 = pos.getY() - radius - 5; + int z1 = pos.getZ() - radius - 5; + int x2 = pos.getX() + radius + 5; + int y2 = pos.getY() + radius + 5; + int z2 = pos.getZ() + radius + 5; + BlocksHelper.fixBlocks(world, new BlockPos(x1, y1, z1), new BlockPos(x2, y2, z2)); + } +} diff --git a/src/main/java/ru/betterend/world/features/terrain/caves/RoundCaveFeature.java b/src/main/java/ru/betterend/world/features/terrain/caves/RoundCaveFeature.java new file mode 100644 index 00000000..5f32e5e4 --- /dev/null +++ b/src/main/java/ru/betterend/world/features/terrain/caves/RoundCaveFeature.java @@ -0,0 +1,85 @@ +package ru.betterend.world.features.terrain.caves; + +import java.util.Random; +import java.util.Set; + +import com.google.common.collect.Sets; + +import net.minecraft.block.BlockState; +import net.minecraft.block.Material; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockPos.Mutable; +import net.minecraft.world.StructureWorldAccess; +import ru.betterend.noise.OpenSimplexNoise; +import ru.betterend.registry.EndTags; +import ru.betterend.util.BlocksHelper; +import ru.betterend.util.MHelper; + +public class RoundCaveFeature extends EndCaveFeature { + @Override + protected Set generate(StructureWorldAccess world, BlockPos center, int radius, Random random) { + OpenSimplexNoise noise = new OpenSimplexNoise(MHelper.getSeed(534, center.getX(), center.getZ())); + + int x1 = center.getX() - radius - 5; + int z1 = center.getZ() - radius - 5; + int x2 = center.getX() + radius + 5; + int z2 = center.getZ() + radius + 5; + int y1 = MHelper.floor(center.getY() - (radius + 5) / 1.6); + int y2 = MHelper.floor(center.getY() + (radius + 5) / 1.6); + + double hr = radius * 0.75; + double nr = radius * 0.25; + + BlockState state; + Mutable bpos = new Mutable(); + Set blocks = Sets.newHashSet(); + for (int x = x1; x <= x2; x++) { + int xsq = x - center.getX(); + xsq *= xsq; + bpos.setX(x); + for (int z = z1; z <= z2; z++) { + int zsq = z - center.getZ(); + zsq *= zsq; + bpos.setZ(z); + for (int y = y1; y <= y2; y++) { + int ysq = y - center.getY(); + ysq *= 1.6; + ysq *= ysq; + bpos.setY(y); + double r = noise.eval(x * 0.1, y * 0.1, z * 0.1) * nr + hr; + //double r2 = r + 5; + double dist = xsq + ysq + zsq; + if (dist < r * r) { + state = world.getBlockState(bpos); + if (isReplaceable(state)) { + BlocksHelper.setWithoutUpdate(world, bpos, CAVE_AIR); + blocks.add(bpos.toImmutable()); + + while (state.getMaterial().equals(Material.LEAVES)) { + BlocksHelper.setWithoutUpdate(world, bpos, CAVE_AIR); + bpos.setY(bpos.getY() + 1); + state = world.getBlockState(bpos); + } + + bpos.setY(y - 1); + while (state.getMaterial().equals(Material.LEAVES)) { + BlocksHelper.setWithoutUpdate(world, bpos, CAVE_AIR); + bpos.setY(bpos.getY() - 1); + state = world.getBlockState(bpos); + } + } + } + } + } + } + + return blocks; + } + + private boolean isReplaceable(BlockState state) { + return state.isIn(EndTags.GEN_TERRAIN) + || state.getMaterial().isReplaceable() + || state.getMaterial().equals(Material.PLANT) + || state.getMaterial().equals(Material.LEAVES); + } +} diff --git a/src/main/java/ru/betterend/world/generator/BetterEndBiomeSource.java b/src/main/java/ru/betterend/world/generator/BetterEndBiomeSource.java index 96e98a76..a2eb7c0a 100644 --- a/src/main/java/ru/betterend/world/generator/BetterEndBiomeSource.java +++ b/src/main/java/ru/betterend/world/generator/BetterEndBiomeSource.java @@ -10,7 +10,6 @@ import net.minecraft.util.math.noise.SimplexNoiseSampler; import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.RegistryLookupCodec; import net.minecraft.world.biome.Biome; -import net.minecraft.world.biome.Biome.Category; import net.minecraft.world.biome.BiomeKeys; import net.minecraft.world.biome.source.BiomeSource; import net.minecraft.world.biome.source.TheEndBiomeSource; @@ -61,7 +60,7 @@ public class BetterEndBiomeSource extends BiomeSource { private static List getBiomes(Registry biomeRegistry) { List list = Lists.newArrayList(); biomeRegistry.forEach((biome) -> { - if (biome.getCategory() == Category.THEEND) { + if (EndBiomes.hasBiome(biomeRegistry.getId(biome))) { list.add(biome); } }); diff --git a/src/main/java/ru/betterend/world/generator/BiomePicker.java b/src/main/java/ru/betterend/world/generator/BiomePicker.java index 4db12d23..050ab133 100644 --- a/src/main/java/ru/betterend/world/generator/BiomePicker.java +++ b/src/main/java/ru/betterend/world/generator/BiomePicker.java @@ -32,12 +32,13 @@ public class BiomePicker { public void clearMutables() { maxChance = maxChanceUnmutable; - for (int i = biomes.size() - 1; i >= biomeCount; i--) + for (int i = biomes.size() - 1; i >= biomeCount; i--) { biomes.remove(i); + } } public EndBiome getBiome(Random random) { - return tree.getBiome(random.nextFloat() * maxChance); + return biomes.isEmpty() ? null : tree.getBiome(random.nextFloat() * maxChance); } public List getBiomes() { @@ -59,6 +60,9 @@ public class BiomePicker { } public void rebuild() { + if (biomes.isEmpty()) { + return; + } maxChance = maxChanceUnmutable; for (int i = biomeCount; i < biomes.size(); i++) { maxChance = biomes.get(i).mutateGenChance(maxChance); diff --git a/src/main/resources/betterend.mixins.common.json b/src/main/resources/betterend.mixins.common.json index 47b3b116..1dc83764 100644 --- a/src/main/resources/betterend.mixins.common.json +++ b/src/main/resources/betterend.mixins.common.json @@ -33,6 +33,7 @@ "SlimeEntityMixin", "AnvilBlockMixin", "BrewingAccessor", + "BiomeArrayMixin", "EntityMixin" ], "injectors": {