Portal islands
This commit is contained in:
parent
fd093318c6
commit
6630ce0cab
6 changed files with 98 additions and 65 deletions
|
@ -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 //
|
||||
|
|
|
@ -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,22 +158,29 @@ 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();
|
||||
if (exit == null) {
|
||||
initPortal(worldId, portalId);
|
||||
} else {
|
||||
if (!worldId.equals(targetWorldId)) {
|
||||
try {
|
||||
if (exit == null) {
|
||||
initPortal(worldId, portalId);
|
||||
} else if (!checkFrame(targetWorld, exit.down())) {
|
||||
Direction.Axis portalAxis = (Direction.Axis.X == axis) ? Direction.Axis.Z : Direction.Axis.X;
|
||||
generatePortal(targetWorld, exit, portalAxis, portalId);
|
||||
} else {
|
||||
if (!worldId.equals(targetWorldId)) {
|
||||
initPortal(worldId, portalId);
|
||||
} else if (!checkFrame(targetWorld, exit.down())) {
|
||||
Direction.Axis portalAxis = (Direction.Axis.X == axis) ? Direction.Axis.Z : Direction.Axis.X;
|
||||
generatePortal(targetWorld, exit, portalAxis, portalId);
|
||||
}
|
||||
activatePortal(targetWorld, exit, portalId);
|
||||
}
|
||||
activatePortal(targetWorld, exit, portalId);
|
||||
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;
|
||||
}
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue