Portal islands

This commit is contained in:
Aleksey 2021-04-04 14:56:18 +03:00
parent fd093318c6
commit 6630ce0cab
6 changed files with 98 additions and 65 deletions

View file

@ -29,7 +29,7 @@ import ru.betterend.world.features.HydraluxFeature;
import ru.betterend.world.features.LanceleafFeature;
import ru.betterend.world.features.MengerSpongeFeature;
import ru.betterend.world.features.NeonCactusFeature;
import ru.betterend.world.features.OverworldIslandFeature;
import ru.betterend.world.features.BiomeIslandFeature;
import ru.betterend.world.features.SilkMothNestFeature;
import ru.betterend.world.features.SingleInvertedScatterFeature;
import ru.betterend.world.features.SinglePlantFeature;
@ -179,7 +179,7 @@ public class EndFeatures {
public static final EndFeature CHARNIA_GREEN = new EndFeature("charnia_green", new CharniaFeature(EndBlocks.CHARNIA_GREEN), 10);
public static final EndFeature MENGER_SPONGE = new EndFeature("menger_sponge", new MengerSpongeFeature(5), 1);
public static final EndFeature CHARNIA_RED_RARE = new EndFeature("charnia_red_rare", new CharniaFeature(EndBlocks.CHARNIA_RED), 2);
public static final EndFeature OVERWORLD_ISLAND = EndFeature.makeFetureConfigured("overworld_island", new OverworldIslandFeature());
public static final EndFeature BIOME_ISLAND = EndFeature.makeFeatureConfigured("overworld_island", new BiomeIslandFeature());
public static final EndFeature FLAMAEA = new EndFeature("flamaea", new SinglePlantFeature(EndBlocks.FLAMAEA, 12, false, 5), 20);
// Terrain //

View file

@ -8,7 +8,6 @@ import java.util.Set;
import java.util.function.Predicate;
import com.google.common.collect.Lists;
import net.minecraft.util.BlockRotation;
import net.minecraft.world.chunk.ChunkSection;
import net.minecraft.world.chunk.WorldChunk;
import org.jetbrains.annotations.Nullable;
@ -38,6 +37,7 @@ import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.world.gen.feature.ConfiguredFeatures;
import ru.betterend.BetterEnd;
import ru.betterend.blocks.BlockProperties;
import ru.betterend.blocks.EndPortalBlock;
import ru.betterend.blocks.RunedFlavolite;
@ -158,10 +158,9 @@ public class EternalRitual {
if (active) return;
Identifier itemId = Registry.ITEM.getId(keyItem);
int portalId = EndPortals.getPortalIdByItem(itemId);
activatePortal(world, center, portalId);
doEffects((ServerWorld) world, center);
World targetWorld = getTargetWorld(portalId);
Identifier worldId = targetWorld.getRegistryKey().getValue();
try {
if (exit == null) {
initPortal(worldId, portalId);
} else {
@ -173,7 +172,15 @@ public class EternalRitual {
}
activatePortal(targetWorld, exit, portalId);
}
this.active = true;
activatePortal(world, center, portalId);
doEffects((ServerWorld) world, center);
active = true;
} catch (Exception ex) {
BetterEnd.LOGGER.error("Create End portals error.", ex);
removePortal(targetWorld, exit);
removePortal(world, center);
active = false;
}
}
private void initPortal(Identifier worldId, int portalId) {
@ -328,8 +335,8 @@ public class EternalRitual {
ConfiguredFeatures.END_ISLAND.generate(targetWorld, targetWorld.getChunkManager().getChunkGenerator(), new Random(basePos.asLong()), basePos.down());
} else if (targetWorld.getRegistryKey() == World.OVERWORLD) {
basePos.setY(targetWorld.getChunk(basePos).sampleHeightmap(Heightmap.Type.WORLD_SURFACE, basePos.getX(), basePos.getZ()) + 1);
EndFeatures.OVERWORLD_ISLAND.getFeatureConfigured().generate(targetWorld, targetWorld.getChunkManager().getChunkGenerator(), new Random(basePos.asLong()), basePos.down());
}
EndFeatures.BIOME_ISLAND.getFeatureConfigured().generate(targetWorld, targetWorld.getChunkManager().getChunkGenerator(), new Random(basePos.asLong()), basePos.down());
generatePortal(targetWorld, basePos, portalAxis, portalId);
return basePos.toImmutable();
}

View file

@ -121,11 +121,11 @@ public class BlocksHelper {
}
public static BlockState rotateHorizontal(BlockState state, BlockRotation rotation, Property<Direction> facing) {
return (BlockState) state.with(facing, rotation.rotate((Direction) state.get(facing)));
return state.with(facing, rotation.rotate(state.get(facing)));
}
public static BlockState mirrorHorizontal(BlockState state, BlockMirror mirror, Property<Direction> facing) {
return state.rotate(mirror.getRotation((Direction) state.get(facing)));
return state.rotate(mirror.getRotation(state.get(facing)));
}
public static int getLengthDown(WorldAccess world, BlockPos pos, Block block) {
@ -364,4 +364,8 @@ public class BlocksHelper {
public static Direction randomDirection(Random random) {
return DIRECTIONS[random.nextInt(6)];
}
public static boolean isFluid(BlockState blockState) {
return !blockState.getFluidState().isEmpty();
}
}

View file

@ -0,0 +1,69 @@
package ru.betterend.world.features;
import java.util.Random;
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.StructureWorldAccess;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.feature.DefaultFeatureConfig;
import net.minecraft.world.gen.surfacebuilder.SurfaceConfig;
import net.minecraft.world.gen.surfacebuilder.TernarySurfaceConfig;
import ru.betterend.noise.OpenSimplexNoise;
import ru.betterend.util.BlocksHelper;
import ru.betterend.util.sdf.SDF;
import ru.betterend.util.sdf.operator.SDFDisplacement;
import ru.betterend.util.sdf.operator.SDFTranslate;
import ru.betterend.util.sdf.primitive.SDFCappedCone;
public class BiomeIslandFeature extends DefaultFeature {
private static final Mutable CENTER = new Mutable();
private static final SDF ISLAND;
private static OpenSimplexNoise simplexNoise = new OpenSimplexNoise(412L);
private static BlockState topBlock = Blocks.GRASS_BLOCK.getDefaultState();
private static BlockState underBlock = Blocks.DIRT.getDefaultState();
@Override
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) {
Biome biome = world.getBiome(pos);
SurfaceConfig surfaceConfig = biome.getGenerationSettings().getSurfaceConfig();
BlockState topMaterial = surfaceConfig.getTopMaterial();
if (BlocksHelper.isFluid(topMaterial)) {
topBlock = ((TernarySurfaceConfig) surfaceConfig).getUnderwaterMaterial();
} else {
topBlock = topMaterial;
}
underBlock = surfaceConfig.getUnderMaterial();
simplexNoise = new OpenSimplexNoise(world.getSeed());
CENTER.set(pos);
ISLAND.fillRecursive(world, pos.down());
return true;
}
private static SDF createSDFIsland() {
SDF sdfCone = new SDFCappedCone().setRadius1(0).setRadius2(6).setHeight(4).setBlock(pos -> {
if (pos.getY() > CENTER.getY()) return AIR;
if (pos.getY() == CENTER.getY()) return topBlock;
return underBlock;
});
sdfCone = new SDFTranslate().setTranslate(0, -2, 0).setSource(sdfCone);
sdfCone = new SDFDisplacement().setFunction(pos -> {
float deltaX = Math.abs(pos.getX());
float deltaY = Math.abs(pos.getY());
float deltaZ = Math.abs(pos.getZ());
if (deltaY < 2.0f && (deltaX < 3.0f || deltaZ < 3.0F)) return 0.0f;
return (float) simplexNoise.eval(CENTER.getX() + pos.getX(),
CENTER.getY() + pos.getY(), CENTER.getZ() + pos.getZ());
}).setSource(sdfCone).setReplaceFunction(state -> BlocksHelper.isFluid(state) ||
state.getMaterial().isReplaceable());
return sdfCone;
}
static {
ISLAND = createSDFIsland();
}
}

View file

@ -114,7 +114,7 @@ public class EndFeature {
return new EndFeature(name, feature, GenerationStep.Feature.RAW_GENERATION, configured);
}
public static EndFeature makeFetureConfigured(String name, Feature<DefaultFeatureConfig> feature) {
public static EndFeature makeFeatureConfigured(String name, Feature<DefaultFeatureConfig> feature) {
ConfiguredFeature<?, ?> configured = feature.configure(FeatureConfig.DEFAULT);
return new EndFeature(name, feature, GenerationStep.Feature.RAW_GENERATION, configured);
}

View file

@ -1,47 +0,0 @@
package ru.betterend.world.features;
import java.util.Random;
import net.minecraft.block.Blocks;
import net.minecraft.util.math.BlockPos;
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.noise.OpenSimplexNoise;
import ru.betterend.util.sdf.SDF;
import ru.betterend.util.sdf.operator.SDFDisplacement;
import ru.betterend.util.sdf.operator.SDFTranslate;
import ru.betterend.util.sdf.primitive.SDFCappedCone;
public class OverworldIslandFeature extends DefaultFeature {
private static final OpenSimplexNoise NOISE = new OpenSimplexNoise(412);
private static final Mutable CENTER = new Mutable();
private static final SDF ISLAND;
@Override
public boolean generate(StructureWorldAccess world, ChunkGenerator chunkGenerator, Random random, BlockPos pos, DefaultFeatureConfig config) {
CENTER.set(pos);
ISLAND.fillRecursive(world, pos.down());
return true;
}
static {
SDF cone = new SDFCappedCone().setRadius1(0).setRadius2(6).setHeight(4).setBlock((pos) -> {
if (pos.getY() == CENTER.getY()) return Blocks.GRASS_BLOCK.getDefaultState();
if (pos.getY() == CENTER.getY() - 1) {
return Blocks.DIRT.getDefaultState();
} else if (pos.getY() == CENTER.getY() - Math.round(2.0 * Math.random())) {
return Blocks.DIRT.getDefaultState();
}
return Blocks.STONE.getDefaultState();
});
cone = new SDFTranslate().setTranslate(0, -3, 0).setSource(cone);
cone = new SDFDisplacement().setFunction((pos) -> {
return (float) NOISE.eval(CENTER.getX() + pos.getX(), CENTER.getY() + pos.getY(), CENTER.getZ() + pos.getZ());
}).setSource(cone).setReplaceFunction(state -> {
return state.isOf(Blocks.WATER) || state.getMaterial().isReplaceable();
});
ISLAND = cone;
}
}