2015-02-21 04:43:08 +01:00
|
|
|
package com.intellectualcrafters.plot.generator;
|
|
|
|
|
2015-07-05 17:44:10 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.HashSet;
|
|
|
|
import java.util.Iterator;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Random;
|
|
|
|
|
2015-04-01 02:52:22 +02:00
|
|
|
import org.apache.commons.lang.mutable.MutableInt;
|
2015-02-21 04:43:08 +01:00
|
|
|
import org.bukkit.Bukkit;
|
|
|
|
import org.bukkit.Chunk;
|
2015-07-03 04:11:41 +02:00
|
|
|
import org.bukkit.Material;
|
2015-02-21 04:43:08 +01:00
|
|
|
import org.bukkit.World;
|
2015-06-26 09:37:59 +02:00
|
|
|
import org.bukkit.block.Biome;
|
2015-02-21 04:43:08 +01:00
|
|
|
import org.bukkit.block.Block;
|
2015-06-26 09:37:59 +02:00
|
|
|
import org.bukkit.generator.ChunkGenerator;
|
|
|
|
import org.bukkit.generator.ChunkGenerator.BiomeGrid;
|
2015-06-26 11:46:06 +02:00
|
|
|
import org.bukkit.material.Directional;
|
|
|
|
import org.bukkit.material.MaterialData;
|
2015-02-21 04:43:08 +01:00
|
|
|
import org.bukkit.plugin.Plugin;
|
|
|
|
|
2015-07-05 17:44:10 +02:00
|
|
|
import com.intellectualcrafters.plot.BukkitMain;
|
|
|
|
import com.intellectualcrafters.plot.PS;
|
|
|
|
import com.intellectualcrafters.plot.config.C;
|
|
|
|
import com.intellectualcrafters.plot.object.ChunkLoc;
|
|
|
|
import com.intellectualcrafters.plot.object.Location;
|
|
|
|
import com.intellectualcrafters.plot.object.Plot;
|
|
|
|
import com.intellectualcrafters.plot.object.PlotAnalysis;
|
|
|
|
import com.intellectualcrafters.plot.object.PlotBlock;
|
|
|
|
import com.intellectualcrafters.plot.object.PlotWorld;
|
|
|
|
import com.intellectualcrafters.plot.object.RunnableVal;
|
|
|
|
import com.intellectualcrafters.plot.util.ChunkManager;
|
|
|
|
import com.intellectualcrafters.plot.util.MainUtil;
|
|
|
|
import com.intellectualcrafters.plot.util.TaskManager;
|
|
|
|
import com.intellectualcrafters.plot.util.bukkit.BukkitUtil;
|
2015-02-21 04:43:08 +01:00
|
|
|
|
|
|
|
public class BukkitHybridUtils extends HybridUtils {
|
2015-07-03 11:30:26 +02:00
|
|
|
|
|
|
|
public static List<ChunkLoc> regions;
|
|
|
|
public static List<ChunkLoc> chunks = new ArrayList<>();
|
|
|
|
public static String world;
|
|
|
|
private static boolean UPDATE = false;
|
|
|
|
public int task;
|
|
|
|
private long last;
|
|
|
|
|
2015-06-26 11:46:06 +02:00
|
|
|
public double getMean(int[] array) {
|
|
|
|
double count = 0;
|
|
|
|
for (int i : array) {
|
|
|
|
count += i;
|
|
|
|
}
|
2015-07-03 11:30:26 +02:00
|
|
|
return count / array.length;
|
2015-06-26 11:46:06 +02:00
|
|
|
}
|
|
|
|
|
2015-06-28 02:54:57 +02:00
|
|
|
public double getMean(double[] array) {
|
|
|
|
double count = 0;
|
|
|
|
for (double i : array) {
|
|
|
|
count += i;
|
|
|
|
}
|
2015-07-03 11:30:26 +02:00
|
|
|
return count / array.length;
|
2015-06-28 02:54:57 +02:00
|
|
|
}
|
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
public double getSD(double[] array, double av) {
|
2015-06-28 02:54:57 +02:00
|
|
|
double sd = 0;
|
|
|
|
for (int i=0; i<array.length;i++)
|
|
|
|
{
|
|
|
|
sd += Math.pow(Math.abs(array[i] - av), 2);
|
|
|
|
}
|
|
|
|
return Math.sqrt(sd/array.length);
|
|
|
|
}
|
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
public double getSD(int[] array, double av) {
|
2015-06-26 11:46:06 +02:00
|
|
|
double sd = 0;
|
|
|
|
for (int i=0; i<array.length;i++)
|
|
|
|
{
|
|
|
|
sd += Math.pow(Math.abs(array[i] - av), 2);
|
|
|
|
}
|
|
|
|
return Math.sqrt(sd/array.length);
|
|
|
|
}
|
|
|
|
|
2015-06-28 02:54:57 +02:00
|
|
|
public int mod(int x) {
|
|
|
|
if (x < 0) {
|
|
|
|
return (x % 16) + 16;
|
|
|
|
}
|
|
|
|
return x % 16;
|
|
|
|
}
|
|
|
|
|
2015-06-26 09:37:59 +02:00
|
|
|
@Override
|
2015-06-28 02:54:57 +02:00
|
|
|
public void analyzePlot(Plot plot, final RunnableVal<PlotAnalysis> whenDone) {
|
2015-06-26 09:37:59 +02:00
|
|
|
// TODO Auto-generated method stub
|
|
|
|
// int diff, int variety, int verticies, int rotation, int height_sd
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-06-26 09:37:59 +02:00
|
|
|
/*
|
|
|
|
* diff: compare to base by looping through all blocks
|
|
|
|
* 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
|
|
|
*
|
2015-06-26 09:37:59 +02:00
|
|
|
* verticies: 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-06-26 09:37:59 +02:00
|
|
|
*/
|
2015-06-28 02:54:57 +02:00
|
|
|
final World world = Bukkit.getWorld(plot.world);
|
|
|
|
final ChunkGenerator gen = world.getGenerator();
|
|
|
|
if (gen == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
final BiomeGrid base = new BiomeGrid() { @Override public void setBiome(int a, int b, Biome c) {} @Override public Biome getBiome(int a, int b) {return null;}};
|
2015-07-03 04:11:41 +02:00
|
|
|
Location bot = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1);
|
|
|
|
Location top = MainUtil.getPlotTopLoc(plot.world, plot.id);
|
|
|
|
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;
|
2015-06-28 02:54:57 +02:00
|
|
|
final Random r = new Random();
|
2015-06-26 11:46:06 +02:00
|
|
|
AugmentedPopulator.initCache();
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
final int width = tx - bx + 1;
|
|
|
|
final int length = tz - bz + 1;
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
final short[][][] oldblocks = new short[256][width][length];
|
|
|
|
final short[][][] newblocks = new short[256][width][length];
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-06-28 02:54:57 +02:00
|
|
|
final List<Chunk> chunks = new ArrayList<>();
|
2015-07-03 04:11:41 +02:00
|
|
|
final List<Chunk> processed_chunks = new ArrayList<>();
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
for (int X = cbx; X <= ctx; X++) {
|
|
|
|
for (int Z = cbz; Z <= ctz; Z++) {
|
2015-06-26 09:37:59 +02:00
|
|
|
Chunk chunk = world.getChunkAt(X, Z);
|
2015-06-28 02:54:57 +02:00
|
|
|
chunks.add(chunk);
|
|
|
|
}
|
|
|
|
}
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
final Runnable run = new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
int t = 0;
|
|
|
|
for (Chunk chunk : processed_chunks) {
|
|
|
|
short[][] result = gen.generateExtBlockSections(world, r, chunk.getX(), chunk.getZ(), base);
|
|
|
|
int X = chunk.getX();
|
|
|
|
int Z = chunk.getZ();
|
|
|
|
int xb = ((X - cbx) << 4) - bx;
|
|
|
|
int zb = ((Z - cbz) << 4) - bz;
|
|
|
|
for (int i = 0; i < result.length; i++) {
|
|
|
|
if (result[i] == null) {
|
|
|
|
for (int j = 0; j < 4096; j++) {
|
|
|
|
int x = AugmentedPopulator.x_loc[i][j] + xb;
|
|
|
|
if (x < 0 || x >= width) continue;
|
|
|
|
int z = AugmentedPopulator.z_loc[i][j] + zb;
|
|
|
|
if (z < 0 || z >= length) continue;
|
|
|
|
int y = AugmentedPopulator.y_loc[i][j];
|
|
|
|
oldblocks[y][x][z] = 0;
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
for (int j = 0; j < result[i].length; j++) {
|
|
|
|
int x = AugmentedPopulator.x_loc[i][j] + xb;
|
|
|
|
if (x < 0 || x >= width) continue;
|
|
|
|
int z = AugmentedPopulator.z_loc[i][j] + zb;
|
|
|
|
if (z < 0 || z >= length) continue;
|
|
|
|
int y = AugmentedPopulator.y_loc[i][j];
|
|
|
|
oldblocks[y][x][z] = result[i][j];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
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];
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
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) {
|
|
|
|
t++;
|
|
|
|
changes[i]++;
|
|
|
|
}
|
|
|
|
if (now == 0) {
|
|
|
|
air[i]++;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// check verticies
|
|
|
|
// modifications_adjacent
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
if (x > 0 && z > 0 && y > 0 && x < width - 1 && z < length - 1 && y < 255) {
|
|
|
|
if (oldblocks[y - 1][x][z] == 0) faces[i]++;
|
|
|
|
if (oldblocks[y][x - 1][z] == 0) faces[i]++;
|
|
|
|
if (oldblocks[y][x][z - 1] == 0) faces[i]++;
|
|
|
|
if (oldblocks[y + 1][x][z] == 0) faces[i]++;
|
|
|
|
if (oldblocks[y][x + 1][z] == 0) faces[i]++;
|
|
|
|
if (oldblocks[y][x][z + 1] == 0) faces[i]++;
|
|
|
|
}
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
Material material = Material.getMaterial(now);
|
|
|
|
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++;
|
|
|
|
}
|
|
|
|
}
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
// analyze plot
|
|
|
|
// put in analysis obj
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
// run whenDone
|
|
|
|
PlotAnalysis analysis = new PlotAnalysis();
|
|
|
|
analysis.changes = getMean(changes);
|
|
|
|
analysis.faces = getMean(faces);
|
|
|
|
analysis.data = getMean(data);
|
|
|
|
analysis.air = getMean(air);
|
|
|
|
analysis.variety = getMean(variety);
|
|
|
|
analysis.complexity = getSD(changes, analysis.changes) + getSD(faces, analysis.faces) + getSD(data, analysis.data) + getSD(air, analysis.air) + getSD(variety, analysis.variety);
|
|
|
|
whenDone.value = analysis;
|
|
|
|
whenDone.run();
|
|
|
|
}
|
|
|
|
};
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
System.gc();
|
|
|
|
AugmentedPopulator.initCache();
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-06-28 02:54:57 +02:00
|
|
|
TaskManager.index.increment();
|
|
|
|
final Integer currentIndex = TaskManager.index.toInteger();
|
|
|
|
final Integer task = TaskManager.runTaskRepeat(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
int index = chunks.size() - 1;
|
|
|
|
if (index == -1) {
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.get().TASK.cancelTask(TaskManager.tasks.get(currentIndex));
|
2015-07-03 04:11:41 +02:00
|
|
|
TaskManager.runTaskAsync(run);
|
2015-06-28 02:54:57 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
Chunk chunk = chunks.remove(0);
|
2015-07-03 04:11:41 +02:00
|
|
|
processed_chunks.add(chunk);
|
2015-06-28 02:54:57 +02:00
|
|
|
int X = chunk.getX();
|
|
|
|
int Z = chunk.getZ();
|
2015-06-26 11:46:06 +02:00
|
|
|
short[][] current = new short[16][];
|
2015-06-28 02:54:57 +02:00
|
|
|
int minX;
|
|
|
|
int minZ;
|
|
|
|
int maxX;
|
|
|
|
int maxZ;
|
2015-07-03 04:11:41 +02:00
|
|
|
if (X == cbx) minX = mod(bx);
|
2015-06-28 02:54:57 +02:00
|
|
|
else minX = 0;
|
2015-07-03 04:11:41 +02:00
|
|
|
if (Z == cbz) minZ = mod(bz);
|
2015-06-28 02:54:57 +02:00
|
|
|
else minZ = 0;
|
2015-07-03 04:11:41 +02:00
|
|
|
if (X == ctx) maxX = mod(tx);
|
2015-06-28 02:54:57 +02:00
|
|
|
else maxX = 16;
|
2015-07-03 04:11:41 +02:00
|
|
|
if (Z == ctz) maxZ = mod(tz);
|
2015-06-28 02:54:57 +02:00
|
|
|
else maxZ = 16;
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
int xb = ((X - cbx) << 4) - bx;
|
|
|
|
int zb = ((Z - cbz) << 4) - bz;
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-07-03 04:11:41 +02:00
|
|
|
for (int x = minX; x <= maxX; x++) {
|
|
|
|
for (int z = minZ; z <= maxZ; z++) {
|
2015-06-26 11:46:06 +02:00
|
|
|
for (int y = 0; y < 256; y++) {
|
|
|
|
Block block = chunk.getBlock(x, y, z);
|
2015-07-03 11:30:26 +02:00
|
|
|
int xx = xb + x;
|
2015-07-03 04:11:41 +02:00
|
|
|
int zz = zb + z;
|
|
|
|
newblocks[y][xx][zz] = (short) block.getTypeId();
|
2015-06-26 11:46:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-07-03 11:30:26 +02:00
|
|
|
}
|
2015-06-28 02:54:57 +02:00
|
|
|
}, 1);
|
|
|
|
TaskManager.tasks.put(currentIndex, task);
|
2015-06-26 09:37:59 +02:00
|
|
|
}
|
2015-07-03 11:30:26 +02:00
|
|
|
|
|
|
|
public void checkModified(final Plot plot, final RunnableVal<Integer> whenDone) {
|
|
|
|
TaskManager.index.increment();
|
|
|
|
final Location bot = MainUtil.getPlotBottomLoc(plot.world, plot.id).add(1, 0, 1);
|
|
|
|
final Location top = MainUtil.getPlotTopLoc(plot.world, plot.id);
|
2015-04-01 02:52:22 +02:00
|
|
|
int bx = bot.getX() >> 4;
|
|
|
|
int bz = bot.getZ() >> 4;
|
|
|
|
int tx = top.getX() >> 4;
|
|
|
|
int tz = top.getZ() >> 4;
|
|
|
|
World world = BukkitUtil.getWorld(plot.world);
|
|
|
|
final HashSet<Chunk> chunks = new HashSet<>();
|
|
|
|
for (int X = bx; X <= tx; X++) {
|
|
|
|
for (int Z = bz; Z <= tz; Z++) {
|
|
|
|
chunks.add(world.getChunkAt(X,Z));
|
|
|
|
}
|
|
|
|
}
|
2015-07-03 14:15:20 +02:00
|
|
|
PlotWorld plotworld = PS.get().getPlotWorld(plot.world);
|
2015-04-01 02:52:22 +02:00
|
|
|
if (!(plotworld instanceof ClassicPlotWorld)) {
|
2015-04-03 09:30:27 +02:00
|
|
|
whenDone.value = -1;
|
2015-04-01 02:52:22 +02:00
|
|
|
TaskManager.runTaskLater(whenDone, 1);
|
|
|
|
return;
|
|
|
|
}
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-04-01 02:52:22 +02:00
|
|
|
final ClassicPlotWorld cpw = (ClassicPlotWorld) plotworld;
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-04-01 02:52:22 +02:00
|
|
|
final MutableInt count = new MutableInt(0);
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-04-01 02:52:22 +02:00
|
|
|
final Integer currentIndex = TaskManager.index.toInteger();
|
|
|
|
final Integer task = TaskManager.runTaskRepeat(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
if (chunks.size() == 0) {
|
2015-04-05 16:59:56 +02:00
|
|
|
whenDone.value = count.intValue();
|
2015-04-03 09:30:27 +02:00
|
|
|
TaskManager.runTaskLater(whenDone, 1);
|
2015-04-01 02:52:22 +02:00
|
|
|
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
|
|
|
|
TaskManager.tasks.remove(currentIndex);
|
|
|
|
return;
|
|
|
|
}
|
2015-04-05 16:59:56 +02:00
|
|
|
Iterator<Chunk> iter = chunks.iterator();
|
|
|
|
final Chunk chunk = iter.next();
|
|
|
|
iter.remove();
|
|
|
|
int bx = Math.max(chunk.getX() << 4, bot.getX());
|
|
|
|
int bz = Math.max(chunk.getZ() << 4, bot.getZ());
|
|
|
|
int ex = Math.min((chunk.getX() << 4) + 15, top.getX());
|
|
|
|
int ez = Math.min((chunk.getZ() << 4) + 15, top.getZ());
|
2015-04-01 02:52:22 +02:00
|
|
|
// count changes
|
|
|
|
count.add(checkModified(plot.world, bx, ex, 1, cpw.PLOT_HEIGHT - 1, bz, ez, cpw.MAIN_BLOCK));
|
|
|
|
count.add(checkModified(plot.world, bx, ex, cpw.PLOT_HEIGHT, cpw.PLOT_HEIGHT, bz, ez, cpw.TOP_BLOCK));
|
2015-04-05 16:59:56 +02:00
|
|
|
count.add(checkModified(plot.world, bx, ex, cpw.PLOT_HEIGHT + 1, 255, bz, ez, new PlotBlock[] { new PlotBlock((short) 0, (byte) 0) }));
|
2015-04-01 02:52:22 +02:00
|
|
|
}
|
|
|
|
}, 1);
|
|
|
|
TaskManager.tasks.put(currentIndex, task);
|
|
|
|
|
|
|
|
}
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-02-21 04:43:08 +01:00
|
|
|
@Override
|
2015-04-01 02:52:22 +02:00
|
|
|
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;
|
|
|
|
for (int y = y1; y <= y2; y++) {
|
|
|
|
for (int x = x1; x <= x2; x++) {
|
|
|
|
for (int z = z1; z <= z2; z++) {
|
|
|
|
final Block block = world.getBlockAt(x, y, z);
|
|
|
|
final int id = block.getTypeId();
|
|
|
|
boolean same = false;
|
|
|
|
for (final PlotBlock p : blocks) {
|
|
|
|
if (id == p.id) {
|
|
|
|
same = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!same) {
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-02-21 04:43:08 +01:00
|
|
|
@Override
|
2015-02-23 02:32:27 +01:00
|
|
|
public int get_ey(final String worldname, final int sx, final int ex, final int sz, final int ez, final int sy) {
|
|
|
|
final World world = BukkitUtil.getWorld(worldname);
|
|
|
|
final int maxY = world.getMaxHeight();
|
2015-02-21 04:43:08 +01:00
|
|
|
int ey = sy;
|
|
|
|
for (int x = sx; x <= ex; x++) {
|
|
|
|
for (int z = sz; z <= ez; z++) {
|
|
|
|
for (int y = sy; y < maxY; y++) {
|
|
|
|
if (y > ey) {
|
|
|
|
final Block block = world.getBlockAt(x, y, z);
|
|
|
|
if (block.getTypeId() != 0) {
|
|
|
|
ey = y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ey;
|
|
|
|
}
|
2015-02-23 02:32:27 +01:00
|
|
|
|
|
|
|
public void regenerateChunkChunk(final String worldname, final ChunkLoc loc) {
|
|
|
|
final World world = BukkitUtil.getWorld(worldname);
|
2015-02-21 04:43:08 +01:00
|
|
|
final int sx = loc.x << 5;
|
|
|
|
final int sz = loc.z << 5;
|
|
|
|
for (int x = sx; x < (sx + 32); x++) {
|
|
|
|
for (int z = sz; z < (sz + 32); z++) {
|
|
|
|
final Chunk chunk = world.getChunkAt(x, z);
|
|
|
|
chunk.load(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
final ArrayList<Chunk> chunks2 = new ArrayList<>();
|
|
|
|
for (int x = sx; x < (sx + 32); x++) {
|
|
|
|
for (int z = sz; z < (sz + 32); z++) {
|
|
|
|
final Chunk chunk = world.getChunkAt(x, z);
|
|
|
|
chunks2.add(chunk);
|
2015-06-11 02:56:53 +02:00
|
|
|
regenerateRoad(worldname, new ChunkLoc(x, z), 0);
|
2015-04-02 02:56:34 +02:00
|
|
|
MainUtil.update(world.getName(), new ChunkLoc(chunk.getX(), chunk.getZ()));
|
2015-02-21 04:43:08 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-07-03 11:30:26 +02:00
|
|
|
|
2015-03-24 06:27:56 +01:00
|
|
|
public final ArrayList<ChunkLoc> getChunks(ChunkLoc region) {
|
|
|
|
ArrayList<ChunkLoc> chunks = new ArrayList<ChunkLoc>();
|
|
|
|
final int sx = region.x << 5;
|
|
|
|
final int sz = region.z << 5;
|
|
|
|
for (int x = sx; x < (sx + 32); x++) {
|
|
|
|
for (int z = sz; z < (sz + 32); z++) {
|
|
|
|
chunks.add(new ChunkLoc(x, z));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return chunks;
|
|
|
|
}
|
2015-02-23 02:32:27 +01:00
|
|
|
|
2015-02-21 04:43:08 +01:00
|
|
|
@Override
|
2015-06-11 02:56:53 +02:00
|
|
|
public boolean scheduleRoadUpdate(final String world, int extend) {
|
2015-02-21 04:43:08 +01:00
|
|
|
if (BukkitHybridUtils.UPDATE) {
|
|
|
|
return false;
|
|
|
|
}
|
2015-04-07 09:57:07 +02:00
|
|
|
BukkitHybridUtils.UPDATE = true;
|
2015-03-24 06:27:56 +01:00
|
|
|
final List<ChunkLoc> regions = ChunkManager.manager.getChunkChunks(world);
|
2015-06-11 02:56:53 +02:00
|
|
|
return scheduleRoadUpdate(world, regions, extend);
|
2015-04-07 09:57:07 +02:00
|
|
|
}
|
|
|
|
|
2015-06-11 02:56:53 +02:00
|
|
|
public boolean scheduleRoadUpdate(final String world, final List<ChunkLoc> rgs, final int extend) {
|
2015-06-07 21:37:40 +02:00
|
|
|
BukkitHybridUtils.regions = rgs;
|
|
|
|
BukkitHybridUtils.world = world;
|
|
|
|
chunks = new ArrayList<ChunkLoc>();
|
2015-02-23 02:32:27 +01:00
|
|
|
final Plugin plugin = BukkitMain.THIS;
|
2015-06-07 21:37:40 +02:00
|
|
|
final MutableInt count = new MutableInt(0);
|
2015-02-21 04:43:08 +01:00
|
|
|
this.task = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2015-06-07 21:37:40 +02:00
|
|
|
count.increment();
|
|
|
|
if (count.intValue() % 20 == 0) {
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log("PROGRESS: " + ((100 * (2048 - chunks.size())) / 2048) + "%");
|
2015-06-07 21:37:40 +02:00
|
|
|
}
|
2015-05-07 10:15:51 +02:00
|
|
|
if (regions.size() == 0 && chunks.size() == 0) {
|
2015-02-21 04:43:08 +01:00
|
|
|
BukkitHybridUtils.UPDATE = false;
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log(C.PREFIX.s() + "Finished road conversion");
|
2015-02-21 04:43:08 +01:00
|
|
|
Bukkit.getScheduler().cancelTask(BukkitHybridUtils.this.task);
|
|
|
|
return;
|
|
|
|
} else {
|
2015-03-24 06:27:56 +01:00
|
|
|
try {
|
|
|
|
if (chunks.size() < 1024) {
|
2015-05-07 10:15:51 +02:00
|
|
|
if (regions.size() > 0) {
|
|
|
|
final ChunkLoc loc = regions.get(0);
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log("&3Updating .mcr: " + loc.x + ", " + loc.z + " (aprrox 1024 chunks)");
|
|
|
|
PS.log(" - Remaining: " + regions.size());
|
2015-05-07 10:15:51 +02:00
|
|
|
chunks.addAll(getChunks(loc));
|
|
|
|
regions.remove(0);
|
|
|
|
System.gc();
|
|
|
|
}
|
2015-03-24 06:27:56 +01:00
|
|
|
}
|
|
|
|
if (chunks.size() > 0) {
|
2015-04-07 09:57:07 +02:00
|
|
|
long diff = System.currentTimeMillis() + 25;
|
2015-06-07 21:37:40 +02:00
|
|
|
if (System.currentTimeMillis() - last > 1200 && last != 0) {
|
2015-04-07 09:57:07 +02:00
|
|
|
last = 0;
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log(C.PREFIX.s() + "Detected low TPS. Rescheduling in 30s");
|
2015-04-07 09:57:07 +02:00
|
|
|
while (chunks.size() > 0) {
|
|
|
|
ChunkLoc chunk = chunks.get(0);
|
|
|
|
chunks.remove(0);
|
2015-06-11 02:56:53 +02:00
|
|
|
regenerateRoad(world, chunk, extend);
|
2015-04-07 09:57:07 +02:00
|
|
|
ChunkManager.manager.unloadChunk(world, chunk);
|
|
|
|
}
|
|
|
|
Bukkit.getScheduler().cancelTask(BukkitHybridUtils.this.task);
|
|
|
|
TaskManager.runTaskLater(new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
2015-06-11 02:56:53 +02:00
|
|
|
scheduleRoadUpdate(world, regions, extend);
|
2015-04-07 09:57:07 +02:00
|
|
|
}
|
2015-07-11 17:59:40 +02:00
|
|
|
}, 600);
|
2015-04-07 09:57:07 +02:00
|
|
|
return;
|
|
|
|
}
|
2015-06-07 21:37:40 +02:00
|
|
|
if (System.currentTimeMillis() - last < 1000) {
|
2015-05-07 10:15:51 +02:00
|
|
|
while (System.currentTimeMillis() < diff && chunks.size() > 0) {
|
2015-04-07 09:57:07 +02:00
|
|
|
ChunkLoc chunk = chunks.get(0);
|
|
|
|
chunks.remove(0);
|
2015-06-11 02:56:53 +02:00
|
|
|
regenerateRoad(world, chunk, extend);
|
2015-04-07 09:57:07 +02:00
|
|
|
ChunkManager.manager.unloadChunk(world, chunk);
|
|
|
|
}
|
2015-03-24 06:27:56 +01:00
|
|
|
}
|
2015-04-07 09:57:07 +02:00
|
|
|
last = System.currentTimeMillis();
|
2015-03-24 06:27:56 +01:00
|
|
|
}
|
|
|
|
} catch (final Exception e) {
|
2015-05-07 10:15:51 +02:00
|
|
|
e.printStackTrace();
|
2015-03-24 06:27:56 +01:00
|
|
|
final ChunkLoc loc = regions.get(0);
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log("&c[ERROR]&7 Could not update '" + world + "/region/r." + loc.x + "." + loc.z + ".mca' (Corrupt chunk?)");
|
2015-03-24 06:27:56 +01:00
|
|
|
final int sx = loc.x << 5;
|
|
|
|
final int sz = loc.z << 5;
|
|
|
|
for (int x = sx; x < (sx + 32); x++) {
|
|
|
|
for (int z = sz; z < (sz + 32); z++) {
|
|
|
|
ChunkManager.manager.unloadChunk(world, new ChunkLoc(x, z));
|
2015-03-10 10:01:06 +01:00
|
|
|
}
|
2015-03-11 09:47:22 +01:00
|
|
|
}
|
2015-07-03 14:15:20 +02:00
|
|
|
PS.log("&d - Potentially skipping 1024 chunks");
|
|
|
|
PS.log("&d - TODO: recommend chunkster if corrupt");
|
2015-03-10 10:01:06 +01:00
|
|
|
}
|
2015-02-21 04:43:08 +01:00
|
|
|
}
|
|
|
|
}
|
2015-06-07 21:37:40 +02:00
|
|
|
}, 20, 20);
|
2015-02-21 04:43:08 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|