Plot analysis (#2239)

* Start to fix (and may have fixed) plot analysis with block buxkets and 1.13

* Standard deviation ought also be multiplied by 100, and only obtain the BlockBucket array once

* Add schematics to Plot Analysis
Add generateBlockBucketChunk method to SingleWorldGenerator
This commit is contained in:
dordsor21 2019-01-17 01:04:00 +00:00 committed by GitHub
parent 0817d7de5a
commit 223064567f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 377 additions and 251 deletions

View File

@ -4,6 +4,7 @@ import com.github.intellectualsites.plotsquared.bukkit.util.BukkitUtil;
import com.github.intellectualsites.plotsquared.bukkit.util.block.GenChunk; import com.github.intellectualsites.plotsquared.bukkit.util.block.GenChunk;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.generator.GeneratorWrapper; import com.github.intellectualsites.plotsquared.plot.generator.GeneratorWrapper;
import com.github.intellectualsites.plotsquared.plot.generator.HybridPlotWorld;
import com.github.intellectualsites.plotsquared.plot.generator.IndependentPlotGenerator; import com.github.intellectualsites.plotsquared.plot.generator.IndependentPlotGenerator;
import com.github.intellectualsites.plotsquared.plot.object.*; import com.github.intellectualsites.plotsquared.plot.object.*;
import com.github.intellectualsites.plotsquared.plot.object.worlds.SingleWorldGenerator; import com.github.intellectualsites.plotsquared.plot.object.worlds.SingleWorldGenerator;
@ -28,7 +29,6 @@ public class BukkitPlotGenerator extends ChunkGenerator
private final IndependentPlotGenerator plotGenerator; private final IndependentPlotGenerator plotGenerator;
private final ChunkGenerator platformGenerator; private final ChunkGenerator platformGenerator;
private final boolean full; private final boolean full;
private final HashMap<ChunkLoc, byte[][]> dataMap = new HashMap<>();
private List<BlockPopulator> populators; private List<BlockPopulator> populators;
private boolean loaded = false; private boolean loaded = false;
@ -89,6 +89,30 @@ public class BukkitPlotGenerator extends ChunkGenerator
.getNewPlotArea(world, id, min, max); .getNewPlotArea(world, id, min, max);
} }
@Override public BlockBucket[][] generateBlockBucketChunk(PlotArea settings) {
BlockBucket[][] blockBuckets = new BlockBucket[16][];
HybridPlotWorld hpw = (HybridPlotWorld) settings;
// Bedrock
if (hpw.PLOT_BEDROCK) {
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
blockBuckets[0][(z << 4) | x] =
BlockBucket.withSingle(PlotBlock.get("bedrock"));
}
}
}
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
for (int y = 1; y < hpw.PLOT_HEIGHT; y++) {
blockBuckets[y >> 4][((y & 0xF) << 8) | (z << 4) | x] = hpw.MAIN_BLOCK;
}
blockBuckets[hpw.PLOT_HEIGHT >> 4][((hpw.PLOT_HEIGHT & 0xF) << 8) | (z << 4)
| x] = hpw.MAIN_BLOCK;
}
}
return blockBuckets;
}
@Override @Override
public void generateChunk(final ScopedLocalBlockQueue result, PlotArea settings) { public void generateChunk(final ScopedLocalBlockQueue result, PlotArea settings) {
World w = BukkitUtil.getWorld(world); World w = BukkitUtil.getWorld(world);

View File

@ -1,9 +1,26 @@
package com.github.intellectualsites.plotsquared.bukkit.util; package com.github.intellectualsites.plotsquared.bukkit.util;
import com.github.intellectualsites.plotsquared.bukkit.generator.BukkitPlotGenerator;
import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.generator.HybridPlotWorld;
import com.github.intellectualsites.plotsquared.plot.generator.HybridUtils; import com.github.intellectualsites.plotsquared.plot.generator.HybridUtils;
import com.github.intellectualsites.plotsquared.plot.object.RegionWrapper; import com.github.intellectualsites.plotsquared.plot.object.*;
import com.github.intellectualsites.plotsquared.plot.object.RunnableVal; import com.github.intellectualsites.plotsquared.plot.util.ChunkManager;
import com.github.intellectualsites.plotsquared.plot.util.MainUtil;
import com.github.intellectualsites.plotsquared.plot.util.MathMan;
import com.github.intellectualsites.plotsquared.plot.util.TaskManager;
import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue;
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
import com.github.intellectualsites.plotsquared.plot.util.expiry.PlotAnalysis; import com.github.intellectualsites.plotsquared.plot.util.expiry.PlotAnalysis;
import com.sk89q.worldedit.world.block.BaseBlock;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.Directional;
import org.bukkit.generator.ChunkGenerator;
import java.util.HashSet;
public class BukkitHybridUtils extends HybridUtils { public class BukkitHybridUtils extends HybridUtils {
@ -21,242 +38,257 @@ public class BukkitHybridUtils extends HybridUtils {
* - recheck each block * - recheck each block
* *
*/ */
/* TODO: Redo TaskManager.runTaskAsync(() -> {
TaskManager.runTaskAsync(new Runnable() { final LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(world, false);
@Override public void run() { final World worldObj = Bukkit.getWorld(world);
final LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(world, false); final ChunkGenerator chunkGenerator = worldObj.getGenerator();
final World worldObj = Bukkit.getWorld(world); if (!(chunkGenerator instanceof BukkitPlotGenerator)) {
final ChunkGenerator gen = worldObj.getGenerator(); return;
if (gen == null) {
return;
}
final BiomeGrid nullBiomeGrid = new BiomeGrid() {
@Override public void setBiome(int a, int b, Biome c) {
}
@Override public Biome getBiome(int a, int b) {
return null;
}
};
final Location bot = new Location(world, region.minX, region.minY, region.minZ);
final Location top = new Location(world, region.maxX, region.maxY, region.maxZ);
final int bx = bot.getX();
final int bz = bot.getZ();
final int tx = top.getX();
final int tz = top.getZ();
final int cbx = bx >> 4;
final int cbz = bz >> 4;
final int ctx = tx >> 4;
final int ctz = tz >> 4;
final Random r = new Random();
MainUtil.initCache();
final int width = tx - bx + 1;
final int length = tz - bz + 1;
System.gc();
System.gc();
final short[][][] oldBlocks = new short[256][width][length];
final short[][][] newBlocks = new short[256][width][length];
final Runnable run = new Runnable() {
@Override public void run() {
ChunkManager.chunkTask(bot, top, new RunnableVal<int[]>() {
@Override public void run(int[] value) {
// [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge]
int X = value[0];
int Z = value[1];
short[][] result =
gen.generateExtBlockSections(worldObj, r, X, Z, nullBiomeGrid);
int xb = (X << 4) - bx;
int zb = (Z << 4) - bz;
for (int i = 0; i < result.length; i++) {
if (result[i] == null) {
for (int j = 0; j < 4096; j++) {
int x = MainUtil.x_loc[i][j] + xb;
if (x < 0 || x >= width) {
continue;
}
int z = MainUtil.z_loc[i][j] + zb;
if (z < 0 || z >= length) {
continue;
}
int y = MainUtil.y_loc[i][j];
oldBlocks[y][x][z] = 0;
}
continue;
}
for (int j = 0; j < result[i].length; j++) {
int x = MainUtil.x_loc[i][j] + xb;
if (x < 0 || x >= width) {
continue;
}
int z = MainUtil.z_loc[i][j] + zb;
if (z < 0 || z >= length) {
continue;
}
int y = MainUtil.y_loc[i][j];
oldBlocks[y][x][z] = result[i][j];
}
}
}
}, new Runnable() {
@Override public void run() {
TaskManager.runTaskAsync(new Runnable() {
@Override public void run() {
int size = width * length;
int[] changes = new int[size];
int[] faces = new int[size];
int[] data = new int[size];
int[] air = new int[size];
int[] variety = new int[size];
int i = 0;
for (int x = 0; x < width; x++) {
for (int z = 0; z < length; z++) {
HashSet<Short> types = new HashSet<>();
for (int y = 0; y < 256; y++) {
short old = oldBlocks[y][x][z];
short now = newBlocks[y][x][z];
if (old != now) {
changes[i]++;
}
if (now == 0) {
air[i]++;
} else {
// check vertices
// modifications_adjacent
if (x > 0 && z > 0 && y > 0 && x < width - 1
&& z < length - 1 && y < 255) {
if (newBlocks[y - 1][x][z] == 0) {
faces[i]++;
}
if (newBlocks[y][x - 1][z] == 0) {
faces[i]++;
}
if (newBlocks[y][x][z - 1] == 0) {
faces[i]++;
}
if (newBlocks[y + 1][x][z] == 0) {
faces[i]++;
}
if (newBlocks[y][x + 1][z] == 0) {
faces[i]++;
}
if (newBlocks[y][x][z + 1] == 0) {
faces[i]++;
}
}
Material material =
Material.getMaterial(now);
if (material != null) {
Class<? extends MaterialData> md =
material.getData();
if (md.equals(Directional.class)) {
data[i] += 8;
} else if (!md
.equals(MaterialData.class)) {
data[i]++;
}
}
types.add(now);
}
}
variety[i] = types.size();
i++;
}
}
// analyze plot
// put in analysis obj
// run whenDone
PlotAnalysis analysis = new PlotAnalysis();
analysis.changes = (int) (MathMan.getMean(changes) * 100);
analysis.faces = (int) (MathMan.getMean(faces) * 100);
analysis.data = (int) (MathMan.getMean(data) * 100);
analysis.air = (int) (MathMan.getMean(air) * 100);
analysis.variety = (int) (MathMan.getMean(variety) * 100);
analysis.changes_sd =
(int) MathMan.getSD(changes, analysis.changes);
analysis.faces_sd =
(int) MathMan.getSD(faces, analysis.faces);
analysis.data_sd = (int) MathMan.getSD(data, analysis.data);
analysis.air_sd = (int) MathMan.getSD(air, analysis.air);
analysis.variety_sd =
(int) MathMan.getSD(variety, analysis.variety);
System.gc();
System.gc();
whenDone.value = analysis;
whenDone.run();
}
});
}
}, 5);
}
};
System.gc();
MainUtil.initCache();
ChunkManager.chunkTask(bot, top, new RunnableVal<int[]>() {
@Override public void run(int[] value) {
int X = value[0];
int Z = value[1];
worldObj.loadChunk(X, Z);
int minX;
if (X == cbx) {
minX = bx & 15;
} else {
minX = 0;
}
int minZ;
if (Z == cbz) {
minZ = bz & 15;
} else {
minZ = 0;
}
int maxX;
if (X == ctx) {
maxX = tx & 15;
} else {
maxX = 16;
}
int maxZ;
if (Z == ctz) {
maxZ = tz & 15;
} else {
maxZ = 16;
}
int cbx = X << 4;
int cbz = Z << 4;
int xb = cbx - bx;
int zb = cbz - bz;
for (int x = minX; x <= maxX; x++) {
int xx = cbx + x;
for (int z = minZ; z <= maxZ; z++) {
int zz = cbz + z;
for (int y = 0; y < 256; y++) {
PlotBlock block = queue.getBlock(xx, y, zz);
int xr = xb + x;
int zr = zb + z;
newBlocks[y][xr][zr] = block.id;
}
}
}
worldObj.unloadChunkRequest(X, Z, true);
}
}, new Runnable() {
@Override public void run() {
TaskManager.runTaskAsync(run);
}
}, 5);
} }
final Location bot = new Location(world, region.minX, region.minY, region.minZ);
final Location top = new Location(world, region.maxX, region.maxY, region.maxZ);
final int bx = bot.getX();
final int bz = bot.getZ();
final int tx = top.getX();
final int tz = top.getZ();
final int cbx = bx >> 4;
final int cbz = bz >> 4;
final int ctx = tx >> 4;
final int ctz = tz >> 4;
MainUtil.initCache();
final int width = tx - bx + 1;
final int length = tz - bz + 1;
System.gc();
System.gc();
final BlockBucket[][][] oldBlocks = new BlockBucket[256][width][length];
final PlotBlock[][][] newBlocks = new PlotBlock[256][width][length];
PlotArea area = PlotSquared.get().getPlotArea(world, null);
if (!(area instanceof HybridPlotWorld))
return;
HybridPlotWorld hpw = (HybridPlotWorld) area;
final BlockBucket[][] result = hpw.getBlockBucketChunk();
if (hpw.PLOT_SCHEMATIC) {
short[] rx = new short[16];
short[] rz = new short[16];
short rbx;
short rbz;
if (bx < 0) {
rbx = (short) (hpw.SIZE + (bx % hpw.SIZE));
} else {
rbx = (short) (bx % hpw.SIZE);
}
if (bz < 0) {
rbz = (short) (hpw.SIZE + (bz % hpw.SIZE));
} else {
rbz = (short) (bz % hpw.SIZE);
}
for (short i = 0; i < 16; i++) {
short v = (short) (rbx + i);
if (v >= hpw.SIZE) {
v -= hpw.SIZE;
}
rx[i] = v;
}
for (short i = 0; i < 16; i++) {
short v = (short) (rbz + i);
if (v >= hpw.SIZE) {
v -= hpw.SIZE;
}
rz[i] = v;
}
int minY = Math.min(hpw.PLOT_HEIGHT, hpw.ROAD_HEIGHT);
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
BaseBlock[] blocks = hpw.G_SCH.get(MathMan.pair(rx[x], rz[z]));
for (int y = 0; y < blocks.length; y++) {
if (blocks[y] != null) {
result[(minY + y) >> 4][(((minY + y) & 0xF) << 8) | (z << 4) | x] =
BlockBucket.withSingle(PlotBlock.get(blocks[y]));
}
}
}
}
}
final Runnable run = () -> ChunkManager.chunkTask(bot, top, new RunnableVal<int[]>() {
@Override public void run(int[] value) {
// [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge]
int X = value[0];
int Z = value[1];
int xb = (X << 4) - bx;
int zb = (Z << 4) - bz;
for (int i = 0; i < result.length; i++) {
if (result[i] == null) {
for (int j = 0; j < 4096; j++) {
int x = MainUtil.x_loc[i][j] + xb;
if (x < 0 || x >= width) {
continue;
}
int z = MainUtil.z_loc[i][j] + zb;
if (z < 0 || z >= length) {
continue;
}
int y = MainUtil.y_loc[i][j];
oldBlocks[y][x][z] =
BlockBucket.withSingle(StringPlotBlock.EVERYTHING);
}
continue;
}
for (int j = 0; j < result[i].length; j++) {
int x = MainUtil.x_loc[i][j] + xb;
if (x < 0 || x >= width) {
continue;
}
int z = MainUtil.z_loc[i][j] + zb;
if (z < 0 || z >= length) {
continue;
}
int y = MainUtil.y_loc[i][j];
oldBlocks[y][x][z] = result[i][j];
}
}
}
}, () -> TaskManager.runTaskAsync(() -> {
int size = width * length;
int[] changes = new int[size];
int[] faces = new int[size];
int[] data = new int[size];
int[] air = new int[size];
int[] variety = new int[size];
int i = 0;
for (int x = 0; x < width; x++) {
for (int z = 0; z < length; z++) {
HashSet<PlotBlock> types = new HashSet<>();
for (int y = 0; y < 256; y++) {
BlockBucket old = oldBlocks[y][x][z];
PlotBlock now = newBlocks[y][x][z];
if (!old.getBlocks().contains(now)) {
changes[i]++;
}
if (now.isAir()) {
air[i]++;
} else {
// check vertices
// modifications_adjacent
if (x > 0 && z > 0 && y > 0 && x < width - 1 && z < length - 1
&& y < 255) {
if (newBlocks[y - 1][x][z].isAir()) {
faces[i]++;
}
if (newBlocks[y][x - 1][z].isAir()) {
faces[i]++;
}
if (newBlocks[y][x][z - 1].isAir()) {
faces[i]++;
}
if (newBlocks[y + 1][x][z].isAir()) {
faces[i]++;
}
if (newBlocks[y][x + 1][z].isAir()) {
faces[i]++;
}
if (newBlocks[y][x][z + 1].isAir()) {
faces[i]++;
}
}
Material material = now.to(Material.class);
if (material != null) {
BlockData blockData = material.createBlockData();
if (blockData instanceof Directional) {
data[i] += 8;
} else if (!blockData.getClass().equals(BlockData.class)) {
data[i]++;
}
}
types.add(now);
}
}
variety[i] = types.size();
i++;
}
}
// analyze plot
// put in analysis obj
// run whenDone
PlotAnalysis analysis = new PlotAnalysis();
analysis.changes = (int) (MathMan.getMean(changes) * 100);
analysis.faces = (int) (MathMan.getMean(faces) * 100);
analysis.data = (int) (MathMan.getMean(data) * 100);
analysis.air = (int) (MathMan.getMean(air) * 100);
analysis.variety = (int) (MathMan.getMean(variety) * 100);
analysis.changes_sd = (int) (MathMan.getSD(changes, analysis.changes) * 100);
analysis.faces_sd = (int) (MathMan.getSD(faces, analysis.faces) * 100);
analysis.data_sd = (int) (MathMan.getSD(data, analysis.data) * 100);
analysis.air_sd = (int) (MathMan.getSD(air, analysis.air) * 100);
analysis.variety_sd = (int) (MathMan.getSD(variety, analysis.variety) * 100);
System.gc();
System.gc();
whenDone.value = analysis;
whenDone.run();
}), 5);
System.gc();
MainUtil.initCache();
ChunkManager.chunkTask(bot, top, new RunnableVal<int[]>() {
@Override public void run(int[] value) {
int X = value[0];
int Z = value[1];
worldObj.loadChunk(X, Z);
int minX;
if (X == cbx) {
minX = bx & 15;
} else {
minX = 0;
}
int minZ;
if (Z == cbz) {
minZ = bz & 15;
} else {
minZ = 0;
}
int maxX;
if (X == ctx) {
maxX = tx & 15;
} else {
maxX = 16;
}
int maxZ;
if (Z == ctz) {
maxZ = tz & 15;
} else {
maxZ = 16;
}
int cbx = X << 4;
int cbz = Z << 4;
int xb = cbx - bx;
int zb = cbz - bz;
for (int x = minX; x <= maxX; x++) {
int xx = cbx + x;
for (int z = minZ; z <= maxZ; z++) {
int zz = cbz + z;
for (int y = 0; y < 256; y++) {
PlotBlock block = queue.getBlock(xx, y, zz);
int xr = xb + x;
int zr = zb + z;
newBlocks[y][xr][zr] = block;
}
}
}
worldObj.unloadChunkRequest(X, Z, true);
}
}, () -> TaskManager.runTaskAsync(run), 5);
}); });
*/
} }
} }

View File

@ -27,6 +27,30 @@ public class HybridGen extends IndependentPlotGenerator {
} }
} }
@Override public BlockBucket[][] generateBlockBucketChunk(PlotArea settings) {
BlockBucket[][] blockBuckets = new BlockBucket[16][];
HybridPlotWorld hpw = (HybridPlotWorld) settings;
// Bedrock
if (hpw.PLOT_BEDROCK) {
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
blockBuckets[0][(z << 4) | x] =
BlockBucket.withSingle(PlotBlock.get("bedrock"));
}
}
}
for (short x = 0; x < 16; x++) {
for (short z = 0; z < 16; z++) {
for (int y = 1; y < hpw.PLOT_HEIGHT; y++) {
blockBuckets[y >> 4][((y & 0xF) << 8) | (z << 4) | x] = hpw.MAIN_BLOCK;
}
blockBuckets[hpw.PLOT_HEIGHT >> 4][((hpw.PLOT_HEIGHT & 0xF) << 8) | (z << 4) | x] =
hpw.MAIN_BLOCK;
}
}
return blockBuckets;
}
@Override public void generateChunk(ScopedLocalBlockQueue result, PlotArea settings) { @Override public void generateChunk(ScopedLocalBlockQueue result, PlotArea settings) {
HybridPlotWorld hpw = (HybridPlotWorld) settings; HybridPlotWorld hpw = (HybridPlotWorld) settings;
// Biome // Biome
@ -41,8 +65,6 @@ public class HybridGen extends IndependentPlotGenerator {
} }
// Coords // Coords
Location min = result.getMin(); Location min = result.getMin();
int cx = min.getX() >> 4;
int cz = min.getZ() >> 4;
int bx = (min.getX()) - hpw.ROAD_OFFSET_X; int bx = (min.getX()) - hpw.ROAD_OFFSET_X;
int bz = (min.getZ()) - hpw.ROAD_OFFSET_Z; int bz = (min.getZ()) - hpw.ROAD_OFFSET_Z;
short rbx; short rbx;

View File

@ -1,10 +1,7 @@
package com.github.intellectualsites.plotsquared.plot.generator; package com.github.intellectualsites.plotsquared.plot.generator;
import com.github.intellectualsites.plotsquared.plot.PlotSquared; import com.github.intellectualsites.plotsquared.plot.PlotSquared;
import com.github.intellectualsites.plotsquared.plot.object.PlotArea; import com.github.intellectualsites.plotsquared.plot.object.*;
import com.github.intellectualsites.plotsquared.plot.object.PlotId;
import com.github.intellectualsites.plotsquared.plot.object.PlotManager;
import com.github.intellectualsites.plotsquared.plot.object.SetupObject;
import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.ScopedLocalBlockQueue;
/** /**
@ -19,6 +16,14 @@ public abstract class IndependentPlotGenerator {
*/ */
public abstract String getName(); public abstract String getName();
/**
* Generates a 16x4096 array of BlockBuckets corresponding to the area settings to allow for plot analysis
*
* @param settings
* @return
*/
public abstract BlockBucket[][] generateBlockBucketChunk(PlotArea settings);
/** /**
* Use the setBlock or setBiome method of the PlotChunk result parameter to make changes. * Use the setBlock or setBiome method of the PlotChunk result parameter to make changes.
* The PlotArea settings is the same one this was initialized with. * The PlotArea settings is the same one this was initialized with.

View File

@ -14,6 +14,7 @@ import com.github.intellectualsites.plotsquared.plot.util.*;
import com.github.intellectualsites.plotsquared.plot.util.area.QuadMap; import com.github.intellectualsites.plotsquared.plot.util.area.QuadMap;
import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue;
import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue; import com.github.intellectualsites.plotsquared.plot.util.block.LocalBlockQueue;
import lombok.Getter;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -34,6 +35,7 @@ public abstract class PlotArea {
private final PlotId min; private final PlotId min;
private final PlotId max; private final PlotId max;
private final IndependentPlotGenerator generator; private final IndependentPlotGenerator generator;
@Getter private final BlockBucket[][] blockBucketChunk;
public int MAX_PLOT_MEMBERS = 128; public int MAX_PLOT_MEMBERS = 128;
public boolean AUTO_MERGE = false; public boolean AUTO_MERGE = false;
public boolean ALLOW_SIGNS = true; public boolean ALLOW_SIGNS = true;
@ -66,8 +68,9 @@ public abstract class PlotArea {
private ConcurrentHashMap<String, Object> meta; private ConcurrentHashMap<String, Object> meta;
private QuadMap<PlotCluster> clusters; private QuadMap<PlotCluster> clusters;
public PlotArea(@Nonnull final String worldName, @Nullable final String id, @Nullable IndependentPlotGenerator generator, public PlotArea(@Nonnull final String worldName, @Nullable final String id,
@Nullable final PlotId min, @Nullable final PlotId max) { @Nullable IndependentPlotGenerator generator, @Nullable final PlotId min,
@Nullable final PlotId max) {
this.worldname = worldName; this.worldname = worldName;
this.id = id; this.id = id;
this.manager = generator != null ? generator.getNewPlotManager() : null; this.manager = generator != null ? generator.getNewPlotManager() : null;
@ -84,6 +87,11 @@ public abstract class PlotArea {
this.max = max; this.max = max;
} }
this.worldhash = worldName.hashCode(); this.worldhash = worldName.hashCode();
if (Settings.Enabled_Components.PLOT_EXPIRY) {
blockBucketChunk = generator.generateBlockBucketChunk(this);
} else {
blockBucketChunk = null;
}
} }
/** /**
@ -395,7 +403,7 @@ public abstract class PlotArea {
* *
* @return ConfigurationNode[] * @return ConfigurationNode[]
*/ */
public abstract ConfigurationNode[] getSettingNodes(); public abstract ConfigurationNode[] getSettingNodes();
/** /**
* Gets the {@code Plot} at a location. * Gets the {@code Plot} at a location.
@ -591,7 +599,8 @@ public abstract class PlotArea {
return this.clusters != null ? this.clusters.get(plot.getId().x, plot.getId().y) : null; return this.clusters != null ? this.clusters.get(plot.getId().x, plot.getId().y) : null;
} }
@Nullable public PlotCluster getFirstIntersectingCluster(@Nonnull final PlotId pos1, @Nonnull final PlotId pos2) { @Nullable public PlotCluster getFirstIntersectingCluster(@Nonnull final PlotId pos1,
@Nonnull final PlotId pos2) {
if (this.clusters == null) { if (this.clusters == null) {
return null; return null;
} }
@ -615,6 +624,7 @@ public abstract class PlotArea {
* Session only plot metadata (session is until the server stops). * Session only plot metadata (session is until the server stops).
* <br> * <br>
* For persistent metadata use the flag system * For persistent metadata use the flag system
*
* @see FlagManager * @see FlagManager
*/ */
public void setMeta(@Nonnull final String key, @Nullable final Object value) { public void setMeta(@Nonnull final String key, @Nullable final Object value) {

View File

@ -17,6 +17,39 @@ public class SingleWorldGenerator extends IndependentPlotGenerator {
return "PlotSquared:single"; return "PlotSquared:single";
} }
@Override public BlockBucket[][] generateBlockBucketChunk(PlotArea settings) {
BlockBucket[][] blockBuckets = new BlockBucket[16][];
SinglePlotArea area = (SinglePlotArea) settings;
if (area.VOID) {
return blockBuckets;
}
for (int x = bedrock1.getX(); x <= bedrock2.getX(); x++) {
for (int z = bedrock1.getZ(); z <= bedrock2.getZ(); z++) {
for (int y = bedrock1.getY(); y <= bedrock2.getY(); y++) {
blockBuckets[y >> 4][((y & 0xF) << 8) | (z << 4) | x] =
BlockBucket.withSingle(PlotBlock.get("bedrock"));
}
}
}
for (int x = dirt1.getX(); x <= dirt2.getX(); x++) {
for (int z = dirt1.getZ(); z <= dirt2.getZ(); z++) {
for (int y = dirt1.getY(); y <= dirt2.getY(); y++) {
blockBuckets[y >> 4][((y & 0xF) << 8) | (z << 4) | x] =
BlockBucket.withSingle(PlotBlock.get("dirt"));
}
}
}
for (int x = grass1.getX(); x <= grass2.getX(); x++) {
for (int z = grass1.getZ(); z <= grass2.getZ(); z++) {
for (int y = grass1.getY(); y <= grass2.getY(); y++) {
blockBuckets[y >> 4][((y & 0xF) << 8) | (z << 4) | x] =
BlockBucket.withSingle(PlotBlock.get("grass_block"));
}
}
}
return blockBuckets;
}
@Override public void generateChunk(ScopedLocalBlockQueue result, PlotArea settings) { @Override public void generateChunk(ScopedLocalBlockQueue result, PlotArea settings) {
SinglePlotArea area = (SinglePlotArea) settings; SinglePlotArea area = (SinglePlotArea) settings;
if (area.VOID) { if (area.VOID) {
@ -25,9 +58,9 @@ public class SingleWorldGenerator extends IndependentPlotGenerator {
result.setBlock(0, 0, 0, PlotBlock.get("bedrock")); result.setBlock(0, 0, 0, PlotBlock.get("bedrock"));
} }
} else { } else {
result.setCuboid(bedrock1, bedrock2, PlotBlock.get(7, 0)); result.setCuboid(bedrock1, bedrock2, PlotBlock.get("bedrock"));
result.setCuboid(dirt1, dirt2, PlotBlock.get(3, 0)); result.setCuboid(dirt1, dirt2, PlotBlock.get("dirt"));
result.setCuboid(grass1, grass2, PlotBlock.get(2, 0)); result.setCuboid(grass1, grass2, PlotBlock.get("grass_block"));
} }
result.fillBiome("PLAINS"); result.fillBiome("PLAINS");
} }