PlotSquared/src/main/java/com/plotsquared/bukkit/util/BukkitHybridUtils.java

326 lines
16 KiB
Java
Raw Normal View History

2015-07-28 08:06:19 +02:00
package com.plotsquared.bukkit.util;
2015-02-21 04:43:08 +01:00
2015-07-30 16:25:16 +02:00
import com.intellectualcrafters.plot.generator.HybridUtils;
import com.intellectualcrafters.plot.object.Location;
import com.intellectualcrafters.plot.object.PlotAnalysis;
import com.intellectualcrafters.plot.object.PlotBlock;
2015-09-22 15:23:28 +02:00
import com.intellectualcrafters.plot.object.RegionWrapper;
2015-07-30 16:25:16 +02:00
import com.intellectualcrafters.plot.object.RunnableVal;
import com.intellectualcrafters.plot.util.ChunkManager;
2015-07-30 16:25:16 +02:00
import com.intellectualcrafters.plot.util.MainUtil;
import com.intellectualcrafters.plot.util.MathMan;
import com.intellectualcrafters.plot.util.TaskManager;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.generator.ChunkGenerator;
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
import org.bukkit.material.Directional;
import org.bukkit.material.MaterialData;
import java.util.HashSet;
import java.util.Random;
2015-02-21 04:43:08 +01:00
2015-09-13 06:04:31 +02:00
public class BukkitHybridUtils extends HybridUtils {
@Override
2015-09-22 15:23:28 +02:00
public void analyzeRegion(final String world, final RegionWrapper region, final RunnableVal<PlotAnalysis> whenDone) {
2016-02-05 00:45:50 +01:00
// int diff, int variety, int vertices, int rotation, int height_sd
/*
* diff: compare to base by looping through all blocks
2016-02-05 00:45:50 +01:00
* variety: add to HashSet for each PlotBlock
* height_sd: loop over all blocks and get top block
2015-07-03 11:30:26 +02:00
*
2016-02-05 00:45:50 +01:00
* vertices: store air map and compare with neighbours
* for each block check the adjacent
* - Store all blocks then go through in second loop
* - recheck each block
2015-07-03 11:30:26 +02:00
*
*/
2015-09-13 06:04:31 +02:00
TaskManager.runTaskAsync(new Runnable() {
@Override
2015-09-13 06:04:31 +02:00
public void run() {
2015-09-22 15:23:28 +02:00
final World worldObj = Bukkit.getWorld(world);
final ChunkGenerator gen = worldObj.getGenerator();
if (gen == null) {
return;
}
2015-09-22 15:23:28 +02:00
final BiomeGrid nullBiomeGrid = new BiomeGrid() {
2015-09-11 12:09:22 +02:00
@Override
public void setBiome(final int a, final int b, final Biome c) {
}
2015-09-11 12:09:22 +02:00
@Override
2015-09-13 06:04:31 +02:00
public Biome getBiome(final int a, final int b) {
2015-09-11 12:09:22 +02:00
return null;
}
};
2015-09-22 15:23:28 +02:00
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 Location bot = MainUtil.getPlotBottomLoc(plot.world, plot.type).add(1, 0, 1);
// final Location top = MainUtil.getPlotTopLoc(plot.world, plot.type);
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();
2015-09-11 12:09:22 +02:00
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];
2015-09-13 06:04:31 +02:00
final Runnable run = new Runnable() {
@Override
2015-09-13 06:04:31 +02:00
public void run() {
ChunkManager.chunkTask(bot, top, new RunnableVal<int[]>() {
@Override
2016-02-10 19:59:51 +01:00
public void run(int[] value) {
2015-09-22 15:23:28 +02:00
// [chunkx, chunkz, pos1x, pos1z, pos2x, pos2z, isedge]
2015-09-11 12:09:22 +02:00
final int X = value[0];
final int Z = value[1];
2015-09-22 15:23:28 +02:00
final short[][] result = gen.generateExtBlockSections(worldObj, r, X, Z, nullBiomeGrid);
2015-09-11 12:09:22 +02:00
final int xb = ((X) << 4) - bx;
final int zb = ((Z) << 4) - bz;
2015-09-13 06:04:31 +02:00
for (int i = 0; i < result.length; i++) {
if (result[i] == null) {
for (int j = 0; j < 4096; j++) {
2015-09-11 12:09:22 +02:00
final int x = MainUtil.x_loc[i][j] + xb;
2015-09-13 06:04:31 +02:00
if ((x < 0) || (x >= width)) {
2015-09-11 12:09:22 +02:00
continue;
}
final int z = MainUtil.z_loc[i][j] + zb;
2015-09-13 06:04:31 +02:00
if ((z < 0) || (z >= length)) {
2015-09-11 12:09:22 +02:00
continue;
}
final int y = MainUtil.y_loc[i][j];
oldblocks[y][x][z] = 0;
}
continue;
}
2015-09-13 06:04:31 +02:00
for (int j = 0; j < result[i].length; j++) {
2015-09-11 12:09:22 +02:00
final int x = MainUtil.x_loc[i][j] + xb;
2015-09-13 06:04:31 +02:00
if ((x < 0) || (x >= width)) {
2015-09-11 12:09:22 +02:00
continue;
}
final int z = MainUtil.z_loc[i][j] + zb;
2015-09-13 06:04:31 +02:00
if ((z < 0) || (z >= length)) {
2015-09-11 12:09:22 +02:00
continue;
}
final int y = MainUtil.y_loc[i][j];
oldblocks[y][x][z] = result[i][j];
}
}
}
2015-09-13 06:04:31 +02:00
}, new Runnable() {
@Override
2015-09-13 06:04:31 +02:00
public void run() {
TaskManager.runTaskAsync(new Runnable() {
@Override
2015-09-13 06:04:31 +02:00
public void run() {
2015-09-11 12:09:22 +02:00
final int size = width * length;
final int[] changes = new int[size];
final int[] faces = new int[size];
final int[] data = new int[size];
final int[] air = new int[size];
final int[] variety = new int[size];
int i = 0;
2015-09-13 06:04:31 +02:00
for (int x = 0; x < width; x++) {
for (int z = 0; z < length; z++) {
2015-09-11 12:09:22 +02:00
final HashSet<Short> types = new HashSet<>();
2015-09-13 06:04:31 +02:00
for (int y = 0; y < 256; y++) {
2015-09-11 12:09:22 +02:00
final short old = oldblocks[y][x][z];
final short now = newblocks[y][x][z];
2015-09-13 06:04:31 +02:00
if (old != now) {
changes[i]++;
}
2015-09-13 06:04:31 +02:00
if (now == 0) {
air[i]++;
2015-09-13 06:04:31 +02:00
} else {
2016-02-05 00:45:50 +01:00
// check vertices
// modifications_adjacent
2015-09-13 06:04:31 +02:00
if ((x > 0) && (z > 0) && (y > 0) && (x < (width - 1)) && (z < (length - 1)) && (y < 255)) {
if (newblocks[y - 1][x][z] == 0) {
2015-09-11 12:09:22 +02:00
faces[i]++;
}
2015-09-13 06:04:31 +02:00
if (newblocks[y][x - 1][z] == 0) {
2015-09-11 12:09:22 +02:00
faces[i]++;
}
2015-09-13 06:04:31 +02:00
if (newblocks[y][x][z - 1] == 0) {
2015-09-11 12:09:22 +02:00
faces[i]++;
}
2015-09-13 06:04:31 +02:00
if (newblocks[y + 1][x][z] == 0) {
2015-09-11 12:09:22 +02:00
faces[i]++;
}
2015-09-13 06:04:31 +02:00
if (newblocks[y][x + 1][z] == 0) {
2015-09-11 12:09:22 +02:00
faces[i]++;
}
2015-09-13 06:04:31 +02:00
if (newblocks[y][x][z + 1] == 0) {
2015-09-11 12:09:22 +02:00
faces[i]++;
}
}
2015-09-11 12:09:22 +02:00
final Material material = Material.getMaterial(now);
final Class<? extends MaterialData> md = material.getData();
2015-09-13 06:04:31 +02:00
if (md.equals(Directional.class)) {
data[i] += 8;
2015-09-13 06:04:31 +02:00
} else if (!md.equals(MaterialData.class)) {
data[i]++;
}
types.add(now);
}
}
variety[i] = types.size();
i++;
}
}
// analyze plot
// put in analysis obj
// run whenDone
2015-09-11 12:09:22 +02:00
final 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();
2015-09-13 06:04:31 +02:00
ChunkManager.chunkTask(bot, top, new RunnableVal<int[]>() {
@Override
2016-02-10 19:59:51 +01:00
public void run(int[] value) {
2015-09-11 12:09:22 +02:00
final int X = value[0];
final int Z = value[1];
2015-09-22 15:23:28 +02:00
worldObj.loadChunk(X, Z);
int minX;
int minZ;
int maxX;
int maxZ;
2015-09-13 06:04:31 +02:00
if (X == cbx) {
2015-09-11 12:09:22 +02:00
minX = bx & 15;
2015-09-13 06:04:31 +02:00
} else {
2015-09-11 12:09:22 +02:00
minX = 0;
}
2015-09-13 06:04:31 +02:00
if (Z == cbz) {
2015-09-11 12:09:22 +02:00
minZ = bz & 15;
2015-09-13 06:04:31 +02:00
} else {
2015-09-11 12:09:22 +02:00
minZ = 0;
}
2015-09-13 06:04:31 +02:00
if (X == ctx) {
2015-09-11 12:09:22 +02:00
maxX = tx & 15;
2015-09-13 06:04:31 +02:00
} else {
2015-09-11 12:09:22 +02:00
maxX = 16;
}
2015-09-13 06:04:31 +02:00
if (Z == ctz) {
2015-09-11 12:09:22 +02:00
maxZ = tz & 15;
2015-09-13 06:04:31 +02:00
} else {
2015-09-11 12:09:22 +02:00
maxZ = 16;
}
2015-09-11 12:09:22 +02:00
final int cbx = X << 4;
final int cbz = Z << 4;
2015-09-11 12:09:22 +02:00
final int xb = (cbx) - bx;
final int zb = (cbz) - bz;
2015-09-13 06:04:31 +02:00
for (int x = minX; x <= maxX; x++) {
2015-09-11 12:09:22 +02:00
final int xx = cbx + x;
2015-09-13 06:04:31 +02:00
for (int z = minZ; z <= maxZ; z++) {
2015-09-11 12:09:22 +02:00
final int zz = cbz + z;
2015-09-13 06:04:31 +02:00
for (int y = 0; y < 256; y++) {
2015-09-22 15:23:28 +02:00
final Block block = worldObj.getBlockAt(xx, y, zz);
2015-09-11 12:09:22 +02:00
final int xr = xb + x;
final int zr = zb + z;
newblocks[y][xr][zr] = (short) block.getTypeId();
}
}
}
2015-09-22 15:23:28 +02:00
worldObj.unloadChunkRequest(X, Z, true);
}
2015-09-13 06:04:31 +02:00
}, new Runnable() {
@Override
2015-09-13 06:04:31 +02:00
public void run() {
TaskManager.runTaskAsync(run);
2015-06-26 11:46:06 +02:00
}
}, 5);
2015-07-03 11:30:26 +02:00
}
});
}
2015-02-21 04:43:08 +01:00
@Override
public int checkModified(final String worldname, final int x1, final int x2, final int y1, final int y2, final int z1, final int z2,
final PlotBlock[] blocks) {
2015-02-23 02:32:27 +01:00
final World world = BukkitUtil.getWorld(worldname);
2015-02-21 04:43:08 +01:00
int count = 0;
2015-09-13 06:04:31 +02:00
for (int y = y1; y <= y2; y++) {
for (int x = x1; x <= x2; x++) {
for (int z = z1; z <= z2; z++) {
2015-02-21 04:43:08 +01:00
final Block block = world.getBlockAt(x, y, z);
final int id = block.getTypeId();
boolean same = false;
2015-09-13 06:04:31 +02:00
for (final PlotBlock p : blocks) {
if (id == p.id) {
2015-02-21 04:43:08 +01:00
same = true;
break;
}
}
2015-09-13 06:04:31 +02:00
if (!same) {
2015-02-21 04:43:08 +01:00
count++;
}
}
}
}
return count;
}
2015-02-21 04:43:08 +01:00
@Override
2015-09-13 06:04:31 +02:00
public int get_ey(final String worldname, final int sx, final int ex, final int sz, final int ez, final int sy) {
2015-02-23 02:32:27 +01:00
final World world = BukkitUtil.getWorld(worldname);
final int maxY = world.getMaxHeight();
2015-02-21 04:43:08 +01:00
int ey = sy;
2015-09-13 06:04:31 +02:00
for (int x = sx; x <= ex; x++) {
for (int z = sz; z <= ez; z++) {
for (int y = sy; y < maxY; y++) {
if (y > ey) {
2015-02-21 04:43:08 +01:00
final Block block = world.getBlockAt(x, y, z);
2015-09-13 06:04:31 +02:00
if (block.getTypeId() != 0) {
2015-02-21 04:43:08 +01:00
ey = y;
}
}
}
}
}
return ey;
}
}