improve how world spawn is located
This commit is contained in:
parent
d9a7afb225
commit
151fc67284
@ -163,9 +163,8 @@ public class River extends TerrainPopulator {
|
|||||||
// lerp the position's height to the riverbank height
|
// lerp the position's height to the riverbank height
|
||||||
if (cell.value > bankHeight) {
|
if (cell.value > bankHeight) {
|
||||||
cell.value = NoiseUtil.lerp(cell.value, bankHeight, valleyAlpha);
|
cell.value = NoiseUtil.lerp(cell.value, bankHeight, valleyAlpha);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean carveBanks(Cell<Terrain> cell, float banksAlpha, float bedHeight) {
|
private boolean carveBanks(Cell<Terrain> cell, float banksAlpha, float bedHeight) {
|
||||||
|
@ -63,10 +63,22 @@ public class BiomeProvider extends AbstractBiomeProvider {
|
|||||||
this.modifierManager = SetupHooks.setup(new BiomeModifierManager(context, biomeMap), context.copy());
|
this.modifierManager = SetupHooks.setup(new BiomeModifierManager(context, biomeMap), context.copy());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TerraContext getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void lookupPos(int x, int z, Cell<Terrain> cell) {
|
||||||
|
worldLookup.applyCell(cell, x, z);
|
||||||
|
}
|
||||||
|
|
||||||
public Cell<Terrain> lookupPos(int x, int z) {
|
public Cell<Terrain> lookupPos(int x, int z) {
|
||||||
return worldLookup.getCell(x, z);
|
return worldLookup.getCell(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean canSpawnAt(Cell<Terrain> cell) {
|
||||||
|
return cell.tag != context.terrain.ocean && cell.tag != context.terrain.deepOcean && cell.value > context.levels.ground;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Biome getNoiseBiome(int x, int y, int z) {
|
public Biome getNoiseBiome(int x, int y, int z) {
|
||||||
x = (x << 2);
|
x = (x << 2);
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.terraforged.mod.biome.spawn;
|
||||||
|
|
||||||
|
import com.terraforged.mod.Log;
|
||||||
|
import com.terraforged.mod.biome.provider.BiomeProvider;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.gen.feature.ConfiguredFeature;
|
||||||
|
import net.minecraft.world.gen.feature.Feature;
|
||||||
|
import net.minecraft.world.gen.feature.IFeatureConfig;
|
||||||
|
import net.minecraft.world.server.ServerWorld;
|
||||||
|
import net.minecraftforge.event.world.WorldEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
|
||||||
|
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE)
|
||||||
|
public class SpawnHandler {
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void createSpawn(WorldEvent.CreateSpawnPosition event) {
|
||||||
|
if (event.getWorld() instanceof ServerWorld) {
|
||||||
|
ServerWorld world =(ServerWorld) event.getWorld();
|
||||||
|
if (world.getChunkProvider().getChunkGenerator().getBiomeProvider() instanceof BiomeProvider) {
|
||||||
|
Log.info("Searching for world spawn position");
|
||||||
|
BiomeProvider provider = (BiomeProvider) world.getChunkProvider().getChunkGenerator().getBiomeProvider();
|
||||||
|
SpawnSearch search = new SpawnSearch(BlockPos.ZERO, provider);
|
||||||
|
BlockPos spawn = search.get();
|
||||||
|
|
||||||
|
Log.info("Setting world spawn: {}", spawn);
|
||||||
|
event.setCanceled(true);
|
||||||
|
event.getWorld().getWorldInfo().setSpawn(spawn);
|
||||||
|
|
||||||
|
if (event.getSettings().isBonusChestEnabled()) {
|
||||||
|
Log.info("Generating bonus chest");
|
||||||
|
createBonusChest(world, spawn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createBonusChest(ServerWorld world, BlockPos pos) {
|
||||||
|
ConfiguredFeature<?, ?> chest = Feature.BONUS_CHEST.withConfiguration(IFeatureConfig.NO_FEATURE_CONFIG);
|
||||||
|
chest.place(world, world.getChunkProvider().getChunkGenerator(), world.rand, pos);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package com.terraforged.mod.biome.spawn;
|
||||||
|
|
||||||
|
import com.terraforged.core.cell.Cell;
|
||||||
|
import com.terraforged.core.world.terrain.Terrain;
|
||||||
|
import com.terraforged.mod.Log;
|
||||||
|
import com.terraforged.mod.biome.provider.BiomeProvider;
|
||||||
|
import com.terraforged.mod.command.search.Search;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
public class SpawnSearch extends Search {
|
||||||
|
|
||||||
|
private final BiomeProvider biomeProvider;
|
||||||
|
private final Cell<Terrain> cell = new Cell<>();
|
||||||
|
|
||||||
|
public SpawnSearch(BlockPos center, BiomeProvider biomeProvider) {
|
||||||
|
super(center, 0, 2048);
|
||||||
|
this.biomeProvider = biomeProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSpacing() {
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(BlockPos pos) {
|
||||||
|
biomeProvider.lookupPos(pos.getX(), pos.getZ(), cell);
|
||||||
|
return biomeProvider.canSpawnAt(cell);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BlockPos success(BlockPos.Mutable pos) {
|
||||||
|
pos.setY(biomeProvider.getContext().levels.scale(cell.value));
|
||||||
|
Log.info("Found valid spawn position: {}", pos);
|
||||||
|
return super.success(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BlockPos fail(BlockPos pos) {
|
||||||
|
Log.info("Unable to find valid spawn position, defaulting x=0, z=0");
|
||||||
|
return new BlockPos(0, biomeProvider.getContext().levels.groundLevel, 0);
|
||||||
|
}
|
||||||
|
}
|
@ -41,7 +41,6 @@ import net.minecraft.command.arguments.IArgumentSerializer;
|
|||||||
import net.minecraft.network.PacketBuffer;
|
import net.minecraft.network.PacketBuffer;
|
||||||
import net.minecraft.util.text.StringTextComponent;
|
import net.minecraft.util.text.StringTextComponent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -38,6 +38,14 @@ public abstract class Search implements Supplier<BlockPos> {
|
|||||||
return 16;
|
return 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected BlockPos success(BlockPos.Mutable pos) {
|
||||||
|
return pos.toImmutable();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected BlockPos fail(BlockPos pos) {
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockPos get() {
|
public BlockPos get() {
|
||||||
int radius = maxRadius;
|
int radius = maxRadius;
|
||||||
@ -60,7 +68,7 @@ public abstract class Search implements Supplier<BlockPos> {
|
|||||||
pos.setPos(center.getX() + (x * getSpacing()), center.getY(), center.getZ() + (z * getSpacing()));
|
pos.setPos(center.getX() + (x * getSpacing()), center.getY(), center.getZ() + (z * getSpacing()));
|
||||||
if (center.distanceSq(pos) >= minRadius2) {
|
if (center.distanceSq(pos) >= minRadius2) {
|
||||||
if (test(pos)) {
|
if (test(pos)) {
|
||||||
return pos.toImmutable();
|
return success(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +83,7 @@ public abstract class Search implements Supplier<BlockPos> {
|
|||||||
z += dz;
|
z += dz;
|
||||||
}
|
}
|
||||||
|
|
||||||
return BlockPos.ZERO;
|
return fail(BlockPos.ZERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean test(BlockPos pos);
|
public abstract boolean test(BlockPos pos);
|
||||||
|
Loading…
Reference in New Issue
Block a user