Look ma, no Bukkit API in the core package

This commit is contained in:
dfsek
2020-12-11 17:30:17 -07:00
parent 7ee1d2c391
commit 5bf699cba9
345 changed files with 1352 additions and 2642 deletions
@@ -0,0 +1,96 @@
package com.dfsek.terra.population;
import com.dfsek.terra.api.generic.TerraPlugin;
import com.dfsek.terra.api.generic.generator.TerraBlockPopulator;
import com.dfsek.terra.api.generic.world.Chunk;
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.MaterialData;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class CavePopulator implements TerraBlockPopulator {
private final TerraPlugin main;
private static final Map<MaterialData, BlockData> shiftStorage = new HashMap<>(); // Persist BlockData created for shifts, to avoid re-calculating each time.
public CavePopulator(TerraPlugin main) {
this.main = main;
}
@SuppressWarnings("try")
@Override
public void populate(@NotNull World world, @NotNull Random r, @NotNull Chunk chunk) {
/*
TerraWorld tw = main.getWorld(world);
WorldHandle handle = main.getWorldHandle();
try(ProfileFuture ignored = tw.getProfiler().measure("CaveTime")) {
Random random = PopulationUtil.getRandom(chunk);
if(!tw.isSafe()) return;
ConfigPack config = tw.getConfig();
for(UserDefinedCarver c : config.getCarvers()) {
CarverTemplate template = c.getConfig();
Map<Location, BlockData> shiftCandidate = new HashMap<>();
Set<Block> updateNeeded = new HashSet<>();
c.carve(chunk.getX(), chunk.getZ(), world, (v, type) -> {
Block b = chunk.getBlock(v.getBlockX(), v.getBlockY(), v.getBlockZ());
MaterialData m = handle.getType(b);
switch(type) {
case CENTER:
if(template.getInner().canReplace(m)) {
handle.setBlockData(b, template.getInner().get(v.getBlockY()).get(random), false);
if(template.getUpdate().contains(m)) updateNeeded.add(b);
if(template.getShift().containsKey(m)) shiftCandidate.put(b.getLocation(), m);
}
break;
case WALL:
if(template.getOuter().canReplace(m)) {
handle.setBlockData(b, template.getOuter().get(v.getBlockY()).get(random), false);
if(template.getUpdate().contains(m)) updateNeeded.add(b);
if(template.getShift().containsKey(m)) shiftCandidate.put(b.getLocation(), m);
}
break;
case TOP:
if(template.getTop().canReplace(m)) {
handle.setBlockData(b, template.getTop().get(v.getBlockY()).get(random), false);
if(template.getUpdate().contains(m)) updateNeeded.add(b);
if(template.getShift().containsKey(m)) shiftCandidate.put(b.getLocation(), m);
}
break;
case BOTTOM:
if(template.getBottom().canReplace(m)) {
handle.setBlockData(b, template.getBottom().get(v.getBlockY()).get(random), false);
if(template.getUpdate().contains(m)) updateNeeded.add(b);
if(template.getShift().containsKey(m)) shiftCandidate.put(b.getLocation(), m);
}
break;
}
});
for(Map.Entry<Location, Material> entry : shiftCandidate.entrySet()) {
Location l = entry.getKey();
Location mut = l.clone();
Material orig = handle.getType(l.getBlock());
do mut.subtract(0, 1, 0);
while(handle.getType(mut.getBlock()).equals(orig));
try {
if(template.getShift().get(entry.getValue()).contains(mut.getBlock().getType())) {
handle.setBlockData(mut.getBlock(), shiftStorage.computeIfAbsent(entry.getValue(), Material::createBlockData), false);
}
} catch(NullPointerException ignore) {
}
}
for(Block b : updateNeeded) {
BlockData orig = handle.getBlockData(b);
handle.setBlockData(b, AIR, false);
handle.setBlockData(b, orig, true);
}
}
}
*/
}
}
@@ -0,0 +1,60 @@
package com.dfsek.terra.population;
import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.api.gaea.generation.GenerationPhase;
import com.dfsek.terra.api.gaea.profiler.ProfileFuture;
import com.dfsek.terra.api.generic.TerraPlugin;
import com.dfsek.terra.api.generic.generator.TerraBlockPopulator;
import com.dfsek.terra.api.generic.world.Chunk;
import com.dfsek.terra.api.generic.world.World;
import com.dfsek.terra.api.generic.world.vector.Vector2;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.grid.master.TerraBiomeGrid;
import com.dfsek.terra.generation.items.flora.FloraLayer;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
/**
* Populates Flora and Trees
*/
public class FloraPopulator implements TerraBlockPopulator {
private final TerraPlugin main;
public FloraPopulator(TerraPlugin main) {
this.main = main;
}
@SuppressWarnings("try")
@Override
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) {
TerraWorld tw = main.getWorld(world);
try(ProfileFuture ignored = tw.getProfiler().measure("FloraTime")) {
if(!tw.isSafe()) return;
TerraBiomeGrid grid = tw.getGrid();
Map<Vector2, List<FloraLayer>> layers = new HashMap<>();
for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) {
UserDefinedBiome biome = (UserDefinedBiome) grid.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, GenerationPhase.POPULATE);
Vector2 l = new Vector2(x, z);
layers.put(l, biome.getConfig().getFlora());
}
}
int iter = 0;
boolean finished = false;
while(!finished) {
finished = true;
for(Map.Entry<Vector2, List<FloraLayer>> entry : layers.entrySet()) {
if(entry.getValue().size() <= iter) continue;
finished = false;
FloraLayer layer = entry.getValue().get(iter);
if(layer.getDensity() >= random.nextDouble() * 100D) layer.place(chunk, entry.getKey(), random);
}
iter++;
}
}
}
}
@@ -0,0 +1,53 @@
package com.dfsek.terra.population;
import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.api.gaea.biome.Biome;
import com.dfsek.terra.api.gaea.generation.GenerationPhase;
import com.dfsek.terra.api.gaea.math.MathUtil;
import com.dfsek.terra.api.gaea.profiler.ProfileFuture;
import com.dfsek.terra.api.gaea.util.FastRandom;
import com.dfsek.terra.api.generic.TerraPlugin;
import com.dfsek.terra.api.generic.generator.TerraBlockPopulator;
import com.dfsek.terra.api.generic.world.Chunk;
import com.dfsek.terra.api.generic.world.World;
import com.dfsek.terra.api.generic.world.vector.Vector3;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.config.templates.BiomeTemplate;
import org.jetbrains.annotations.NotNull;
import java.util.Random;
public class OrePopulator implements TerraBlockPopulator {
private final TerraPlugin main;
public OrePopulator(TerraPlugin main) {
this.main = main;
}
@SuppressWarnings("try")
@Override
public void populate(@NotNull World world, @NotNull Random r, @NotNull Chunk chunk) {
TerraWorld tw = main.getWorld(world);
try(ProfileFuture ignored = tw.getProfiler().measure("OreTime")) {
if(!tw.isSafe()) return;
for(int cx = -1; cx <= 1; cx++) {
for(int cz = -1; cz <= 1; cz++) {
Random random = new FastRandom(MathUtil.getCarverChunkSeed(chunk.getX() + cx, chunk.getZ() + cz, world.getSeed()));
int originX = ((chunk.getX() + cx) << 4);
int originZ = ((chunk.getZ() + cz) << 4);
Biome b = main.getWorld(world).getGrid().getBiome(originX + 8, originZ + 8, GenerationPhase.POPULATE);
BiomeTemplate config = ((UserDefinedBiome) b).getConfig();
int finalCx = cx;
int finalCz = cz;
config.getOreHolder().forEach((ore, oreConfig) -> {
int amount = oreConfig.getAmount().get(random);
for(int i = 0; i < amount; i++) {
Vector3 location = new Vector3(random.nextInt(16) + 16 * finalCx, oreConfig.getHeight().get(random), random.nextInt(16) + 16 * finalCz);
ore.generate(location, chunk, random);
}
});
}
}
}
}
}
@@ -0,0 +1,68 @@
package com.dfsek.terra.population;
import com.dfsek.terra.api.generic.TerraPlugin;
import com.dfsek.terra.api.generic.generator.TerraBlockPopulator;
import com.dfsek.terra.api.generic.world.Chunk;
import com.dfsek.terra.api.generic.world.World;
import org.jetbrains.annotations.NotNull;
import java.util.Random;
public class StructurePopulator implements TerraBlockPopulator {
private final TerraPlugin main;
public StructurePopulator(TerraPlugin main) {
this.main = main;
}
@SuppressWarnings("try")
@Override
public void populate(@NotNull World world, @NotNull Random r, @NotNull Chunk chunk) {
/*
TerraWorld tw = main.getWorld(world);
try(ProfileFuture ignored = tw.getProfiler().measure("StructureTime")) {
Random random = PopulationUtil.getRandom(chunk);
int cx = (chunk.getX() << 4);
int cz = (chunk.getZ() << 4);
if(!tw.isSafe()) return;
TerraBiomeGrid grid = tw.getGrid();
ConfigPack config = tw.getConfig();
structure:
for(TerraStructure conf : config.getStructures()) {
Location spawn = conf.getSpawn().getNearestSpawn(cx + 8, cz + 8, world.getSeed()).toLocation(world);
if(!((UserDefinedBiome) grid.getBiome(spawn)).getConfig().getStructures().contains(conf))
continue;
Random r2 = new FastRandom(spawn.hashCode());
Structure struc = conf.getStructures().get(r2);
Rotation rotation = Rotation.fromDegrees(r2.nextInt(4) * 90);
for(int y = conf.getSpawnStart().get(r2); y > 0; y--) {
if(!conf.getBound().isInRange(y)) continue structure;
spawn.setY(y);
if(!struc.checkSpawns(spawn, rotation, main)) continue;
double horizontal = struc.getStructureInfo().getMaxHorizontal();
if(FastMath.abs((cx + 8) - spawn.getBlockX()) <= horizontal && FastMath.abs((cz + 8) - spawn.getBlockZ()) <= horizontal) {
struc.paste(spawn, chunk, rotation, main);
for(StructureContainedInventory i : struc.getInventories()) {
try {
Vector2 lootCoords = RotationUtil.getRotatedCoords(new Vector2(i.getX() - struc.getStructureInfo().getCenterX(), i.getZ() - struc.getStructureInfo().getCenterZ()), rotation.inverse());
Location inv = spawn.clone().add(lootCoords.getX(), i.getY(), lootCoords.getZ());
if(FastMath.floorDiv(inv.getBlockX(), 16) != chunk.getX() || FastMath.floorDiv(inv.getBlockZ(), 16) != chunk.getZ())
continue;
LootTable table = conf.getLoot().get(i.getUid());
if(table == null) continue;
table.fillInventory(((BlockInventoryHolder) inv.getBlock().getState()).getInventory(), random);
} catch(ClassCastException e) {
Debug.error("Could not populate structure loot!");
Debug.stack(e);
}
}
for(Feature f : conf.getTemplate().getFeatures()) f.apply(struc, rotation, spawn, chunk); // Apply features.
break;
}
}
}
}
*/
}
}
@@ -0,0 +1,49 @@
package com.dfsek.terra.population;
import com.dfsek.terra.TerraWorld;
import com.dfsek.terra.api.gaea.generation.GenerationPhase;
import com.dfsek.terra.api.gaea.profiler.ProfileFuture;
import com.dfsek.terra.api.generic.TerraPlugin;
import com.dfsek.terra.api.generic.generator.TerraBlockPopulator;
import com.dfsek.terra.api.generic.world.Chunk;
import com.dfsek.terra.api.generic.world.World;
import com.dfsek.terra.api.generic.world.vector.Vector2;
import com.dfsek.terra.biome.UserDefinedBiome;
import com.dfsek.terra.biome.grid.master.TerraBiomeGrid;
import com.dfsek.terra.generation.items.tree.TreeLayer;
import net.jafama.FastMath;
import org.jetbrains.annotations.NotNull;
import java.util.Random;
public class TreePopulator implements TerraBlockPopulator {
private final TerraPlugin main;
public TreePopulator(TerraPlugin main) {
this.main = main;
}
private static int offset(Random r, int i) {
return FastMath.min(FastMath.max(i + r.nextInt(3) - 1, 0), 15);
}
@Override
@SuppressWarnings("try")
public void populate(@NotNull World world, @NotNull Random random, @NotNull Chunk chunk) {
TerraWorld tw = main.getWorld(world);
try(ProfileFuture ignored = tw.getProfiler().measure("TreeTime")) {
if(!tw.isSafe()) return;
TerraBiomeGrid grid = tw.getGrid();
for(int x = 0; x < 16; x += 2) {
for(int z = 0; z < 16; z += 2) {
UserDefinedBiome biome = (UserDefinedBiome) grid.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, GenerationPhase.POPULATE);
for(TreeLayer layer : biome.getConfig().getTrees()) {
if(layer.getDensity() >= random.nextDouble() * 100)
layer.place(chunk, new Vector2(offset(random, x), offset(random, z)), random);
}
}
}
}
}
}