mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-10-26 14:00:14 +00:00
Improve ore performance by caching chunks
This commit is contained in:
1 parent
ef16143565
commit
6480fb0bb6
3 files changed
+51
-7
No files matched your search
@@ -3,11 +3,13 @@ package com.dfsek.terra.command;
|
|||||||
import com.dfsek.terra.TerraWorld;
|
import com.dfsek.terra.TerraWorld;
|
||||||
import com.dfsek.terra.config.genconfig.OreConfig;
|
import com.dfsek.terra.config.genconfig.OreConfig;
|
||||||
import com.dfsek.terra.config.lang.LangUtil;
|
import com.dfsek.terra.config.lang.LangUtil;
|
||||||
|
import org.bukkit.Location;
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.command.Command;
|
import org.bukkit.command.Command;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.polydev.gaea.command.WorldCommand;
|
import org.polydev.gaea.command.WorldCommand;
|
||||||
|
|
||||||
@@ -33,7 +35,8 @@ public class OreCommand extends WorldCommand {
|
|||||||
LangUtil.send("command.ore.out-of-range", sender);
|
LangUtil.send("command.ore.out-of-range", sender);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ore.doVein(bl.getLocation(), new Random());
|
Vector source = new Vector(Math.floorMod(bl.getX(), 16), bl.getY(), Math.floorMod(bl.getZ(), 16));
|
||||||
|
ore.doVein(source, bl.getChunk(), new Random());
|
||||||
} else {
|
} else {
|
||||||
LangUtil.send("command.ore.main-menu", sender);
|
LangUtil.send("command.ore.main-menu", sender);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,15 +5,20 @@ import com.dfsek.terra.config.base.ConfigUtil;
|
|||||||
import com.dfsek.terra.config.TerraConfig;
|
import com.dfsek.terra.config.TerraConfig;
|
||||||
import com.dfsek.terra.config.exception.ConfigException;
|
import com.dfsek.terra.config.exception.ConfigException;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.data.BlockData;
|
import org.bukkit.block.data.BlockData;
|
||||||
import org.bukkit.configuration.InvalidConfigurationException;
|
import org.bukkit.configuration.InvalidConfigurationException;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
import org.polydev.gaea.math.FastNoise;
|
import org.polydev.gaea.math.FastNoise;
|
||||||
|
import org.polydev.gaea.population.ChunkCoordinate;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@@ -26,6 +31,7 @@ public class OreConfig extends TerraConfig {
|
|||||||
private final double deformFrequency;
|
private final double deformFrequency;
|
||||||
private final String id;
|
private final String id;
|
||||||
private final boolean update;
|
private final boolean update;
|
||||||
|
private final boolean crossChunks;
|
||||||
Set<Material> replaceable;
|
Set<Material> replaceable;
|
||||||
public OreConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException {
|
public OreConfig(File file, ConfigPack config) throws IOException, InvalidConfigurationException {
|
||||||
super(file, config);
|
super(file, config);
|
||||||
@@ -39,6 +45,7 @@ public class OreConfig extends TerraConfig {
|
|||||||
deform = getDouble("deform", 0.75);
|
deform = getDouble("deform", 0.75);
|
||||||
deformFrequency = getDouble("deform-frequency", 0.1);
|
deformFrequency = getDouble("deform-frequency", 0.1);
|
||||||
update = getBoolean("update", false);
|
update = getBoolean("update", false);
|
||||||
|
crossChunks = getBoolean("cross-chunks", true);
|
||||||
|
|
||||||
replaceable = ConfigUtil.toBlockData(getStringList("replace"), "replaceable", getID());
|
replaceable = ConfigUtil.toBlockData(getStringList("replace"), "replaceable", getID());
|
||||||
|
|
||||||
@@ -52,7 +59,31 @@ public class OreConfig extends TerraConfig {
|
|||||||
private int randomInRange(Random r) {
|
private int randomInRange(Random r) {
|
||||||
return r.nextInt(max-min+1)+min;
|
return r.nextInt(max-min+1)+min;
|
||||||
}
|
}
|
||||||
public void doVein(Location l, Random r) {
|
public void doVein(Vector l, Chunk chunk, Random r) {
|
||||||
|
FastNoise ore = new FastNoise(r.nextInt());
|
||||||
|
ore.setNoiseType(FastNoise.NoiseType.SimplexFractal);
|
||||||
|
ore.setFrequency((float) deformFrequency);
|
||||||
|
int rad = randomInRange(r);
|
||||||
|
Map<ChunkCoordinate, Chunk> chunks = new HashMap<>(); // Cache chunks to prevent re-loading chunks every time one is needed.
|
||||||
|
chunks.put(new ChunkCoordinate(chunk), chunk);
|
||||||
|
Vector orig = new Vector(l.getBlockX() + (chunk.getX() << 4), l.getBlockY(), l.getBlockZ() + (chunk.getZ() << 4));
|
||||||
|
for(int x = -rad; x <= rad; x++) {
|
||||||
|
for(int y = -rad; y <= rad; y++) {
|
||||||
|
for(int z = -rad; z <= rad; z++) {
|
||||||
|
Vector oreLoc = orig.clone().add(new Vector(x, y, z));
|
||||||
|
Vector source = l.clone().add(new Vector(x, y, z));
|
||||||
|
if(oreLoc.getBlockY() > 255 || oreLoc.getBlockY() < 0) continue;
|
||||||
|
if(source.distance(l) < (rad + 0.5) * ((ore.getSimplexFractal(x, y, z)+1)*deform)) {
|
||||||
|
ChunkCoordinate coord = new ChunkCoordinate(Math.floorDiv(oreLoc.getBlockX(), 16), Math.floorDiv(oreLoc.getBlockZ(), 16), chunk.getWorld().getUID());
|
||||||
|
Block b = chunks.computeIfAbsent(coord, k -> chunk.getWorld().getChunkAt(oreLoc.toLocation(chunk.getWorld())))
|
||||||
|
.getBlock(Math.floorMod(source.getBlockX(), 16), source.getBlockY(), Math.floorMod(source.getBlockZ(), 16));
|
||||||
|
if(replaceable.contains(b.getType()) && b.getLocation().getY() >= 0) b.setBlockData(oreData, update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void doVeinSingle(Vector l, Chunk chunk, Random r) {
|
||||||
FastNoise ore = new FastNoise(r.nextInt());
|
FastNoise ore = new FastNoise(r.nextInt());
|
||||||
ore.setNoiseType(FastNoise.NoiseType.SimplexFractal);
|
ore.setNoiseType(FastNoise.NoiseType.SimplexFractal);
|
||||||
ore.setFrequency((float) deformFrequency);
|
ore.setFrequency((float) deformFrequency);
|
||||||
@@ -60,8 +91,10 @@ public class OreConfig extends TerraConfig {
|
|||||||
for(int x = -rad; x <= rad; x++) {
|
for(int x = -rad; x <= rad; x++) {
|
||||||
for(int y = -rad; y <= rad; y++) {
|
for(int y = -rad; y <= rad; y++) {
|
||||||
for(int z = -rad; z <= rad; z++) {
|
for(int z = -rad; z <= rad; z++) {
|
||||||
if(l.clone().add(x, y, z).distance(l) < (rad + 0.5) * ((ore.getSimplexFractal(x, y, z)+1)*deform)) {
|
Vector oreLoc = l.clone().add(new Vector(x, y, z));
|
||||||
Block b = l.clone().add(x, y, z).getBlock();
|
if(oreLoc.getBlockX() > 15 || oreLoc.getBlockZ() > 15 || oreLoc.getBlockY() > 255 || oreLoc.getBlockX() < 0 || oreLoc.getBlockZ() < 0 || oreLoc.getBlockY() < 0) continue;
|
||||||
|
if(oreLoc.distance(l) < (rad + 0.5) * ((ore.getSimplexFractal(x, y, z)+1)*deform)) {
|
||||||
|
Block b = chunk.getBlock(oreLoc.getBlockX(), oreLoc.getBlockY(), oreLoc.getBlockZ());
|
||||||
if(replaceable.contains(b.getType()) && b.getLocation().getY() >= 0) b.setBlockData(oreData, update);
|
if(replaceable.contains(b.getType()) && b.getLocation().getY() >= 0) b.setBlockData(oreData, update);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,4 +110,8 @@ public class OreConfig extends TerraConfig {
|
|||||||
public String getID() {
|
public String getID() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean crossChunks() {
|
||||||
|
return crossChunks;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,6 +2,8 @@ package com.dfsek.terra.population;
|
|||||||
|
|
||||||
import com.dfsek.terra.TerraWorld;
|
import com.dfsek.terra.TerraWorld;
|
||||||
import com.dfsek.terra.config.base.ConfigPack;
|
import com.dfsek.terra.config.base.ConfigPack;
|
||||||
|
import com.dfsek.terra.config.genconfig.biome.BiomeOreConfig;
|
||||||
|
import org.bukkit.util.Vector;
|
||||||
import org.polydev.gaea.math.Range;
|
import org.polydev.gaea.math.Range;
|
||||||
import com.dfsek.terra.TerraProfiler;
|
import com.dfsek.terra.TerraProfiler;
|
||||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||||
@@ -25,13 +27,15 @@ public class OrePopulator extends GaeaBlockPopulator {
|
|||||||
if(!tw.isSafe()) return;
|
if(!tw.isSafe()) return;
|
||||||
ConfigPack config = tw.getConfig();
|
ConfigPack config = tw.getConfig();
|
||||||
Biome b = TerraWorld.getWorld(world).getGrid().getBiome((chunk.getX() << 4)+8, (chunk.getZ() << 4) + 8, GenerationPhase.POPULATE);
|
Biome b = TerraWorld.getWorld(world).getGrid().getBiome((chunk.getX() << 4)+8, (chunk.getZ() << 4) + 8, GenerationPhase.POPULATE);
|
||||||
for(Map.Entry<OreConfig, Range> e : config.getBiome((UserDefinedBiome) b).getOres().getOres().entrySet()) {
|
BiomeOreConfig ores = config.getBiome((UserDefinedBiome) b).getOres();
|
||||||
|
for(Map.Entry<OreConfig, Range> e : ores.getOres().entrySet()) {
|
||||||
int num = e.getValue().get(random);
|
int num = e.getValue().get(random);
|
||||||
for(int i = 0; i < num; i++) {
|
for(int i = 0; i < num; i++) {
|
||||||
int x = random.nextInt(16);
|
int x = random.nextInt(16);
|
||||||
int z = random.nextInt(16);
|
int z = random.nextInt(16);
|
||||||
int y = config.getBiome((UserDefinedBiome) b).getOres().getOreHeights().get(e.getKey()).get(random);
|
int y = ores.getOreHeights().get(e.getKey()).get(random);
|
||||||
e.getKey().doVein(chunk.getBlock(x, y, z).getLocation(), random);
|
if(e.getKey().crossChunks()) e.getKey().doVein(new Vector(x, y, z), chunk, random);
|
||||||
|
else e.getKey().doVeinSingle(new Vector(x, y, z), chunk, random);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user