mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-06-14 04:41:13 +00:00
Look ma, no Bukkit API in the core package
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user