added crashResume and some other changes
This commit is contained in:
parent
19b4a31775
commit
590b052e08
8 changed files with 107 additions and 438 deletions
|
@ -12,13 +12,13 @@ public class ConfigProcess implements Runnable {
|
||||||
{
|
{
|
||||||
return !config.contains(name);
|
return !config.contains(name);
|
||||||
}
|
}
|
||||||
static final void addNew(String name, int width, int[] lowerleft, int[] center)
|
static final void addNew(String name, WorldObject newWorld)
|
||||||
{
|
{
|
||||||
config.set(name + ".width", width);
|
config.set(name + ".width", newWorld.width);
|
||||||
config.set(name + ".lowerleft.x", lowerleft[0]);
|
config.set(name + ".lowerleft.x", newWorld.lowerleft[0]);
|
||||||
config.set(name + ".lowerleft.z", lowerleft[1]);
|
config.set(name + ".lowerleft.z", newWorld.lowerleft[1]);
|
||||||
config.set(name + ".currentRegion.x", center[0]);
|
config.set(name + ".currentRegion.x", newWorld.current[0]);
|
||||||
config.set(name + ".currentRegion.z", center[1]);
|
config.set(name + ".currentRegion.z", newWorld.current[1]);
|
||||||
config.set(name + ".n", 1);
|
config.set(name + ".n", 1);
|
||||||
config.set(name + ".c", 1);
|
config.set(name + ".c", 1);
|
||||||
config.set(name + ".D", 1);
|
config.set(name + ".D", 1);
|
||||||
|
@ -48,10 +48,26 @@ public class ConfigProcess implements Runnable {
|
||||||
config.getInt(name + ".B") == 1
|
config.getInt(name + ".B") == 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
static final boolean crashResume()
|
||||||
|
{
|
||||||
|
return config.contains("@ CRASH RESUME");
|
||||||
|
}
|
||||||
|
static final String getCrashResume()
|
||||||
|
{
|
||||||
|
return config.getString("@ CRASH RESUME");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//INSTANCE
|
//INSTANCE
|
||||||
private final String name = TaskManager.loadProcess.worldname;
|
private final String name = TaskManager.loadProcess.worldname;
|
||||||
|
ConfigProcess()
|
||||||
|
{
|
||||||
|
config.set("@ CRASH RESUME", name);
|
||||||
|
}
|
||||||
|
ConfigProcess(boolean b)
|
||||||
|
{
|
||||||
|
//don't create crash resume
|
||||||
|
}
|
||||||
public final void run()
|
public final void run()
|
||||||
{
|
{
|
||||||
final int[] currentRegion = TaskManager.loadProcess.currentRegion;
|
final int[] currentRegion = TaskManager.loadProcess.currentRegion;
|
||||||
|
@ -74,8 +90,17 @@ public class ConfigProcess implements Runnable {
|
||||||
}
|
}
|
||||||
final void finish()
|
final void finish()
|
||||||
{
|
{
|
||||||
config.set("finished worlds, fully saved", name);
|
config.set("@ FINISHED WORLDS", name);
|
||||||
|
config.set("@ CRASH RESUME", null);
|
||||||
config.set(name, null);
|
config.set(name, null);
|
||||||
plugin.saveConfig();
|
plugin.saveConfig();
|
||||||
}
|
}
|
||||||
|
final void stop()
|
||||||
|
{
|
||||||
|
run();
|
||||||
|
config.set("@ CRASH RESUME", null);
|
||||||
|
plugin.saveConfig();
|
||||||
|
Bukkit.getLogger().info("...stopping world-load");
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,22 +7,24 @@ public class LoadProcess implements Runnable
|
||||||
{
|
{
|
||||||
//=================================INIT=================================
|
//=================================INIT=================================
|
||||||
|
|
||||||
final World world;
|
final World world;
|
||||||
final String worldname;
|
final String worldname;
|
||||||
final int totalRegions;
|
final int totalRegions;
|
||||||
int[] currentRegion;
|
int[] currentRegion;
|
||||||
|
|
||||||
|
|
||||||
LoadProcess(String name, WorldObject newWorld)
|
LoadProcess(String name, WorldObject newWorld)
|
||||||
{
|
{
|
||||||
|
ConfigProcess.addNew(name, newWorld);
|
||||||
|
|
||||||
world = Bukkit.getWorld(name);
|
world = Bukkit.getWorld(name);
|
||||||
worldname = name;
|
worldname = name;
|
||||||
|
|
||||||
totalRegions = newWorld.width * newWorld.width;
|
totalRegions = newWorld.width * newWorld.width;
|
||||||
currentRegion = newWorld.current;
|
currentRegion = newWorld.current;
|
||||||
|
|
||||||
this.lowerleft = newWorld.lowerleft;
|
lowerleft = newWorld.lowerleft;
|
||||||
allChunkCoords = generateAllChunkCoords(newWorld.width, newWorld.lowerleft);
|
allChunkCoords = generateAllChunkCoords(newWorld.width);
|
||||||
}
|
}
|
||||||
LoadProcess(String name)
|
LoadProcess(String name)
|
||||||
{
|
{
|
||||||
|
@ -34,14 +36,14 @@ public class LoadProcess implements Runnable
|
||||||
totalRegions = unfinished.width * unfinished.width;
|
totalRegions = unfinished.width * unfinished.width;
|
||||||
currentRegion = unfinished.current;
|
currentRegion = unfinished.current;
|
||||||
|
|
||||||
this.lowerleft = unfinished.lowerleft;
|
lowerleft = unfinished.lowerleft;
|
||||||
allChunkCoords = generateAllChunkCoords(unfinished.width, unfinished.lowerleft);
|
allChunkCoords = generateAllChunkCoords(unfinished.width);
|
||||||
|
|
||||||
this.n = unfinished.n;
|
n = unfinished.n;
|
||||||
this.c = unfinished.c;
|
c = unfinished.c;
|
||||||
this.D = unfinished.D;
|
D = unfinished.D;
|
||||||
this.d = unfinished.d;
|
d = unfinished.d;
|
||||||
this.B = unfinished.B;
|
B = unfinished.B;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,14 +73,15 @@ public class LoadProcess implements Runnable
|
||||||
int d = 0; //distance already traveled
|
int d = 0; //distance already traveled
|
||||||
boolean B = false; //OK to increase distance?
|
boolean B = false; //OK to increase distance?
|
||||||
|
|
||||||
private final void setNextRegion()
|
private final boolean setNextRegion()
|
||||||
{
|
{
|
||||||
n++;
|
n++;
|
||||||
|
if (n == totalRegions) return false;
|
||||||
if (d != D) d++;
|
if (d != D) d++;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d = 0; if (B) D++; B = !B;
|
d = 0; if (B) D++;
|
||||||
|
B = !B;
|
||||||
c = c == 4 ? 1 : c + 1;
|
c = c == 4 ? 1 : c + 1;
|
||||||
}
|
}
|
||||||
switch (c)
|
switch (c)
|
||||||
|
@ -88,9 +91,7 @@ public class LoadProcess implements Runnable
|
||||||
case 3 : currentRegion[0]--; break;
|
case 3 : currentRegion[0]--; break;
|
||||||
case 4 : currentRegion[1]--; break;
|
case 4 : currentRegion[1]--; break;
|
||||||
}
|
}
|
||||||
}
|
return true;
|
||||||
final boolean isFinished(){
|
|
||||||
return n == totalRegions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ public class LoadProcess implements Runnable
|
||||||
|
|
||||||
private final int[] lowerleft;
|
private final int[] lowerleft;
|
||||||
private final int[][][][][] allChunkCoords;
|
private final int[][][][][] allChunkCoords;
|
||||||
private final int[][][][][] generateAllChunkCoords(int w,int[] lowerleft)
|
private final int[][][][][] generateAllChunkCoords(int w)
|
||||||
{
|
{
|
||||||
int[][][][][] allChunkCoords = new int[w][w][32][32][2];
|
int[][][][][] allChunkCoords = new int[w][w][32][32][2];
|
||||||
|
|
||||||
|
@ -145,8 +146,7 @@ public class LoadProcess implements Runnable
|
||||||
|
|
||||||
|
|
||||||
//==================================RUN=================================
|
//==================================RUN=================================
|
||||||
|
private static volatile boolean ready = true;
|
||||||
private boolean ready = true;
|
|
||||||
public final void run()
|
public final void run()
|
||||||
{
|
{
|
||||||
if (!ready) return;
|
if (!ready) return;
|
||||||
|
@ -161,9 +161,10 @@ public class LoadProcess implements Runnable
|
||||||
world.unloadChunk(chunk[0], chunk[1]);
|
world.unloadChunk(chunk[0], chunk[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setNextRegion();
|
if (!setNextRegion())
|
||||||
|
{
|
||||||
if (isFinished()) TaskManager.finish();
|
TaskManager.finish();
|
||||||
else ready = true;
|
}
|
||||||
|
ready = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package iieLoadSaveEntireWorld;
|
package iieLoadSaveEntireWorld;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
|
||||||
public class Main extends JavaPlugin {
|
public class Main extends JavaPlugin {
|
||||||
|
@ -14,5 +15,10 @@ public class Main extends JavaPlugin {
|
||||||
TaskManager.plugin = this;
|
TaskManager.plugin = this;
|
||||||
ConfigProcess.plugin = this;
|
ConfigProcess.plugin = this;
|
||||||
ConfigProcess.config = getConfig();
|
ConfigProcess.config = getConfig();
|
||||||
|
|
||||||
|
if (TaskManager.crashResume())
|
||||||
|
{
|
||||||
|
Bukkit.getLogger().info("...resuming from crash");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,9 @@ public class TaskManager {
|
||||||
|
|
||||||
static Main plugin;
|
static Main plugin;
|
||||||
|
|
||||||
static boolean inProgress = false;
|
static boolean inProgress = false;
|
||||||
|
static boolean canRun = true;
|
||||||
|
|
||||||
static LoadProcess loadProcess;
|
static LoadProcess loadProcess;
|
||||||
static ConfigProcess configProcess;
|
static ConfigProcess configProcess;
|
||||||
static BukkitTask loadTask;
|
static BukkitTask loadTask;
|
||||||
|
@ -31,11 +33,24 @@ public class TaskManager {
|
||||||
loadProcess = new LoadProcess(name);
|
loadProcess = new LoadProcess(name);
|
||||||
isNew = false;
|
isNew = false;
|
||||||
}
|
}
|
||||||
TaskManager.configProcess = new ConfigProcess();
|
configProcess = new ConfigProcess();
|
||||||
TaskManager.loadTask = Bukkit.getScheduler().runTaskTimer( plugin, loadProcess, 0, 10 );
|
loadTask = Bukkit.getScheduler().runTaskTimer( plugin, loadProcess, 0, 100 );
|
||||||
TaskManager.configTask = Bukkit.getScheduler().runTaskTimer( plugin, configProcess, 0, 200 );
|
configTask = Bukkit.getScheduler().runTaskTimer( plugin, configProcess, 0, 200 );
|
||||||
return isNew;
|
return isNew;
|
||||||
}
|
}
|
||||||
|
static final boolean crashResume()
|
||||||
|
{
|
||||||
|
if (ConfigProcess.crashResume())
|
||||||
|
{
|
||||||
|
loadProcess = new LoadProcess(ConfigProcess.getCrashResume());
|
||||||
|
configProcess = new ConfigProcess(false);
|
||||||
|
|
||||||
|
loadTask = Bukkit.getScheduler().runTaskTimer( plugin, loadProcess, 1200, 100 );
|
||||||
|
configTask = Bukkit.getScheduler().runTaskTimer( plugin, configProcess, 1200, 200 );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
static final void finish()
|
static final void finish()
|
||||||
{
|
{
|
||||||
loadTask.cancel();
|
loadTask.cancel();
|
||||||
|
@ -53,12 +68,12 @@ public class TaskManager {
|
||||||
{
|
{
|
||||||
if (inProgress)
|
if (inProgress)
|
||||||
{
|
{
|
||||||
if (loadProcess.isFinished()) finish();
|
if (loadProcess.n == loadProcess.totalRegions) finish();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
loadTask.cancel();
|
loadTask.cancel();
|
||||||
configTask.cancel();
|
configTask.cancel();
|
||||||
configProcess.run();
|
configProcess.stop();
|
||||||
|
|
||||||
loadProcess = null;
|
loadProcess = null;
|
||||||
configProcess = null;
|
configProcess = null;
|
||||||
|
|
|
@ -45,15 +45,27 @@ public class WorldObject {
|
||||||
return new WorldObject();
|
return new WorldObject();
|
||||||
}
|
}
|
||||||
int[] bounds = regionBounds(new ParsedArgs(args));
|
int[] bounds = regionBounds(new ParsedArgs(args));
|
||||||
|
return new WorldObject
|
||||||
return new WorldObject(
|
(
|
||||||
bounds[2] - bounds[0],
|
bounds[2] - bounds[0],//----------------------------width
|
||||||
new int[]{ bounds[0], bounds[2] },
|
new int[] { bounds[0], bounds[2] },//---------------lowerleft
|
||||||
new int[]{
|
new int[] { //--------------------------------------center
|
||||||
bounds[0] - 1 + (bounds[1]-bounds[0] + 1)/2,
|
bounds[0] - 1 + (bounds[1]-bounds[0] + 1)/2,
|
||||||
bounds[2] - 1 + (bounds[3]-bounds[2] + 1)/2
|
bounds[2] - 1 + (bounds[3]-bounds[2] + 1)/2
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
/* for even widths, the math above returns the
|
||||||
|
* minimum center not the maximum center. So:
|
||||||
|
*
|
||||||
|
* * * * *
|
||||||
|
* * X X *
|
||||||
|
* * O X *
|
||||||
|
* * * * *
|
||||||
|
*
|
||||||
|
* the spiral pattern used in LoadProcess rotates
|
||||||
|
* counter-clockwise, so it must begin at minimum
|
||||||
|
* center.
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
private static final class ParsedArgs
|
private static final class ParsedArgs
|
||||||
|
|
|
@ -1,123 +0,0 @@
|
||||||
package unused;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import iieLoadSaveEntireWorld.Main;
|
|
||||||
|
|
||||||
public class CacheOld
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
|
|
||||||
private static int maxNameLength;
|
|
||||||
private static char[][] listUnfinished;
|
|
||||||
private static Map<String,WorldStatus> cacheUnfinished;
|
|
||||||
static void generate()
|
|
||||||
{
|
|
||||||
maxNameLength = Main.config.getInt("max name length");
|
|
||||||
Set<String> set = Main.unfinished.getKeys(false);
|
|
||||||
populateList(set);
|
|
||||||
populateCache(set);
|
|
||||||
}
|
|
||||||
static void addWorld()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
static void saveProgress()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
static void finish(String name)
|
|
||||||
{
|
|
||||||
//TODO
|
|
||||||
}
|
|
||||||
static void addUnfinished(int width, int[] center, int[] lowerleft, String name)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
static boolean isUnfinished(String name){
|
|
||||||
int i = 0;
|
|
||||||
boolean match = true;
|
|
||||||
for (char[] world : listUnfinished)
|
|
||||||
{
|
|
||||||
for (char c : name.toCharArray())
|
|
||||||
{
|
|
||||||
if (c != world[i]){ match = false; break; }
|
|
||||||
}
|
|
||||||
if (match) break;
|
|
||||||
i = 0;
|
|
||||||
match = true;
|
|
||||||
}
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
private static void populateList(Set<String> set)
|
|
||||||
{
|
|
||||||
char[][] listUnfinished = new char[set.size()][maxNameLength];
|
|
||||||
int i = 0;
|
|
||||||
int ii = 0;
|
|
||||||
for (String name : set)
|
|
||||||
{
|
|
||||||
for (char c : name.toCharArray())
|
|
||||||
{
|
|
||||||
listUnfinished[i][ii] = c;
|
|
||||||
ii++;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
ii = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private static void populateCache(Set<String> set)
|
|
||||||
{
|
|
||||||
String path;
|
|
||||||
for (String name : set){
|
|
||||||
path = "unfinishedWorlds." + name + ".";
|
|
||||||
cacheUnfinished.put(
|
|
||||||
name,
|
|
||||||
new WorldStatus(
|
|
||||||
Main.config.getInt(path + "width"),
|
|
||||||
new int[]{
|
|
||||||
Main.config.getInt(path + "lowerleft.x"),
|
|
||||||
Main.config.getInt(path + "lowerleft.z")},
|
|
||||||
new int[]{
|
|
||||||
Main.config.getInt(path + "currentRegion.x"),
|
|
||||||
Main.config.getInt(path + "currentRegion.z")},
|
|
||||||
Main.config.getInt(path + "n"),
|
|
||||||
Main.config.getInt(path + "c"),
|
|
||||||
Main.config.getInt(path + "D"),
|
|
||||||
Main.config.getInt(path + "d"),
|
|
||||||
Main.config.getBoolean(path + "B")));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static final class WorldStatus
|
|
||||||
{
|
|
||||||
final int width;
|
|
||||||
final int[] lowerleft;
|
|
||||||
int[] currentRegion;
|
|
||||||
int n = 1;
|
|
||||||
int c = 1;
|
|
||||||
int D = 1;
|
|
||||||
int d = 0;
|
|
||||||
boolean B = false;
|
|
||||||
WorldStatus(int width, int[] lowerleft, int[]center)
|
|
||||||
{
|
|
||||||
this.width = width;
|
|
||||||
this.lowerleft = lowerleft;
|
|
||||||
currentRegion = center;
|
|
||||||
}
|
|
||||||
WorldStatus(
|
|
||||||
int width, int[] lowerleft,
|
|
||||||
int[] current, int n, int c, int D, int d, boolean B)
|
|
||||||
{
|
|
||||||
this.width = width;
|
|
||||||
this.lowerleft = lowerleft;
|
|
||||||
currentRegion = current;
|
|
||||||
this.n = n;
|
|
||||||
this.c = c;
|
|
||||||
this.D = D;
|
|
||||||
this.d = d;
|
|
||||||
this.B = B;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
package unused;
|
|
||||||
|
|
||||||
import org.bukkit.Location;
|
|
||||||
|
|
||||||
public class ChunkLoaderAPI {
|
|
||||||
/**This method loads a chunk if the chunk isn't loaded already.
|
|
||||||
* @param locationToLoad
|
|
||||||
* @return True if chunk was already loaded, False if chunk wasn't already loaded
|
|
||||||
*/
|
|
||||||
public static boolean loadChunk(Location locationToLoad){
|
|
||||||
if(!(locationToLoad.getBlock().getChunk().isLoaded())){
|
|
||||||
locationToLoad.getBlock().getChunk().load();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**This method loads a chunk if the chunk isn't loaded already.
|
|
||||||
* @param locationToLoad
|
|
||||||
* @return True if chunk was already unloaded, False if chunk wasn't already unloaded
|
|
||||||
*/
|
|
||||||
public static boolean unloadChunk(Location locationToUnload){
|
|
||||||
if (locationToUnload.getBlock().getChunk().isLoaded()){
|
|
||||||
locationToUnload.getBlock().getChunk().unload();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,236 +0,0 @@
|
||||||
package unused;
|
|
||||||
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
|
|
||||||
public class LoadSaveProcessOld {
|
|
||||||
|
|
||||||
/* the contents of this class are static because
|
|
||||||
* loading and saving an entire world is an intensive process,
|
|
||||||
* and only one save process should be running at a time.
|
|
||||||
*
|
|
||||||
* so only one save process should be TRACKED at a time.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//=============================STATIC FIELDS============================
|
|
||||||
|
|
||||||
static BukkitTask task;
|
|
||||||
|
|
||||||
static int[] startRegion;
|
|
||||||
|
|
||||||
static int[] currentRegion;
|
|
||||||
|
|
||||||
static TranslatedCoordinates savedRegions;
|
|
||||||
|
|
||||||
static int[][][][][] allChunkCoords;
|
|
||||||
|
|
||||||
static RegionPattern regionPattern;
|
|
||||||
|
|
||||||
//INITIALIZE FIELDS
|
|
||||||
static void init(int width, int x, int z){
|
|
||||||
boolean even = width % 2 == 0;
|
|
||||||
int radius = Math.floorDiv(width,2);
|
|
||||||
if (even) radius -=1 ;
|
|
||||||
int lowX = x-radius;
|
|
||||||
int lowZ = z-radius;
|
|
||||||
|
|
||||||
startRegion = new int[] {x,z};
|
|
||||||
currentRegion = startRegion;
|
|
||||||
savedRegions = new TranslatedCoordinates(width,lowX,lowZ);
|
|
||||||
generateAllChunkCoords(width,lowX,lowZ);
|
|
||||||
if (even) regionPattern = new OutwardSpiralPattern();
|
|
||||||
else regionPattern = new CardinalPointsPattern();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===============================PATTERNS===============================
|
|
||||||
|
|
||||||
//ABSTRACT PARENT CLASS
|
|
||||||
static abstract class RegionPattern {
|
|
||||||
static int n = 1; //iteration number
|
|
||||||
abstract void reset(); //reset fields
|
|
||||||
abstract void setNextRegion();
|
|
||||||
}
|
|
||||||
|
|
||||||
//EVEN DIAMETER: OUTWARD SPIRAL PATTERN
|
|
||||||
private static class OutwardSpiralPattern extends RegionPattern {
|
|
||||||
|
|
||||||
/* The pattern:
|
|
||||||
*
|
|
||||||
* 3 | 36 35 34 33 32 31
|
|
||||||
* |
|
|
||||||
* 2 | 17 16 15 14 13 30
|
|
||||||
* |
|
|
||||||
* 1 | 18 05 04 03 12 29
|
|
||||||
* |
|
|
||||||
* Z | 19 06 01 02 11 28
|
|
||||||
* |
|
|
||||||
* -1 | 20 07 08 09 10 27
|
|
||||||
* |
|
|
||||||
* -2 | 21 22 23 24 25 26
|
|
||||||
* +-----------------------
|
|
||||||
* -2 -1 X 1 2 3
|
|
||||||
* etc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static int c; //direction of travel: E,N,W,S - 1,2,3,4
|
|
||||||
static int D; //distance to travel
|
|
||||||
static int d; //distance already traveled
|
|
||||||
static boolean B; //OK to change direction?
|
|
||||||
|
|
||||||
OutwardSpiralPattern(){
|
|
||||||
c = 1;
|
|
||||||
D = 1;
|
|
||||||
d = 0;
|
|
||||||
B = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//interface methods
|
|
||||||
public void reset() {
|
|
||||||
|
|
||||||
}
|
|
||||||
public void setNextRegion() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//ODD DIAMETER: CARDINAL POINTS PATTERN
|
|
||||||
private static class CardinalPointsPattern extends RegionPattern {
|
|
||||||
|
|
||||||
/* The pattern:
|
|
||||||
*
|
|
||||||
* 2 | 23 18 10 14 22
|
|
||||||
* |
|
|
||||||
* 1 | 15 07 02 06 21
|
|
||||||
* |
|
|
||||||
* Z | 11 03 01 05 13
|
|
||||||
* |
|
|
||||||
* -1 | 19 08 04 09 17
|
|
||||||
* |
|
|
||||||
* -2 | 24 16 12 20 25
|
|
||||||
* +-------------------
|
|
||||||
* -2 -1 X 1 2
|
|
||||||
* etc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
private static int[] cardinalPoints; //midpoint of each side
|
|
||||||
|
|
||||||
private static int c; //side: N,W,S,E = 1,2,3,4
|
|
||||||
private static int r; //radius from square center
|
|
||||||
|
|
||||||
private static int d; //distance from cardinal point
|
|
||||||
private static boolean B; //direction from cardinal point
|
|
||||||
|
|
||||||
private static void expR(){ //expand radius, cardinal points
|
|
||||||
r++;
|
|
||||||
cardinalPoints[0]++;
|
|
||||||
cardinalPoints[1]--;
|
|
||||||
cardinalPoints[2]--;
|
|
||||||
cardinalPoints[4]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
CardinalPointsPattern(){
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
//interface methods
|
|
||||||
void reset(){
|
|
||||||
cardinalPoints = new int[] { //each cardinal point contains
|
|
||||||
startRegion[1]+1, //only the dimension that moves
|
|
||||||
startRegion[0]-1,
|
|
||||||
startRegion[1]-1,
|
|
||||||
startRegion[0]+1
|
|
||||||
};
|
|
||||||
n = 1;
|
|
||||||
c = 1;
|
|
||||||
r = 1;
|
|
||||||
d = 0;
|
|
||||||
B = false;
|
|
||||||
}
|
|
||||||
void setNextRegion(){
|
|
||||||
n++;
|
|
||||||
switch (c){
|
|
||||||
case 1 :
|
|
||||||
if (B) currentRegion = new int[] {startRegion[0] + d, cardinalPoints[0]};
|
|
||||||
else; currentRegion = new int[] {startRegion[0] - d, cardinalPoints[0]};
|
|
||||||
case 2 :
|
|
||||||
if (B) currentRegion = new int[] {cardinalPoints[1], startRegion[0] + d};
|
|
||||||
else; currentRegion = new int[] {cardinalPoints[1], startRegion[0] - d};
|
|
||||||
case 3 :
|
|
||||||
if (B) currentRegion = new int[] {startRegion[0] - d, cardinalPoints[2]};
|
|
||||||
else; currentRegion = new int[] {startRegion[0] + d, cardinalPoints[2]};
|
|
||||||
case 4 :
|
|
||||||
if (B) currentRegion = new int[] {cardinalPoints[3], startRegion[0] - d};
|
|
||||||
else; currentRegion = new int[] {cardinalPoints[3], startRegion[0] + d};
|
|
||||||
|
|
||||||
if (r == d) { expR(); d = 0; c = 1; }
|
|
||||||
else { d++; c++; B = !B; }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//=================================UTIL=================================
|
|
||||||
|
|
||||||
//CUSTOM MAP CLASS FOR TRACKING SAVED REGIONS
|
|
||||||
static class TranslatedCoordinates {
|
|
||||||
|
|
||||||
int xAdjust;
|
|
||||||
int zAdjust;
|
|
||||||
boolean[][] savemap;
|
|
||||||
public TranslatedCoordinates(int w, int lowX, int lowZ)
|
|
||||||
{
|
|
||||||
xAdjust = 0 - lowX;
|
|
||||||
zAdjust = 0 - lowZ;
|
|
||||||
savemap = new boolean[w][w];
|
|
||||||
}
|
|
||||||
int x(int x){ return x + xAdjust; }
|
|
||||||
int z(int z){ return z + zAdjust; }
|
|
||||||
|
|
||||||
void save(int x, int z) { savemap[x(x)][z(z)] = true; }
|
|
||||||
boolean isSaved(int x, int z) { return savemap[x(x)][z(z)]; }
|
|
||||||
|
|
||||||
boolean allSaved(){
|
|
||||||
for (boolean[] xRow : savemap){
|
|
||||||
for (boolean region : xRow){
|
|
||||||
if (!region) return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//GENERATE ALL CHUNK COORDINATES
|
|
||||||
private static void generateAllChunkCoords(int d, int lowX, int lowZ) {
|
|
||||||
allChunkCoords = new int[d][d][32][32][2];
|
|
||||||
int regionX = lowX;
|
|
||||||
boolean negX = true;
|
|
||||||
for (int[][][][] xRowRegions : allChunkCoords){
|
|
||||||
int regionZ = lowZ;
|
|
||||||
boolean negZ = true;
|
|
||||||
for (int[][][] region : xRowRegions){
|
|
||||||
int chunkX = 0;
|
|
||||||
for (int[][] xRowChunks : region){
|
|
||||||
int chunkZ = 0;
|
|
||||||
for (int[] chunk : xRowChunks){
|
|
||||||
chunk[0] = (regionX * 32) + (negX ? 0 - chunkX : chunkX);
|
|
||||||
chunk[1] = (regionZ * 32) + (negZ ? 0 - chunkZ : chunkZ);
|
|
||||||
chunkZ++;
|
|
||||||
}
|
|
||||||
chunkX++;
|
|
||||||
}
|
|
||||||
regionZ++;
|
|
||||||
if (negZ)
|
|
||||||
negZ = regionZ < 0;
|
|
||||||
}
|
|
||||||
regionX++;
|
|
||||||
if (negX)
|
|
||||||
negX = regionX < 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue