mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-04 23:06:05 +00:00
implement check cache
This commit is contained in:
@@ -13,6 +13,7 @@ public class TerraWorld {
|
||||
private final ConfigPack config;
|
||||
private final boolean safe;
|
||||
private final TerraProfiler profiler;
|
||||
private final World world;
|
||||
|
||||
|
||||
public TerraWorld(World w, ConfigPack c, TerraPlugin main) {
|
||||
@@ -20,9 +21,14 @@ public class TerraWorld {
|
||||
profiler = new TerraProfiler(w);
|
||||
this.grid = new TerraBiomeGrid.TerraBiomeGridBuilder(w.getSeed(), c, main).build();
|
||||
this.zone = grid.getZone();
|
||||
this.world = w;
|
||||
safe = true;
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
public static boolean isTerraWorld(World w) {
|
||||
return w.getGenerator().getHandle() instanceof GeneratorWrapper;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.dfsek.terra.api.structures.script.builders.StructureFunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.structure.Rotation;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.Buffer;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.StructureBuffer;
|
||||
import com.dfsek.terra.api.structures.world.CheckCache;
|
||||
import com.dfsek.terra.registry.ScriptRegistry;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
@@ -31,7 +32,7 @@ public class StructureScript {
|
||||
private final String id;
|
||||
private final LinkedHashMap<Location, StructureBuffer> cache;
|
||||
|
||||
public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry) {
|
||||
public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry, CheckCache cache) {
|
||||
Parser parser;
|
||||
try {
|
||||
parser = new Parser(IOUtils.toString(inputStream));
|
||||
@@ -39,7 +40,7 @@ public class StructureScript {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
parser.addFunction("block", new BlockFunctionBuilder(main))
|
||||
.addFunction("check", new CheckFunctionBuilder(main))
|
||||
.addFunction("check", new CheckFunctionBuilder(main, cache))
|
||||
.addFunction("structure", new StructureFunctionBuilder(registry, main))
|
||||
.addFunction("randomInt", new RandomFunctionBuilder())
|
||||
.addFunction("recursions", new RecursionsFunctionBuilder())
|
||||
|
||||
@@ -6,20 +6,23 @@ import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
||||
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||
import com.dfsek.terra.api.structures.script.functions.CheckFunction;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import com.dfsek.terra.api.structures.world.CheckCache;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class CheckFunctionBuilder implements FunctionBuilder<CheckFunction> {
|
||||
private final TerraPlugin main;
|
||||
private final CheckCache cache;
|
||||
|
||||
public CheckFunctionBuilder(TerraPlugin main) {
|
||||
public CheckFunctionBuilder(TerraPlugin main, CheckCache cache) {
|
||||
this.main = main;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public CheckFunction build(List<Returnable<?>> argumentList, Position position) throws ParseException {
|
||||
return new CheckFunction(main, (Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), position);
|
||||
return new CheckFunction(main, (Returnable<Number>) argumentList.get(0), (Returnable<Number>) argumentList.get(1), (Returnable<Number>) argumentList.get(2), cache, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.dfsek.terra.api.structures.script.functions;
|
||||
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.api.math.vector.Location;
|
||||
import com.dfsek.terra.api.math.vector.Vector2;
|
||||
import com.dfsek.terra.api.math.vector.Vector3;
|
||||
@@ -11,8 +12,11 @@ import com.dfsek.terra.api.structures.structure.Rotation;
|
||||
import com.dfsek.terra.api.structures.structure.RotationUtil;
|
||||
import com.dfsek.terra.api.structures.structure.buffer.Buffer;
|
||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||
import com.dfsek.terra.api.structures.world.LandCheck;
|
||||
import com.dfsek.terra.api.structures.world.OceanCheck;
|
||||
import com.dfsek.terra.api.structures.world.CheckCache;
|
||||
import com.dfsek.terra.api.world.generation.GenerationPhase;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.biome.grid.master.TerraBiomeGrid;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.Random;
|
||||
@@ -21,13 +25,15 @@ public class CheckFunction implements Function<String> {
|
||||
private final TerraPlugin main;
|
||||
private final Returnable<Number> x, y, z;
|
||||
private final Position position;
|
||||
private final CheckCache cache;
|
||||
|
||||
public CheckFunction(TerraPlugin main, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, Position position) {
|
||||
public CheckFunction(TerraPlugin main, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, CheckCache cache, Position position) {
|
||||
this.main = main;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.position = position;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,11 +55,23 @@ public class CheckFunction implements Function<String> {
|
||||
}
|
||||
|
||||
private String apply(Location vector, World world) {
|
||||
if(new LandCheck(world, main).check(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()))
|
||||
return "LAND";
|
||||
if(new OceanCheck(world, main).check(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ()))
|
||||
return "OCEAN";
|
||||
return "AIR";
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
double comp = sample(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ(), world);
|
||||
|
||||
if(comp > 0) return "LAND"; // If noise val is greater than zero, location will always be land.
|
||||
|
||||
TerraBiomeGrid grid = tw.getGrid();
|
||||
UserDefinedBiome b = (UserDefinedBiome) grid.getBiome(vector.getBlockX(), vector.getBlockZ(), GenerationPhase.POPULATE);
|
||||
BiomeTemplate c = b.getConfig();
|
||||
|
||||
if(vector.getY() > c.getSeaLevel()) return "AIR"; // Above sea level
|
||||
return "OCEAN"; // Below sea level
|
||||
}
|
||||
|
||||
private double sample(int x, int y, int z, World w) {
|
||||
int cx = FastMath.floorDiv(x, 16);
|
||||
int cz = FastMath.floorDiv(z, 16);
|
||||
return cache.get(w, x, z).sample(x - (cx << 4), y, z - (cz << 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.dfsek.terra.api.structures.world;
|
||||
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.api.world.generation.GenerationPhase;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.biome.grid.master.TerraBiomeGrid;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
|
||||
public class AirCheck extends SpawnCheck {
|
||||
public AirCheck(World world, TerraPlugin main) {
|
||||
super(world, main);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(int x, int y, int z) {
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
TerraBiomeGrid g = tw.getGrid();
|
||||
UserDefinedBiome b = (UserDefinedBiome) g.getBiome(x, z, GenerationPhase.POPULATE);
|
||||
BiomeTemplate c = b.getConfig();
|
||||
if(y <= c.getSeaLevel()) return false;
|
||||
return sample(x, y, z, g) <= 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.dfsek.terra.api.structures.world;
|
||||
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.generation.math.Sampler;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CheckCache {
|
||||
private final Map<Long, Container> cache;
|
||||
private final TerraPlugin main;
|
||||
|
||||
public CheckCache(TerraPlugin main) {
|
||||
cache = new HashMap<>();
|
||||
this.main = main;
|
||||
}
|
||||
|
||||
public Sampler get(World world, int x, int z) {
|
||||
return cache.computeIfAbsent(world.getSeed(), seed -> new Container(world, new LinkedHashMap<Long, Sampler>() {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<Long, Sampler> eldest) {
|
||||
return size() > main.getTerraConfig().getCheckCache();
|
||||
}
|
||||
})).get(x, z);
|
||||
}
|
||||
|
||||
|
||||
private class Container {
|
||||
private final World world;
|
||||
private final Map<Long, Sampler> cache;
|
||||
|
||||
private Container(World world, Map<Long, Sampler> cache) {
|
||||
this.world = world;
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
public Sampler get(int x, int z) {
|
||||
int cx = FastMath.floorDiv(x, 16);
|
||||
int cz = FastMath.floorDiv(z, 16);
|
||||
long key = (((long) cx) << 32) | (cz & 0xffffffffL);
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
return cache.computeIfAbsent(key, k -> new Sampler(cx, cz, tw.getGrid(), world, 4, 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package com.dfsek.terra.api.structures.world;
|
||||
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
|
||||
public class LandCheck extends SpawnCheck {
|
||||
public LandCheck(World world, TerraPlugin main) {
|
||||
super(world, main);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(int x, int y, int z) {
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
return sample(x, y, z, tw.getGrid()) > 0;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package com.dfsek.terra.api.structures.world;
|
||||
|
||||
import com.dfsek.terra.TerraWorld;
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.api.world.generation.GenerationPhase;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.biome.grid.master.TerraBiomeGrid;
|
||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||
|
||||
public class OceanCheck extends SpawnCheck {
|
||||
public OceanCheck(World world, TerraPlugin main) {
|
||||
super(world, main);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean check(int x, int y, int z) {
|
||||
TerraWorld tw = main.getWorld(world);
|
||||
TerraBiomeGrid grid = tw.getGrid();
|
||||
UserDefinedBiome b = (UserDefinedBiome) grid.getBiome(x, z, GenerationPhase.POPULATE);
|
||||
BiomeTemplate c = b.getConfig();
|
||||
if(y > c.getSeaLevel()) return false;
|
||||
return sample(x, y, z, grid) <= 0;
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.dfsek.terra.api.structures.world;
|
||||
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.platform.world.World;
|
||||
import com.dfsek.terra.biome.grid.master.TerraBiomeGrid;
|
||||
import com.dfsek.terra.generation.math.Sampler;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class SpawnCheck {
|
||||
protected final World world;
|
||||
protected final TerraPlugin main;
|
||||
private final Map<Long, Sampler> cache;
|
||||
|
||||
protected SpawnCheck(World world, TerraPlugin main) {
|
||||
this.world = world;
|
||||
this.main = main;
|
||||
cache = new LinkedHashMap<Long, Sampler>() {
|
||||
@Override
|
||||
protected boolean removeEldestEntry(Map.Entry<Long, Sampler> eldest) {
|
||||
return size() > main.getTerraConfig().getCheckCache();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public abstract boolean check(int x, int y, int z);
|
||||
|
||||
protected double sample(int x, int y, int z, TerraBiomeGrid grid) {
|
||||
int cx = FastMath.floorDiv(x, 16);
|
||||
int cz = FastMath.floorDiv(z, 16);
|
||||
long key = (((long) cx) << 32) | (cz & 0xffffffffL);
|
||||
return cache.computeIfAbsent(key, k -> new Sampler(cx, cz, grid, world, 4, 8)).sample(x - (cx << 4), y, z - (cz << 4));
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import com.dfsek.terra.api.LoaderRegistrar;
|
||||
import com.dfsek.terra.api.loot.LootTable;
|
||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||
import com.dfsek.terra.api.structures.world.CheckCache;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.flora.Flora;
|
||||
import com.dfsek.terra.api.world.palette.Palette;
|
||||
@@ -148,8 +149,9 @@ public class ConfigPack implements LoaderRegistrar {
|
||||
abstractConfigLoader
|
||||
.registerLoader(LootTable.class, new LootTableLoader(loader, main)); // These loaders need access to the Loader instance to get files.
|
||||
|
||||
CheckCache checkCache = new CheckCache(main);
|
||||
loader.open("structures/data", ".tesf").then(streams -> streams.forEach(stream -> {
|
||||
StructureScript structureScript = new StructureScript(stream, main, scriptRegistry);
|
||||
StructureScript structureScript = new StructureScript(stream, main, scriptRegistry, checkCache);
|
||||
scriptRegistry.add(structureScript.getId(), structureScript);
|
||||
})).close();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user