Gigantic amaranita feature

This commit is contained in:
paulevsGitch 2021-03-06 03:26:33 +03:00
parent 697d2bfe20
commit 9899492a93
3 changed files with 342 additions and 0 deletions

View file

@ -51,6 +51,7 @@ 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.trees.DragonTreeFeature;
import ru.betterend.world.features.trees.GiganticAmaranitaFeature;
import ru.betterend.world.features.trees.HelixTreeFeature;
import ru.betterend.world.features.trees.JellyshroomFeature;
import ru.betterend.world.features.trees.LacugroveFeature;
@ -70,6 +71,7 @@ public class EndFeatures {
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(), 4);
public static final EndFeature JELLYSHROOM = new EndFeature("jellyshroom", new JellyshroomFeature(), 3);
public static final EndFeature GIGANTIC_AMARANITA = new EndFeature("gigantic_amaranita", new GiganticAmaranitaFeature(), 1);
// Bushes //
public static final EndFeature PYTHADENDRON_BUSH = new EndFeature("pythadendron_bush", new BushFeature(EndBlocks.PYTHADENDRON_LEAVES, EndBlocks.PYTHADENDRON.bark), 4);

View file

@ -21,6 +21,7 @@ public class DragonGraveyardsBiome extends EndBiome {
.addFeature(EndFeatures.OBSIDIAN_PILLAR_BASEMENT)
.addFeature(EndFeatures.FALLEN_PILLAR)
.addFeature(EndFeatures.OBSIDIAN_BOULDER)
.addFeature(EndFeatures.GIGANTIC_AMARANITA)
.addFeature(EndFeatures.LARGE_AMARANITA)
.addFeature(EndFeatures.SMALL_AMARANITA)
.addFeature(EndFeatures.GLOBULAGUS)

View file

@ -0,0 +1,339 @@
package ru.betterend.world.features.trees;
import java.util.List;
import java.util.Random;
import java.util.function.Function;
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.Direction;
import net.minecraft.util.math.Direction.Axis;
import net.minecraft.util.math.Direction.AxisDirection;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.BlockPos.Mutable;
import net.minecraft.world.StructureWorldAccess;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import ru.betterend.blocks.basis.AttachedBlock;
import ru.betterend.registry.EndBlocks;
import ru.betterend.registry.EndTags;
import ru.betterend.util.BlocksHelper;
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.world.features.DefaultFeature;
public class GiganticAmaranitaFeature extends DefaultFeature {
private static final Function<BlockState, Boolean> REPLACE;
private static final Function<BlockState, Boolean> IGNORE;
private static final Function<PosInfo, BlockState> POST;
@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(5, 10, random);
List<Vector3f> spline = SplineHelper.makeSpline(0, 0, 0, 0, size, 0, 5);
SplineHelper.offsetParts(spline, random, 0.7F, 0, 0.7F);
if (!SplineHelper.canGenerate(spline, pos, world, REPLACE)) {
return false;
}
BlocksHelper.setWithoutUpdate(world, pos, AIR);
float radius = size * 0.17F;//MHelper.randRange(0.8F, 1.2F, random);
SDF function = SplineHelper.buildSDF(spline, radius, 0.2F, (bpos) -> {
return EndBlocks.AMARANITA_STEM.getDefaultState();
});
Vector3f capPos = spline.get(spline.size() - 1);
makeHead(world, pos.add(capPos.getX() + 0.5F, capPos.getY() + 1.5F ,capPos.getZ() + 0.5F), MathHelper.floor(size / 1.6F));
function.setReplaceFunction(REPLACE);
function.addPostProcess(POST);
function.fillRecursiveIgnore(world, pos, IGNORE);
for (int i = 0; i < 3; i++) {
List<Vector3f> copy = SplineHelper.copySpline(spline);
SplineHelper.offsetParts(copy, random, 0.2F, 0, 0.2F);
SplineHelper.fillSplineForce(copy, world, EndBlocks.AMARANITA_HYPHAE.getDefaultState(), pos, REPLACE);
}
return true;
}
private void makeHead(StructureWorldAccess world, BlockPos pos, int radius) {
Mutable mut = new Mutable();
if (radius < 2) {
for (int i = -1; i < 2; i++) {
mut.set(pos).move(Direction.NORTH, 2).move(Direction.EAST, i);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.set(pos).move(Direction.SOUTH, 2).move(Direction.EAST, i);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.set(pos).move(Direction.EAST, 2).move(Direction.NORTH, i);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.set(pos).move(Direction.WEST, 2).move(Direction.NORTH, i);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
}
for (int x = -1; x < 2; x++) {
for (int z = -1; z < 2; z++) {
mut.set(pos).move(x, 0, z);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN);
mut.move(Direction.DOWN);
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN);
mut.move(Direction.DOWN);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_FUR.getDefaultState().with(AttachedBlock.FACING, Direction.DOWN));
}
}
}
}
int h = radius + 1;
for (int y = 0; y < h; y++) {
mut.setY(pos.getY() + y + 1);
for (int x = -1; x < 2; x++) {
mut.setX(pos.getX() + x);
for (int z = -1; z < 2; z++) {
mut.setZ(pos.getZ() + z);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP);
}
}
}
}
mut.setY(pos.getY() + h + 1);
for (int x = -1; x < 2; x++) {
mut.setX(pos.getX() + x);
for (int z = -1; z < 2; z++) {
mut.setZ(pos.getZ() + z);
if ((x == 0 || z == 0) && world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP);
}
}
}
}
else if (radius < 4) {
pos = pos.add(-1, 0, -1);
for (int i = -2; i < 2; i++) {
mut.set(pos).move(Direction.NORTH, 2).move(Direction.WEST, i);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.set(pos).move(Direction.SOUTH, 3).move(Direction.WEST, i);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.set(pos).move(Direction.EAST, 3).move(Direction.NORTH, i);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.set(pos).move(Direction.WEST, 2).move(Direction.NORTH, i);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
}
for (int x = -1; x < 3; x++) {
for (int z = -1; z < 3; z++) {
mut.set(pos).move(x, 0, z);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN);
mut.move(Direction.DOWN);
if ((x >> 1) == 0 || (z >> 1) == 0) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN);
Axis axis = x < 0 || x > 1 ? Axis.X : Axis.Z;
int distance = axis == Axis.X ? x < 0 ? -1 : 1 : z < 0 ? -1 : 1;
BlockPos offseted = mut.offset(axis, distance);
if (world.getBlockState(offseted).getMaterial().isReplaceable()) {
Direction dir = Direction.from(axis, distance < 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE);
BlocksHelper.setWithoutUpdate(world, offseted, EndBlocks.AMARANITA_FUR.getDefaultState().with(AttachedBlock.FACING, dir));
}
mut.move(Direction.DOWN);
}
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_FUR.getDefaultState().with(AttachedBlock.FACING, Direction.DOWN));
}
}
}
}
int h = radius - 1;
for (int y = 0; y < h; y++) {
mut.setY(pos.getY() + y + 1);
for (int x = -1; x < 3; x++) {
mut.setX(pos.getX() + x);
for (int z = -1; z < 3; z++) {
mut.setZ(pos.getZ() + z);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP);
}
}
}
}
mut.setY(pos.getY() + h + 1);
for (int x = -1; x < 3; x++) {
mut.setX(pos.getX() + x);
for (int z = -1; z < 3; z++) {
mut.setZ(pos.getZ() + z);
if (((x >> 1) == 0 || (z >> 1) == 0) && world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP);
}
}
}
}
else {
for (int i = -2; i < 3; i++) {
mut.set(pos).move(Direction.NORTH, 3).move(Direction.EAST, i);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.move(Direction.UP);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.move(Direction.NORTH);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.set(pos).move(Direction.SOUTH, 3).move(Direction.EAST, i);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.move(Direction.UP);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.move(Direction.SOUTH);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.set(pos).move(Direction.EAST, 3).move(Direction.NORTH, i);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.move(Direction.UP);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.move(Direction.EAST);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.set(pos).move(Direction.WEST, 3).move(Direction.NORTH, i);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.move(Direction.UP);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
mut.move(Direction.WEST);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
}
for (int i = 0; i < 4; i++) {
mut.set(pos).move(Direction.UP).move(BlocksHelper.HORIZONTAL[i], 3).move(BlocksHelper.HORIZONTAL[(i + 1) & 3], 3);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_HYMENOPHORE);
}
}
for (int x = -2; x < 3; x++) {
for (int z = -2; z < 3; z++) {
mut.set(pos).move(x, 0, z);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN);
mut.move(Direction.DOWN);
if ((x / 2) == 0 || (z / 2) == 0) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_LANTERN);
Axis axis = x < 0 || x > 1 ? Axis.X : Axis.Z;
int distance = axis == Axis.X ? x < 0 ? -1 : 1 : z < 0 ? -1 : 1;
BlockPos offseted = mut.offset(axis, distance);
if (world.getBlockState(offseted).getMaterial().isReplaceable()) {
Direction dir = Direction.from(axis, distance < 0 ? AxisDirection.NEGATIVE : AxisDirection.POSITIVE);
BlocksHelper.setWithoutUpdate(world, offseted, EndBlocks.AMARANITA_FUR.getDefaultState().with(AttachedBlock.FACING, dir));
}
mut.move(Direction.DOWN);
}
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_FUR.getDefaultState().with(AttachedBlock.FACING, Direction.DOWN));
}
}
}
}
for (int y = 0; y < 3; y++) {
mut.setY(pos.getY() + y + 1);
for (int x = -2; x < 3; x++) {
mut.setX(pos.getX() + x);
for (int z = -2; z < 3; z++) {
mut.setZ(pos.getZ() + z);
if (world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP);
}
}
}
}
int h = radius + 1;
for (int y = 4; y < h; y++) {
mut.setY(pos.getY() + y);
for (int x = -2; x < 3; x++) {
mut.setX(pos.getX() + x);
for (int z = -2; z < 3; z++) {
mut.setZ(pos.getZ() + z);
if (y < 6) {
if (((x / 2) == 0 || (z / 2) == 0) && world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP);
}
}
else {
if ((x == 0 || z == 0) && (Math.abs(x) < 2 && Math.abs(z) < 2) && world.getBlockState(mut).getMaterial().isReplaceable()) {
BlocksHelper.setWithoutUpdate(world, mut, EndBlocks.AMARANITA_CAP);
}
}
}
}
}
}
}
static {
REPLACE = (state) -> {
if (state.isIn(EndTags.END_GROUND) || state.getMaterial().equals(Material.PLANT)) {
return true;
}
return state.getMaterial().isReplaceable();
};
IGNORE = (state) -> {
return EndBlocks.DRAGON_TREE.isTreeLog(state);
};
POST = (info) -> {
if (!info.getStateUp().isOf(EndBlocks.AMARANITA_STEM) || !info.getStateDown().isOf(EndBlocks.AMARANITA_STEM)) {
return EndBlocks.AMARANITA_HYPHAE.getDefaultState();
}
return info.getState();
};
}
}