Implement more stuff

This commit is contained in:
dfsek 2020-12-10 15:23:43 -07:00
parent 31361286b5
commit 7a61a2548b
14 changed files with 232 additions and 84 deletions

View File

@ -1,6 +1,7 @@
package com.dfsek.terra.api.bukkit; package com.dfsek.terra.api.bukkit;
import com.dfsek.terra.api.generic.world.Chunk; import com.dfsek.terra.api.generic.world.Chunk;
import com.dfsek.terra.api.generic.world.World;
public class BukkitChunk implements Chunk { public class BukkitChunk implements Chunk {
private final org.bukkit.Chunk delegate; private final org.bukkit.Chunk delegate;
@ -19,6 +20,11 @@ public class BukkitChunk implements Chunk {
return delegate.getZ(); return delegate.getZ();
} }
@Override
public World getWorld() {
return new BukkitWorld(delegate.getWorld());
}
@Override @Override
public org.bukkit.Chunk getHandle() { public org.bukkit.Chunk getHandle() {
return delegate; return delegate;

View File

@ -1,7 +1,13 @@
package com.dfsek.terra.api.bukkit; package com.dfsek.terra.api.bukkit;
import com.dfsek.terra.api.bukkit.generator.BukkitChunkGenerator;
import com.dfsek.terra.api.generic.generator.ChunkGenerator;
import com.dfsek.terra.api.generic.world.Chunk;
import com.dfsek.terra.api.generic.world.World; import com.dfsek.terra.api.generic.world.World;
import java.io.File;
import java.util.UUID;
public class BukkitWorld implements World { public class BukkitWorld implements World {
private final org.bukkit.World delegate; private final org.bukkit.World delegate;
@ -14,6 +20,41 @@ public class BukkitWorld implements World {
return delegate.getSeed(); return delegate.getSeed();
} }
@Override
public int getMaxHeight() {
return delegate.getMaxHeight();
}
@Override
public ChunkGenerator getGenerator() {
return new BukkitChunkGenerator(delegate.getGenerator());
}
@Override
public String getName() {
return null;
}
@Override
public UUID getUID() {
return null;
}
@Override
public boolean isChunkGenerated(int x, int z) {
return false;
}
@Override
public Chunk getChunkAt(int x, int z) {
return null;
}
@Override
public File getWorldFolder() {
return null;
}
@Override @Override
public org.bukkit.World getHandle() { public org.bukkit.World getHandle() {
return delegate; return delegate;

View File

@ -2,57 +2,60 @@ package com.dfsek.terra.api.bukkit.generator;
import com.dfsek.terra.api.bukkit.BukkitBiomeGrid; import com.dfsek.terra.api.bukkit.BukkitBiomeGrid;
import com.dfsek.terra.api.bukkit.BukkitWorld; import com.dfsek.terra.api.bukkit.BukkitWorld;
import com.dfsek.terra.api.bukkit.world.block.BukkitBlockData; import com.dfsek.terra.api.generic.generator.BlockPopulator;
import com.dfsek.terra.api.generic.world.block.BlockData; import com.dfsek.terra.api.generic.world.BiomeGrid;
import org.bukkit.World; import com.dfsek.terra.api.generic.world.World;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.stream.Collectors;
public class BukkitChunkGenerator extends ChunkGenerator { public class BukkitChunkGenerator implements com.dfsek.terra.api.generic.generator.ChunkGenerator {
private final com.dfsek.terra.api.generic.generator.ChunkGenerator delegate; private final ChunkGenerator delegate;
public BukkitChunkGenerator(com.dfsek.terra.api.generic.generator.ChunkGenerator delegate) { public BukkitChunkGenerator(ChunkGenerator delegate) {
this.delegate = delegate; this.delegate = delegate;
} }
@Override @Override
public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random random, int x, int z, @NotNull BiomeGrid biome) { public ChunkGenerator getHandle() {
BukkitWorld bukkitWorld = new BukkitWorld(world); return delegate;
BukkitChunkData data = new BukkitChunkData(createChunkData(world));
delegate.generateChunkData(bukkitWorld, random, x, z, new BukkitBiomeGrid(biome), data);
return data.getHandle();
} }
public static class BukkitChunkData implements com.dfsek.terra.api.generic.generator.ChunkGenerator.ChunkData { @Override
public boolean isParallelCapable() {
return delegate.isParallelCapable();
}
private final ChunkGenerator.ChunkData delegate; @Override
public boolean shouldGenerateCaves() {
return delegate.shouldGenerateCaves();
}
public BukkitChunkData(ChunkGenerator.ChunkData delegate) { @Override
this.delegate = delegate; public boolean shouldGenerateDecorations() {
} return delegate.shouldGenerateDecorations();
}
@Override @Override
public ChunkGenerator.ChunkData getHandle() { public boolean shouldGenerateMobs() {
return delegate; return delegate.shouldGenerateMobs();
} }
@Override @Override
public int getMaxHeight() { public boolean shouldGenerateStructures() {
return delegate.getMaxHeight(); return delegate.shouldGenerateStructures();
} }
@Override
public ChunkData generateChunkData(@NotNull World world, @NotNull Random random, int x, int z, @NotNull BiomeGrid biome, ChunkData data) {
return new BukkitChunkGeneratorWrapper.BukkitChunkData(delegate.generateChunkData(((BukkitWorld) world).getHandle(), random, x, z, ((BukkitBiomeGrid) biome).getHandle()));
}
@Override @Override
public void setBlock(int x, int y, int z, @NotNull BlockData blockData) { public List<BlockPopulator> getDefaultPopulators(World world) {
delegate.setBlock(x, y, z, ((BukkitBlockData) blockData).getHandle()); return delegate.getDefaultPopulators(((BukkitWorld) world).getHandle()).stream().map(BukkitPopulator::new).collect(Collectors.toList());
}
@Override
public @NotNull BlockData getBlockData(int x, int y, int z) {
return new BukkitBlockData(delegate.getBlockData(x, y, z));
}
} }
} }

View File

@ -0,0 +1,58 @@
package com.dfsek.terra.api.bukkit.generator;
import com.dfsek.terra.api.bukkit.BukkitBiomeGrid;
import com.dfsek.terra.api.bukkit.BukkitWorld;
import com.dfsek.terra.api.bukkit.world.block.BukkitBlockData;
import com.dfsek.terra.api.generic.world.block.BlockData;
import org.bukkit.World;
import org.bukkit.generator.ChunkGenerator;
import org.jetbrains.annotations.NotNull;
import java.util.Random;
public class BukkitChunkGeneratorWrapper extends ChunkGenerator {
private final com.dfsek.terra.api.generic.generator.ChunkGenerator delegate;
public BukkitChunkGeneratorWrapper(com.dfsek.terra.api.generic.generator.ChunkGenerator delegate) {
this.delegate = delegate;
}
@Override
public @NotNull ChunkData generateChunkData(@NotNull World world, @NotNull Random random, int x, int z, @NotNull BiomeGrid biome) {
BukkitWorld bukkitWorld = new BukkitWorld(world);
BukkitChunkData data = new BukkitChunkData(createChunkData(world));
delegate.generateChunkData(bukkitWorld, random, x, z, new BukkitBiomeGrid(biome), data);
return data.getHandle();
}
public static class BukkitChunkData implements com.dfsek.terra.api.generic.generator.ChunkGenerator.ChunkData {
private final ChunkGenerator.ChunkData delegate;
public BukkitChunkData(ChunkGenerator.ChunkData delegate) {
this.delegate = delegate;
}
@Override
public ChunkGenerator.ChunkData getHandle() {
return delegate;
}
@Override
public int getMaxHeight() {
return delegate.getMaxHeight();
}
@Override
public void setBlock(int x, int y, int z, @NotNull BlockData blockData) {
delegate.setBlock(x, y, z, ((BukkitBlockData) blockData).getHandle());
}
@Override
public @NotNull BlockData getBlockData(int x, int y, int z) {
return new BukkitBlockData(delegate.getBlockData(x, y, z));
}
}
}

View File

@ -0,0 +1,27 @@
package com.dfsek.terra.api.bukkit.generator;
import com.dfsek.terra.api.bukkit.BukkitChunk;
import com.dfsek.terra.api.bukkit.BukkitWorld;
import com.dfsek.terra.api.generic.generator.BlockPopulator;
import com.dfsek.terra.api.generic.world.Chunk;
import com.dfsek.terra.api.generic.world.World;
import java.util.Random;
public class BukkitPopulator implements BlockPopulator {
private final org.bukkit.generator.BlockPopulator handle;
public BukkitPopulator(org.bukkit.generator.BlockPopulator handle) {
this.handle = handle;
}
@Override
public void populate(World world, Random random, Chunk chunk) {
handle.populate(((BukkitWorld) world).getHandle(), random, ((BukkitChunk) chunk).getHandle());
}
@Override
public org.bukkit.generator.BlockPopulator getHandle() {
return handle;
}
}

View File

@ -1,10 +1,11 @@
package com.dfsek.terra.api.gaea; package com.dfsek.terra.api.gaea;
import org.bukkit.World;
import com.dfsek.terra.api.generic.world.World;
import java.io.File; import java.io.File;
public class Gaea { public class Gaea {
private static boolean debug; private static boolean debug;
public static File getGaeaFolder(World w) { public static File getGaeaFolder(World w) {

View File

@ -1,6 +1,7 @@
package com.dfsek.terra.api.gaea.population; package com.dfsek.terra.api.gaea.population;
import org.bukkit.Chunk;
import com.dfsek.terra.api.generic.world.Chunk;
import java.io.Serializable; import java.io.Serializable;
import java.util.UUID; import java.util.UUID;

View File

@ -6,10 +6,10 @@ import com.dfsek.terra.api.gaea.profiler.WorldProfiler;
import com.dfsek.terra.api.gaea.util.FastRandom; import com.dfsek.terra.api.gaea.util.FastRandom;
import com.dfsek.terra.api.gaea.util.GlueList; import com.dfsek.terra.api.gaea.util.GlueList;
import com.dfsek.terra.api.gaea.util.SerializationUtil; import com.dfsek.terra.api.gaea.util.SerializationUtil;
import org.bukkit.Chunk; import com.dfsek.terra.api.generic.TerraPlugin;
import org.bukkit.World; import com.dfsek.terra.api.generic.generator.BlockPopulator;
import org.bukkit.generator.BlockPopulator; import com.dfsek.terra.api.generic.world.Chunk;
import org.bukkit.plugin.java.JavaPlugin; import com.dfsek.terra.api.generic.world.World;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.File; import java.io.File;
@ -18,18 +18,18 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
public class PopulationManager extends BlockPopulator { public class PopulationManager implements BlockPopulator {
private final List<GaeaBlockPopulator> attachedPopulators = new GlueList<>(); private final List<BlockPopulator> attachedPopulators = new GlueList<>();
private final HashSet<ChunkCoordinate> needsPop = new HashSet<>(); private final HashSet<ChunkCoordinate> needsPop = new HashSet<>();
private final JavaPlugin main; private final TerraPlugin main;
private final Object popLock = new Object(); private final Object popLock = new Object();
private WorldProfiler profiler; private WorldProfiler profiler;
public PopulationManager(JavaPlugin main) { public PopulationManager(TerraPlugin main) {
this.main = main; this.main = main;
} }
public void attach(GaeaBlockPopulator populator) { public void attach(BlockPopulator populator) {
this.attachedPopulators.add(populator); this.attachedPopulators.add(populator);
} }
@ -85,7 +85,7 @@ public class PopulationManager extends BlockPopulator {
long zRand = (random.nextLong() / 2L << 1L) + 1L; long zRand = (random.nextLong() / 2L << 1L) + 1L;
random.setSeed((long) x * xRand + (long) z * zRand ^ w.getSeed()); random.setSeed((long) x * xRand + (long) z * zRand ^ w.getSeed());
Chunk currentChunk = w.getChunkAt(x, z); Chunk currentChunk = w.getChunkAt(x, z);
for(GaeaBlockPopulator r : attachedPopulators) { for(BlockPopulator r : attachedPopulators) {
r.populate(w, random, currentChunk); r.populate(w, random, currentChunk);
} }
needsPop.remove(c); needsPop.remove(c);

View File

@ -4,4 +4,6 @@ import com.dfsek.terra.api.generic.world.WorldHandle;
public interface TerraPlugin { public interface TerraPlugin {
WorldHandle getHandle(); WorldHandle getHandle();
boolean isEnabled();
} }

View File

@ -1,10 +1,11 @@
package com.dfsek.terra.api.generic.generator; package com.dfsek.terra.api.generic.generator;
import com.dfsek.terra.api.generic.Handle;
import com.dfsek.terra.api.generic.world.Chunk; import com.dfsek.terra.api.generic.world.Chunk;
import com.dfsek.terra.api.generic.world.World; import com.dfsek.terra.api.generic.world.World;
import java.util.Random; import java.util.Random;
public interface BlockPopulator { public interface BlockPopulator extends Handle {
void populate(World world, Random random, Chunk chunk); void populate(World world, Random random, Chunk chunk);
} }

View File

@ -1,5 +1,6 @@
package com.dfsek.terra.api.generic.generator; package com.dfsek.terra.api.generic.generator;
import com.dfsek.terra.api.generic.Handle;
import com.dfsek.terra.api.generic.world.BiomeGrid; import com.dfsek.terra.api.generic.world.BiomeGrid;
import com.dfsek.terra.api.generic.world.World; import com.dfsek.terra.api.generic.world.World;
import com.dfsek.terra.api.generic.world.block.BlockData; import com.dfsek.terra.api.generic.world.block.BlockData;
@ -8,7 +9,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
public interface ChunkGenerator { public interface ChunkGenerator extends Handle {
boolean isParallelCapable(); boolean isParallelCapable();
boolean shouldGenerateCaves(); boolean shouldGenerateCaves();
@ -19,7 +20,7 @@ public interface ChunkGenerator {
boolean shouldGenerateStructures(); boolean shouldGenerateStructures();
void generateChunkData(@NotNull World world, @NotNull Random random, int x, int z, @NotNull BiomeGrid biome, ChunkData data); ChunkData generateChunkData(@NotNull World world, @NotNull Random random, int x, int z, @NotNull BiomeGrid biome, ChunkData data);
List<BlockPopulator> getDefaultPopulators(World world); List<BlockPopulator> getDefaultPopulators(World world);

View File

@ -6,4 +6,6 @@ public interface Chunk extends Handle {
int getX(); int getX();
int getZ(); int getZ();
World getWorld();
} }

View File

@ -1,9 +1,25 @@
package com.dfsek.terra.api.generic.world; package com.dfsek.terra.api.generic.world;
import com.dfsek.terra.api.generic.Handle; import com.dfsek.terra.api.generic.Handle;
import com.dfsek.terra.api.generic.generator.ChunkGenerator;
import java.io.File;
import java.util.UUID;
public interface World extends Handle { public interface World extends Handle {
long getSeed(); long getSeed();
int getMaxHeight(); int getMaxHeight();
ChunkGenerator getGenerator();
String getName();
UUID getUID();
boolean isChunkGenerated(int x, int z);
Chunk getChunkAt(int x, int z);
File getWorldFolder();
} }

View File

@ -4,7 +4,6 @@ import com.dfsek.terra.Terra;
import com.dfsek.terra.TerraWorld; import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.api.gaea.biome.Biome; import com.dfsek.terra.api.gaea.biome.Biome;
import com.dfsek.terra.api.gaea.generation.GenerationPhase; import com.dfsek.terra.api.gaea.generation.GenerationPhase;
import com.dfsek.terra.api.gaea.generation.GenerationPopulator;
import com.dfsek.terra.api.gaea.math.ChunkInterpolator3; import com.dfsek.terra.api.gaea.math.ChunkInterpolator3;
import com.dfsek.terra.api.gaea.population.PopulationManager; import com.dfsek.terra.api.gaea.population.PopulationManager;
import com.dfsek.terra.api.gaea.profiler.ProfileFuture; import com.dfsek.terra.api.gaea.profiler.ProfileFuture;
@ -13,6 +12,7 @@ import com.dfsek.terra.api.gaea.world.palette.Palette;
import com.dfsek.terra.api.generic.generator.BlockPopulator; import com.dfsek.terra.api.generic.generator.BlockPopulator;
import com.dfsek.terra.api.generic.generator.ChunkGenerator; import com.dfsek.terra.api.generic.generator.ChunkGenerator;
import com.dfsek.terra.api.generic.world.BiomeGrid; import com.dfsek.terra.api.generic.world.BiomeGrid;
import com.dfsek.terra.api.generic.world.Chunk;
import com.dfsek.terra.api.generic.world.World; import com.dfsek.terra.api.generic.world.World;
import com.dfsek.terra.api.generic.world.block.BlockData; import com.dfsek.terra.api.generic.world.block.BlockData;
import com.dfsek.terra.api.generic.world.vector.Vector3; import com.dfsek.terra.api.generic.world.vector.Vector3;
@ -21,9 +21,6 @@ import com.dfsek.terra.config.base.ConfigPack;
import com.dfsek.terra.config.lang.LangUtil; import com.dfsek.terra.config.lang.LangUtil;
import com.dfsek.terra.config.templates.BiomeTemplate; import com.dfsek.terra.config.templates.BiomeTemplate;
import com.dfsek.terra.debug.Debug; import com.dfsek.terra.debug.Debug;
import com.dfsek.terra.population.FloraPopulator;
import com.dfsek.terra.population.OrePopulator;
import com.dfsek.terra.population.TreePopulator;
import com.dfsek.terra.util.PaletteUtil; import com.dfsek.terra.util.PaletteUtil;
import com.dfsek.terra.util.SlabUtil; import com.dfsek.terra.util.SlabUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -38,7 +35,7 @@ import java.util.Random;
import java.util.logging.Level; import java.util.logging.Level;
public class ChunkGeneratorImpl implements ChunkGenerator { public class ChunkGeneratorImpl implements ChunkGenerator {
private static final Map<org.bukkit.World, PopulationManager> popMap = new HashMap<>(); private static final Map<World, PopulationManager> popMap = new HashMap<>();
private final PopulationManager popMan; private final PopulationManager popMan;
private final ConfigPack configPack; private final ConfigPack configPack;
private final Terra main; private final Terra main;
@ -48,13 +45,13 @@ public class ChunkGeneratorImpl implements ChunkGenerator {
popMan = new PopulationManager(main); popMan = new PopulationManager(main);
this.configPack = c; this.configPack = c;
this.main = main; this.main = main;
popMan.attach(new OrePopulator(main)); //popMan.attach(new OrePopulator(main));
popMan.attach(new TreePopulator(main)); //popMan.attach(new TreePopulator(main));
popMan.attach(new FloraPopulator(main)); //popMan.attach(new FloraPopulator(main));
} }
public static synchronized void saveAll() { public static synchronized void saveAll() {
for(Map.Entry<org.bukkit.World, PopulationManager> e : popMap.entrySet()) { for(Map.Entry<World, PopulationManager> e : popMap.entrySet()) {
try { try {
e.getValue().saveBlocks(e.getKey()); e.getValue().saveBlocks(e.getKey());
Debug.info("Saved data for world " + e.getKey().getName()); Debug.info("Saved data for world " + e.getKey().getName());
@ -65,7 +62,7 @@ public class ChunkGeneratorImpl implements ChunkGenerator {
} }
public static synchronized void fixChunk(Chunk c) { public static synchronized void fixChunk(Chunk c) {
if(!(c.getWorld().getGenerator() instanceof TerraChunkGenerator)) throw new IllegalArgumentException(); if(!(c.getWorld().getGenerator() instanceof ChunkGeneratorImpl)) throw new IllegalArgumentException();
popMap.get(c.getWorld()).checkNeighbors(c.getX(), c.getZ(), c.getWorld()); popMap.get(c.getWorld()).checkNeighbors(c.getX(), c.getZ(), c.getWorld());
} }
@ -95,22 +92,22 @@ public class ChunkGeneratorImpl implements ChunkGenerator {
} }
@Override @Override
public void generateChunkData(@NotNull World world, @NotNull Random random, int x, int z, @NotNull BiomeGrid biome, ChunkData chunk) { public ChunkData generateChunkData(@NotNull World world, @NotNull Random random, int chunkX, int chunkZ, @NotNull BiomeGrid biome, ChunkData chunk) {
TerraWorld tw = main.getWorld(world); TerraWorld tw = main.getWorld(world);
com.dfsek.terra.api.gaea.biome.BiomeGrid grid = tw.getGrid();
try(ProfileFuture ignore = tw.getProfiler().measure("TotalChunkGenTime")) { try(ProfileFuture ignore = tw.getProfiler().measure("TotalChunkGenTime")) {
ChunkInterpolator3 interp; ChunkInterpolator3 interp;
try(ProfileFuture ignored = tw.getProfiler().measure("ChunkBaseGenTime")) { try(ProfileFuture ignored = tw.getProfiler().measure("ChunkBaseGenTime")) {
interp = new ChunkInterpolator3(world, x, z, tw.getGrid()); interp = new ChunkInterpolator3(world, chunkX, chunkZ, tw.getGrid());
if(needsLoad) load(world); // Load population data for world. if(needsLoad) load(world); // Load population data for world.
if(!tw.isSafe()) return; if(!tw.isSafe()) return chunk;
int xOrig = (x << 4); int xOrig = (chunkX << 4);
int zOrig = (z << 4); int zOrig = (chunkZ << 4);
com.dfsek.terra.api.gaea.biome.BiomeGrid grid = tw.getGrid();
ElevationInterpolator elevationInterpolator; ElevationInterpolator elevationInterpolator;
try(ProfileFuture ignored1 = tw.getProfiler().measure("ElevationTime")) { try(ProfileFuture ignored1 = tw.getProfiler().measure("ElevationTime")) {
elevationInterpolator = new ElevationInterpolator(x, z, tw.getGrid()); elevationInterpolator = new ElevationInterpolator(chunkX, chunkZ, tw.getGrid());
} }
Sampler sampler = new Sampler(interp, elevationInterpolator); Sampler sampler = new Sampler(interp, elevationInterpolator);
@ -158,25 +155,17 @@ public class ChunkGeneratorImpl implements ChunkGenerator {
} }
} }
} }
try(ProfileFuture ignored = measure("BiomeApplyTime")) { int xOrig = (chunkX << 4);
com.dfsek.terra.api.gaea.biome.BiomeGrid grid = getBiomeGrid(world); int zOrig = (chunkZ << 4);
int xOrig = (chunkX << 4); for(int x = 0; x < 4; x++) {
int zOrig = (chunkZ << 4); for(byte z = 0; z < 4; z++) {
for(byte x = 0; x < 4; x++) { int cx = xOrig + (x << 2);
for(byte z = 0; z < 4; z++) { int cz = zOrig + (z << 2);
int cx = xOrig + (x << 2); Biome b = grid.getBiome(cx, cz, GenerationPhase.PALETTE_APPLY);
int cz = zOrig + (z << 2); biome.setBiome(x << 2, z << 2, b.getVanillaBiome());
Biome b = grid.getBiome(cx, cz, GenerationPhase.PALETTE_APPLY);
biome.setBiome(x << 2, z << 2, b.getVanillaBiome());
}
} }
} }
for(GenerationPopulator g : getGenerationPopulators(world)) {
g.populate(world, chunk, random, chunkX, chunkZ, interp);
}
} }
return chunk; return chunk;
} }
@ -189,7 +178,7 @@ public class ChunkGeneratorImpl implements ChunkGenerator {
popMan.attachProfiler(p); popMan.attachProfiler(p);
} }
private void load(org.bukkit.World w) { private void load(World w) {
try { try {
popMan.loadBlocks(w); popMan.loadBlocks(w);
} catch(FileNotFoundException e) { } catch(FileNotFoundException e) {