mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-18 10:32:30 +00:00
Begin work on serialization, improve structure performance.
This commit is contained in:
parent
5669a0e9c4
commit
81d607b900
@ -1,63 +0,0 @@
|
||||
package com.dfsek.terra;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
|
||||
public class MaxMin implements Iterable<Integer> {
|
||||
private final int min;
|
||||
private final int max;
|
||||
public MaxMin(int min, int max) {
|
||||
this.max = max;
|
||||
this.min = min;
|
||||
}
|
||||
|
||||
public boolean isInRange(int test) {
|
||||
return test >= min && test < max;
|
||||
}
|
||||
|
||||
public int getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public int getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
public int get(Random r) {
|
||||
return r.nextInt((max-min)+1)+min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Min: " + getMin() + " Max:" + getMax();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<Integer> iterator() {
|
||||
return new MaxMinIterator(this);
|
||||
}
|
||||
private static class MaxMinIterator implements Iterator<Integer> {
|
||||
private Integer current;
|
||||
private final MaxMin m;
|
||||
|
||||
public MaxMinIterator(MaxMin m) {
|
||||
this.m = m;
|
||||
current = m.getMin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return current < m.getMax();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer next() {
|
||||
current++;
|
||||
return current - 1;
|
||||
}
|
||||
}
|
||||
}
|
95
src/main/java/com/dfsek/terra/Range.java
Normal file
95
src/main/java/com/dfsek/terra/Range.java
Normal file
@ -0,0 +1,95 @@
|
||||
package com.dfsek.terra;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
|
||||
public class Range implements Iterable<Integer> {
|
||||
private int min;
|
||||
private int max;
|
||||
public Range(int min, int max) {
|
||||
if(min > max) throw new IllegalArgumentException("Minimum must not be grater than maximum!");
|
||||
this.max = max;
|
||||
this.min = min;
|
||||
}
|
||||
|
||||
public boolean isInRange(int test) {
|
||||
return test >= min && test < max;
|
||||
}
|
||||
|
||||
public int getMax() {
|
||||
return max;
|
||||
}
|
||||
|
||||
public int getMin() {
|
||||
return min;
|
||||
}
|
||||
|
||||
public int get(Random r) {
|
||||
return r.nextInt((max-min)+1)+min;
|
||||
}
|
||||
|
||||
public Range intersects(Range other) {
|
||||
try {
|
||||
return new Range(Math.max(this.getMin(), other.getMin()), Math.min(this.getMax(), other.getMax()));
|
||||
} catch(IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Range add(int add) {
|
||||
this.min += add;
|
||||
this.max += add;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Range sub(int sub) {
|
||||
this.min -= sub;
|
||||
this.max -= sub;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Min: " + getMin() + ", Max:" + getMax();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return min * 31 + max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof Range)) return false;
|
||||
Range other = (Range) obj;
|
||||
return other.getMin() == this.getMin() && other.getMax() == this.getMax();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<Integer> iterator() {
|
||||
return new RangeIterator(this);
|
||||
}
|
||||
private static class RangeIterator implements Iterator<Integer> {
|
||||
private Integer current;
|
||||
private final Range m;
|
||||
|
||||
public RangeIterator(Range m) {
|
||||
this.m = m;
|
||||
current = m.getMin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return current < m.getMax();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer next() {
|
||||
current++;
|
||||
return current - 1;
|
||||
}
|
||||
}
|
||||
}
|
@ -180,7 +180,7 @@ public class TerraCommand implements CommandExecutor, TabExecutor {
|
||||
try {
|
||||
GaeaStructure struc = GaeaStructure.load(new File(Terra.getInstance().getDataFolder() + File.separator + "export" + File.separator + "structures", args[2] + ".tstructure"));
|
||||
if("true".equals(args[3])) struc.paste(pl.getLocation());
|
||||
//else struc.paste(pl.getLocation(), pl.getLocation().getChunk());
|
||||
else struc.paste(pl.getLocation(), pl.getLocation().getChunk());
|
||||
} catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
sender.sendMessage("Structure not found.");
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.dfsek.terra.carving;
|
||||
|
||||
import com.dfsek.terra.MaxMin;
|
||||
import com.dfsek.terra.Range;
|
||||
import com.dfsek.terra.biome.TerraBiomeGrid;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.config.genconfig.BiomeConfig;
|
||||
@ -15,12 +15,12 @@ public class UserDefinedCarver extends Carver {
|
||||
private final double[] start; // 0, 1, 2 = x, y, z.
|
||||
private final double[] mutate; // 0, 1, 2 = x, y, z. 3 = radius.
|
||||
private final double[] radiusMultiplier;
|
||||
private final MaxMin length;
|
||||
private final MaxMin radius;
|
||||
private final Range length;
|
||||
private final Range radius;
|
||||
private final int hash;
|
||||
private final int topCut;
|
||||
private final int bottomCut;
|
||||
public UserDefinedCarver(MaxMin height, MaxMin radius, MaxMin length, double[] start, double[] mutate, double[] radiusMultiplier, int hash, int topCut, int bottomCut) {
|
||||
public UserDefinedCarver(Range height, Range radius, Range length, double[] start, double[] mutate, double[] radiusMultiplier, int hash, int topCut, int bottomCut) {
|
||||
super(height.getMin(), height.getMax());
|
||||
this.radius = radius;
|
||||
this.length = length;
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.dfsek.terra.config.genconfig;
|
||||
|
||||
import com.dfsek.terra.MaxMin;
|
||||
import com.dfsek.terra.Range;
|
||||
import com.dfsek.terra.TerraTree;
|
||||
import com.dfsek.terra.config.ConfigUtil;
|
||||
import com.dfsek.terra.config.TerraConfigObject;
|
||||
@ -15,7 +15,6 @@ import org.polydev.gaea.tree.TreeType;
|
||||
import org.polydev.gaea.world.Flora;
|
||||
import org.polydev.gaea.world.FloraType;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import org.polydev.gaea.world.palette.Palette;
|
||||
import org.polydev.gaea.world.palette.RandomPalette;
|
||||
|
||||
import java.io.File;
|
||||
@ -29,8 +28,8 @@ import java.util.TreeMap;
|
||||
public class AbstractBiomeConfig extends TerraConfigObject {
|
||||
private static final Map<String, AbstractBiomeConfig> biomes = new HashMap<>();
|
||||
private String biomeID;
|
||||
private Map<OreConfig, MaxMin> ores;
|
||||
private Map<OreConfig, MaxMin> oreHeights;
|
||||
private Map<OreConfig, Range> ores;
|
||||
private Map<OreConfig, Range> oreHeights;
|
||||
private Map<CarverConfig, Integer> carvers;
|
||||
private ProbabilityCollection<Flora> flora;
|
||||
private ProbabilityCollection<Tree> trees;
|
||||
@ -39,7 +38,7 @@ public class AbstractBiomeConfig extends TerraConfigObject {
|
||||
private int treeDensity;
|
||||
private String equation;
|
||||
private int floraAttempts;
|
||||
private Map<Flora, MaxMin> floraHeights;
|
||||
private Map<Flora, Range> floraHeights;
|
||||
private TreeMap<Integer, Palette<BlockData>> paletteMap;
|
||||
private double slabThreshold;
|
||||
private Map<Material, Palette<BlockData>> slabs;
|
||||
@ -109,13 +108,13 @@ public class AbstractBiomeConfig extends TerraConfigObject {
|
||||
Bukkit.getLogger().info("[Terra] Adding " + e.getKey() + " to biome's flora list with weight " + e.getValue());
|
||||
Flora floraObj = FloraType.valueOf(e.getKey());
|
||||
flora.add(floraObj, (Integer) val.get("weight"));
|
||||
floraHeights.put(floraObj, new MaxMin((Integer) y.get("min"), (Integer) y.get("max")));
|
||||
floraHeights.put(floraObj, new Range((Integer) y.get("min"), (Integer) y.get("max")));
|
||||
} catch(IllegalArgumentException ex) {
|
||||
try {
|
||||
Bukkit.getLogger().info("[Terra] Is custom flora: true");
|
||||
Flora floraCustom = FloraConfig.fromID(e.getKey());
|
||||
flora.add(floraCustom, (Integer) val.get("weight"));
|
||||
floraHeights.put(floraCustom, new MaxMin((Integer) y.get("min"), (Integer) y.get("max")));
|
||||
floraHeights.put(floraCustom, new Range((Integer) y.get("min"), (Integer) y.get("max")));
|
||||
} catch(NullPointerException ex2) {
|
||||
throw new InvalidConfigurationException("SEVERE configuration error for flora in biome, ID " + getID() + "\n\nFlora with ID " + e.getKey() + " cannot be found!");
|
||||
}
|
||||
@ -146,8 +145,8 @@ public class AbstractBiomeConfig extends TerraConfigObject {
|
||||
ores = new HashMap<>();
|
||||
oreHeights = new HashMap<>();
|
||||
for(Map.Entry<String, Object> m : Objects.requireNonNull(getConfigurationSection("ores")).getValues(false).entrySet()) {
|
||||
ores.put(OreConfig.fromID(m.getKey()), new MaxMin(((ConfigurationSection) m.getValue()).getInt("min"), ((ConfigurationSection) m.getValue()).getInt("max")));
|
||||
oreHeights.put(OreConfig.fromID(m.getKey()), new MaxMin(((ConfigurationSection) m.getValue()).getInt("min-height"), ((ConfigurationSection) m.getValue()).getInt("max-height")));
|
||||
ores.put(OreConfig.fromID(m.getKey()), new Range(((ConfigurationSection) m.getValue()).getInt("min"), ((ConfigurationSection) m.getValue()).getInt("max")));
|
||||
oreHeights.put(OreConfig.fromID(m.getKey()), new Range(((ConfigurationSection) m.getValue()).getInt("min-height"), ((ConfigurationSection) m.getValue()).getInt("max-height")));
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,15 +189,15 @@ public class AbstractBiomeConfig extends TerraConfigObject {
|
||||
return carvers;
|
||||
}
|
||||
|
||||
public Map<OreConfig, MaxMin> getOreHeights() {
|
||||
public Map<OreConfig, Range> getOreHeights() {
|
||||
return oreHeights;
|
||||
}
|
||||
|
||||
public Map<OreConfig, MaxMin> getOres() {
|
||||
public Map<OreConfig, Range> getOres() {
|
||||
return ores;
|
||||
}
|
||||
|
||||
public Map<Flora, MaxMin> getFloraHeights() {
|
||||
public Map<Flora, Range> getFloraHeights() {
|
||||
return floraHeights;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.dfsek.terra.config.genconfig;
|
||||
|
||||
import com.dfsek.terra.MaxMin;
|
||||
import com.dfsek.terra.Range;
|
||||
import com.dfsek.terra.TerraTree;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
import com.dfsek.terra.generation.UserDefinedDecorator;
|
||||
@ -40,10 +40,10 @@ public class BiomeConfig extends TerraConfigObject {
|
||||
private UserDefinedBiome biome;
|
||||
private String biomeID;
|
||||
private String friendlyName;
|
||||
private Map<OreConfig, MaxMin> ores;
|
||||
private Map<OreConfig, MaxMin> oreHeights;
|
||||
private Map<OreConfig, Range> ores;
|
||||
private Map<OreConfig, Range> oreHeights;
|
||||
private Map<CarverConfig, Integer> carvers;
|
||||
private Map<Flora, MaxMin> floraHeights;
|
||||
private Map<Flora, Range> floraHeights;
|
||||
private String eq;
|
||||
private int floraAttempts;
|
||||
private Map<Material, Palette<BlockData>> slabs;
|
||||
@ -163,13 +163,13 @@ public class BiomeConfig extends TerraConfigObject {
|
||||
Bukkit.getLogger().info("[Terra] Adding " + e.getKey() + " to biome's flora list with weight " + e.getValue());
|
||||
Flora floraObj = FloraType.valueOf(e.getKey());
|
||||
flora.add(floraObj, (Integer) val.get("weight"));
|
||||
floraHeights.put(floraObj, new MaxMin((Integer) y.get("min"), (Integer) y.get("max")));
|
||||
floraHeights.put(floraObj, new Range((Integer) y.get("min"), (Integer) y.get("max")));
|
||||
} catch(IllegalArgumentException ex) {
|
||||
try {
|
||||
Bukkit.getLogger().info("[Terra] Is custom flora: true");
|
||||
Flora floraCustom = FloraConfig.fromID(e.getKey());
|
||||
flora.add(floraCustom, (Integer) val.get("weight"));
|
||||
floraHeights.put(floraCustom, new MaxMin((Integer) y.get("min"), (Integer) y.get("max")));
|
||||
floraHeights.put(floraCustom, new Range((Integer) y.get("min"), (Integer) y.get("max")));
|
||||
} catch(NullPointerException ex2) {
|
||||
throw new InvalidConfigurationException("SEVERE configuration error for flora in biome " + getFriendlyName() + ", ID " + getID() + "\n\nFlora with ID " + e.getKey() + " cannot be found!");
|
||||
}
|
||||
@ -221,8 +221,8 @@ public class BiomeConfig extends TerraConfigObject {
|
||||
} else if(contains("ores")) {
|
||||
ores.clear();
|
||||
for(Map.Entry<String, Object> m : Objects.requireNonNull(getConfigurationSection("ores")).getValues(false).entrySet()) {
|
||||
ores.put(OreConfig.fromID(m.getKey()), new MaxMin(((ConfigurationSection) m.getValue()).getInt("min"), ((ConfigurationSection) m.getValue()).getInt("max")));
|
||||
oreHeights.put(OreConfig.fromID(m.getKey()), new MaxMin(((ConfigurationSection) m.getValue()).getInt("min-height"), ((ConfigurationSection) m.getValue()).getInt("max-height")));
|
||||
ores.put(OreConfig.fromID(m.getKey()), new Range(((ConfigurationSection) m.getValue()).getInt("min"), ((ConfigurationSection) m.getValue()).getInt("max")));
|
||||
oreHeights.put(OreConfig.fromID(m.getKey()), new Range(((ConfigurationSection) m.getValue()).getInt("min-height"), ((ConfigurationSection) m.getValue()).getInt("max-height")));
|
||||
}
|
||||
} else {
|
||||
ores = new HashMap<>();
|
||||
@ -272,7 +272,7 @@ public class BiomeConfig extends TerraConfigObject {
|
||||
biomes.put(biomeID, this);
|
||||
}
|
||||
|
||||
public MaxMin getOreHeight(OreConfig c) {
|
||||
public Range getOreHeight(OreConfig c) {
|
||||
return oreHeights.get(c);
|
||||
}
|
||||
|
||||
@ -292,12 +292,12 @@ public class BiomeConfig extends TerraConfigObject {
|
||||
return friendlyName;
|
||||
}
|
||||
|
||||
public Map<OreConfig, MaxMin> getOres() {
|
||||
public Map<OreConfig, Range> getOres() {
|
||||
return ores;
|
||||
}
|
||||
|
||||
public MaxMin getFloraHeights(Flora f) {
|
||||
return floraHeights.computeIfAbsent(f, input -> new MaxMin(-1, -1));
|
||||
public Range getFloraHeights(Flora f) {
|
||||
return floraHeights.computeIfAbsent(f, input -> new Range(-1, -1));
|
||||
}
|
||||
|
||||
public static BiomeConfig fromBiome(UserDefinedBiome b) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.dfsek.terra.config.genconfig;
|
||||
|
||||
import com.dfsek.terra.MaxMin;
|
||||
import com.dfsek.terra.Range;
|
||||
import com.dfsek.terra.carving.UserDefinedCarver;
|
||||
import com.dfsek.terra.config.TerraConfigObject;
|
||||
import org.bukkit.Bukkit;
|
||||
@ -126,9 +126,9 @@ public class CarverConfig extends TerraConfigObject {
|
||||
double[] start = new double[] {getDouble("start.x"), getDouble("start.y"), getDouble("start.z")};
|
||||
double[] mutate = new double[] {getDouble("mutate.x"), getDouble("mutate.y"), getDouble("mutate.z"), getDouble("mutate.radius")};
|
||||
double[] radiusMultiplier = new double[] {getDouble("start.radius.multiply.x"), getDouble("start.radius.multiply.y"), getDouble("start.radius.multiply.z")};
|
||||
MaxMin length = new MaxMin(getInt("length.min"), getInt("length.max"));
|
||||
MaxMin radius = new MaxMin(getInt("start.radius.min"), getInt("start.radius.max"));
|
||||
MaxMin height = new MaxMin(getInt("start.height.min"), getInt("start.height.max"));
|
||||
Range length = new Range(getInt("length.min"), getInt("length.max"));
|
||||
Range radius = new Range(getInt("start.radius.min"), getInt("start.radius.max"));
|
||||
Range height = new Range(getInt("start.height.min"), getInt("start.height.max"));
|
||||
id = getString("id");
|
||||
if(id == null) throw new InvalidConfigurationException("No ID specified for Carver!");
|
||||
carver = new UserDefinedCarver(height, radius, length, start, mutate, radiusMultiplier, id.hashCode(), getInt("cut.top", 0), getInt("cut.bottom", 0));
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.dfsek.terra.population;
|
||||
|
||||
import com.dfsek.terra.MaxMin;
|
||||
import com.dfsek.terra.Range;
|
||||
import com.dfsek.terra.TerraProfiler;
|
||||
import com.dfsek.terra.biome.TerraBiomeGrid;
|
||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||
@ -23,7 +23,7 @@ public class OrePopulator extends GaeaBlockPopulator {
|
||||
try (ProfileFuture ignored = TerraProfiler.fromWorld(world).measure("OreTime")) {
|
||||
Location l = chunk.getBlock(8, 0, 0).getLocation();
|
||||
Biome b = TerraBiomeGrid.fromWorld(world).getBiome(l.getBlockX(), l.getBlockZ());
|
||||
for(Map.Entry<OreConfig, MaxMin> e : BiomeConfig.fromBiome((UserDefinedBiome) b).getOres().entrySet()) {
|
||||
for(Map.Entry<OreConfig, Range> e : BiomeConfig.fromBiome((UserDefinedBiome) b).getOres().entrySet()) {
|
||||
int num = e.getValue().get(random);
|
||||
for(int i = 0; i < num; i++) {
|
||||
int x = random.nextInt(16);
|
||||
|
@ -1,11 +1,12 @@
|
||||
package com.dfsek.terra.structure;
|
||||
|
||||
import com.dfsek.terra.MaxMin;
|
||||
import com.dfsek.terra.Range;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -21,7 +22,6 @@ import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class GaeaStructure implements Serializable {
|
||||
public static final long serialVersionUID = -6664585217063842035L;
|
||||
@ -49,23 +49,30 @@ public class GaeaStructure implements Serializable {
|
||||
for(int y = 0; y <= l2.getBlockY()-l1.getBlockY(); y++) {
|
||||
for(int z = 0; z <= l2.getBlockZ()-l1.getBlockZ(); z++) {
|
||||
Block b = Objects.requireNonNull(l1.getWorld()).getBlockAt(l1.clone().add(x, y, z));
|
||||
BlockState state = b.getState();
|
||||
BlockData d = b.getBlockData();
|
||||
if(d instanceof Sign) {
|
||||
boolean useState = true;
|
||||
if(state instanceof Sign) {
|
||||
Sign s = (Sign) b.getState();
|
||||
if(s.getLine(0).equals("[TERRA]")) {
|
||||
d = Bukkit.createBlockData(s.getLine(2)+s.getLine(3));
|
||||
if(s.getLine(1).equals("[CENTER]")) {
|
||||
centerX = x;
|
||||
centerZ = z;
|
||||
try {
|
||||
d = Bukkit.createBlockData(s.getLine(2) + s.getLine(3));
|
||||
useState = false;
|
||||
if(s.getLine(1).equals("[CENTER]")) {
|
||||
centerX = x;
|
||||
centerZ = z;
|
||||
}
|
||||
} catch(IllegalArgumentException e) {
|
||||
throw new InitializationException("Invalid Block Data on sign: \"" + s.getLine(2) + s.getLine(3) + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
structure[x][y][z] = new StructureContainedBlock(x, y, z, d);
|
||||
structure[x][y][z] = new StructureContainedBlock(x, y, z, useState ? state : null, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(centerX == -1 || centerZ == -1) throw new InitializationException("No structure center specified.");
|
||||
structureInfo = new GaeaStructureInfo(l2.getBlockX()-l1.getBlockX(), l2.getBlockY()-l1.getBlockY(), l2.getBlockZ()-l1.getBlockZ(), centerX, centerZ);
|
||||
if(centerX < 0 || centerZ < 0) throw new InitializationException("No structure center specified.");
|
||||
structureInfo = new GaeaStructureInfo(l2.getBlockX()-l1.getBlockX()+1, l2.getBlockY()-l1.getBlockY()+1, l2.getBlockZ()-l1.getBlockZ()+1, centerX, centerZ);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@ -74,19 +81,28 @@ public class GaeaStructure implements Serializable {
|
||||
}
|
||||
|
||||
public void paste(@NotNull Location origin) {
|
||||
for(StructureContainedBlock[][] bList2 : structure) {
|
||||
for(StructureContainedBlock[] bList1 : bList2) {
|
||||
for(StructureContainedBlock block : bList1) {
|
||||
BlockData data = block.getBlockData();
|
||||
Block worldBlock = origin.clone().add(block.getX(), block.getY(), block.getZ()).getBlock();
|
||||
if(!data.getMaterial().equals(Material.STRUCTURE_VOID)) worldBlock.setBlockData(data);
|
||||
}
|
||||
}
|
||||
this.executeForBlocksInRange(getRange(Axis.X), getRange(Axis.Y), getRange(Axis.Z), block -> pasteBlock(block, origin));
|
||||
}
|
||||
|
||||
public void paste(Location origin, Chunk chunk) {
|
||||
int xOr = (chunk.getX() << 4);
|
||||
int zOr = (chunk.getZ() << 4);
|
||||
Range intersectX = new Range(xOr, xOr+16).sub(origin.getBlockX() - structureInfo.getCenterX());
|
||||
Range intersectZ = new Range(zOr, zOr+16).sub(origin.getBlockZ() - structureInfo.getCenterZ());
|
||||
if(intersectX == null || intersectZ == null) return;
|
||||
executeForBlocksInRange(intersectX, getRange(Axis.Y), intersectZ, block -> pasteBlock(block, origin));
|
||||
}
|
||||
|
||||
private void pasteBlock(StructureContainedBlock block, Location origin) {
|
||||
BlockData data = block.getBlockData();
|
||||
Block worldBlock = origin.clone().add(block.getX()-structureInfo.getCenterX(), block.getY(), block.getZ()-structureInfo.getCenterZ()).getBlock();
|
||||
if(!data.getMaterial().equals(Material.STRUCTURE_VOID)) worldBlock.setBlockData(data);
|
||||
if(block.getState() != null) {
|
||||
block.getState().getState(worldBlock.getState()).update();
|
||||
}
|
||||
}
|
||||
|
||||
private StructureContainedBlock[][][] executeForBlocksInRange(MaxMin xM, MaxMin yM, MaxMin zM, Consumer<StructureContainedBlock> exec) {
|
||||
StructureContainedBlock[][][] temp = new StructureContainedBlock[xM.getMax()-xM.getMin()+1][yM.getMax()-yM.getMin()+1][zM.getMax()-zM.getMin()+1];
|
||||
private void executeForBlocksInRange(Range xM, Range yM, Range zM, Consumer<StructureContainedBlock> exec) {
|
||||
for(int x : xM) {
|
||||
for(int y : yM) {
|
||||
for(int z : zM) {
|
||||
@ -94,11 +110,10 @@ public class GaeaStructure implements Serializable {
|
||||
}
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
private boolean isInStructure(int x, int y, int z) {
|
||||
return x < structure.length && y < structure[0].length && z < structure[0][0].length;
|
||||
return x < structureInfo.getSizeX() && y < structureInfo.getSizeY() && z < structureInfo.getSizeZ() && x >= 0 && y >= 0 && z >= 0;
|
||||
}
|
||||
|
||||
public void save(@NotNull File f) throws IOException {
|
||||
@ -136,4 +151,20 @@ public class GaeaStructure implements Serializable {
|
||||
public UUID getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public Range getRange(Axis a) {
|
||||
switch(a) {
|
||||
case X:
|
||||
return new Range(0, structureInfo.getSizeX());
|
||||
case Y:
|
||||
return new Range(0, structureInfo.getSizeY());
|
||||
case Z:
|
||||
return new Range(0, structureInfo.getSizeZ());
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
enum Axis {
|
||||
X, Y, Z
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,31 @@
|
||||
package com.dfsek.terra.structure;
|
||||
|
||||
import com.dfsek.terra.structure.serialize.SerializableBlockData;
|
||||
import com.dfsek.terra.structure.serialize.block.SerializableBlockState;
|
||||
import com.dfsek.terra.structure.serialize.block.SerializableSign;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Sign;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.event.block.BlockDamageEvent;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class StructureContainedBlock implements Serializable {
|
||||
public static final long serialVersionUID = 6143969483382710947L;
|
||||
private final transient BlockData bl;
|
||||
private final String dataString;
|
||||
private final SerializableBlockData bl;
|
||||
private transient BlockData data;
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int z;
|
||||
public StructureContainedBlock(int x, int y, int z, BlockData block) {
|
||||
private final SerializableBlockState state;
|
||||
public StructureContainedBlock(int x, int y, int z, BlockState state, BlockData d) {
|
||||
if(state instanceof Sign) {
|
||||
this.state = new SerializableSign((org.bukkit.block.Sign) state);
|
||||
} else this.state = null;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.bl = block;
|
||||
dataString = bl.getAsString(false);
|
||||
this.bl = new SerializableBlockData(d);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
@ -36,10 +41,14 @@ public class StructureContainedBlock implements Serializable {
|
||||
}
|
||||
|
||||
public BlockData getBlockData() {
|
||||
return bl == null ? Bukkit.createBlockData(dataString) : bl;
|
||||
if(data == null) {
|
||||
data = bl.getData();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public String getDataAsString() {
|
||||
return dataString;
|
||||
|
||||
public SerializableBlockState getState() {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,17 @@
|
||||
package com.dfsek.terra.structure.serialize;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.block.data.BlockData;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SerializableBlockData implements Serializable {
|
||||
public static final long serialVersionUID = 5298928608478640008L;
|
||||
private final String data;
|
||||
public SerializableBlockData(BlockData d) {
|
||||
this.data = d.getAsString(false);
|
||||
}
|
||||
public BlockData getData() {
|
||||
return Bukkit.createBlockData(data);
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.dfsek.terra.structure.serialize;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SerializableEnchantment implements Serializable {
|
||||
public static final long serialVersionUID = 5298928608478640006L;
|
||||
private final SerializableNamespacedKey enchant;
|
||||
public SerializableEnchantment(Enchantment e) {
|
||||
enchant = new SerializableNamespacedKey(e.getKey());
|
||||
}
|
||||
public Enchantment toEnchantment() {
|
||||
return Enchantment.getByKey(enchant.getNamespacedKey());
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.dfsek.terra.structure.serialize;
|
||||
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SerializableInventory implements Serializable {
|
||||
public static final long serialVersionUID = 5298928608478640004L;
|
||||
private SerializableItemStack[] items;
|
||||
public SerializableInventory(Inventory inv) {
|
||||
items = new SerializableItemStack[inv.getSize()];
|
||||
for(int i = 0; i < inv.getSize(); i++) {
|
||||
ItemStack item = inv.getItem(i);
|
||||
if(item == null) return;
|
||||
items[i] = new SerializableItemStack(item);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package com.dfsek.terra.structure.serialize;
|
||||
|
||||
import org.bukkit.attribute.Attribute;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SerializableItemMeta implements Serializable {
|
||||
public static final long serialVersionUID = 5298928608478640009L;
|
||||
public SerializableItemMeta(ItemMeta meta) {
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.dfsek.terra.structure.serialize;
|
||||
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.enchantments.Enchantment;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SerializableItemStack implements Serializable {
|
||||
public static final long serialVersionUID = 5298928608478640005L;
|
||||
private final HashMap<SerializableEnchantment, Integer> enchantments = new HashMap<>();
|
||||
private final SerializableBlockData blockData;
|
||||
private transient ItemStack stack;
|
||||
private final SerializableItemMeta meta;
|
||||
private final int amount;
|
||||
public SerializableItemStack(ItemStack item) {
|
||||
for(Map.Entry<Enchantment, Integer> e : item.getEnchantments().entrySet()) {
|
||||
this.enchantments.put(new SerializableEnchantment(e.getKey()), e.getValue());
|
||||
}
|
||||
this.meta = new SerializableItemMeta(item.getItemMeta());
|
||||
this.blockData = new SerializableBlockData(item.getType().createBlockData());
|
||||
this.amount = item.getAmount();
|
||||
}
|
||||
public ItemStack getStack() {
|
||||
if(stack == null) {
|
||||
stack = new ItemStack(blockData.getData().getMaterial(), amount);
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.dfsek.terra.structure.serialize;
|
||||
|
||||
import org.bukkit.NamespacedKey;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SerializableNamespacedKey implements Serializable {
|
||||
public static final long serialVersionUID = 5298928608478640007L;
|
||||
private final String namespace;
|
||||
private final String key;
|
||||
public SerializableNamespacedKey(NamespacedKey key) {
|
||||
this.namespace = key.getNamespace();
|
||||
this.key = key.getKey();
|
||||
}
|
||||
public NamespacedKey getNamespacedKey() {
|
||||
return new NamespacedKey(namespace, key);
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package com.dfsek.terra.structure.serialize.block;
|
||||
|
||||
import org.bukkit.block.BlockState;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface SerializableBlockState extends Serializable {
|
||||
long serialVersionUID = 5298928608478640000L;
|
||||
BlockState getState(BlockState orig);
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package com.dfsek.terra.structure.serialize.block;
|
||||
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
public class SerializableChest implements SerializableContainer {
|
||||
long serialVersionUID = 5298928608478640003L;
|
||||
@Override
|
||||
public Inventory getInventory(Inventory orig) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getState(BlockState orig) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package com.dfsek.terra.structure.serialize.block;
|
||||
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
public interface SerializableContainer extends SerializableBlockState {
|
||||
long serialVersionUID = 5298928608478640002L;
|
||||
Inventory getInventory(Inventory orig);
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
package com.dfsek.terra.structure.serialize.block;
|
||||
|
||||
import org.bukkit.block.BlockState;
|
||||
import org.bukkit.block.Sign;
|
||||
|
||||
public class SerializableSign implements SerializableBlockState {
|
||||
public static final long serialVersionUID = 5298928608478640001L;
|
||||
private final String[] text;
|
||||
private final boolean isEditable;
|
||||
public SerializableSign(Sign orig) {
|
||||
text = orig.getLines();
|
||||
this.isEditable = orig.isEditable();
|
||||
}
|
||||
@Override
|
||||
public BlockState getState(BlockState orig) {
|
||||
if(!(orig instanceof Sign)) throw new IllegalArgumentException("Provided BlockState is not a sign.");
|
||||
Sign sign = (Sign) orig;
|
||||
for(int i = 0; i < text.length; i++) {
|
||||
sign.setLine(i, text[i]);
|
||||
}
|
||||
sign.setEditable(isEditable);
|
||||
return sign;
|
||||
}
|
||||
|
||||
public String[] getLines() {
|
||||
return text;
|
||||
}
|
||||
public String getLine(int index) {
|
||||
return text[index];
|
||||
}
|
||||
|
||||
public boolean isEditable() {
|
||||
return isEditable;
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import com.dfsek.terra.MaxMin;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class MaxMinTest {
|
||||
@Test
|
||||
public void iterator() {
|
||||
MaxMin m = new MaxMin(0, 100);
|
||||
int i = 0;
|
||||
for(int mint : m) {
|
||||
assertEquals(i, mint);
|
||||
i++;
|
||||
}
|
||||
assertEquals(100, i);
|
||||
}
|
||||
}
|
29
src/test/java/RangeTest.java
Normal file
29
src/test/java/RangeTest.java
Normal file
@ -0,0 +1,29 @@
|
||||
import com.dfsek.terra.Range;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
|
||||
public class RangeTest {
|
||||
@Test
|
||||
public void iterator() {
|
||||
Range m = new Range(0, 100);
|
||||
int i = 0;
|
||||
for(int mint : m) {
|
||||
assertEquals(i, mint);
|
||||
i++;
|
||||
}
|
||||
assertEquals(100, i);
|
||||
}
|
||||
@Test
|
||||
public void intersect() {
|
||||
Range one = new Range(10, 100);
|
||||
Range two = new Range(1, 20);
|
||||
Range intersect = one.intersects(two);
|
||||
assertEquals(20, intersect.getMax());
|
||||
assertEquals(10, intersect.getMin());
|
||||
assertEquals(one.intersects(two), two.intersects(one));
|
||||
|
||||
one = new Range(25, 50);
|
||||
assertNull(one.intersects(two));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user