diff --git a/.gitignore b/.gitignore index 32858aa..70069c8 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,7 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* + +/bin/ +.classpath +*.classpath diff --git a/.project b/.project new file mode 100644 index 0000000..6d94092 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + iieLoadSaveEntireWorld + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..3a21537 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/src/iieLoadSaveEntireWorld/ChunkLoaderAPI.java b/src/iieLoadSaveEntireWorld/ChunkLoaderAPI.java new file mode 100644 index 0000000..0a0fd58 --- /dev/null +++ b/src/iieLoadSaveEntireWorld/ChunkLoaderAPI.java @@ -0,0 +1,31 @@ +package iieLoadSaveEntireWorld; + +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; + } + +} diff --git a/src/iieLoadSaveEntireWorld/ConfigProcess.java b/src/iieLoadSaveEntireWorld/ConfigProcess.java new file mode 100644 index 0000000..104c2f1 --- /dev/null +++ b/src/iieLoadSaveEntireWorld/ConfigProcess.java @@ -0,0 +1,58 @@ +package iieLoadSaveEntireWorld; + +import org.bukkit.configuration.file.FileConfiguration; + +public class ConfigProcess implements Runnable { + + //STATIC + private static final Main plugin = new Main(); + private static final FileConfiguration config = plugin.getConfig(); + + static final boolean isNew(String name) + { + return !config.contains(name); + } + static final WorldObject getUnfinished(String name) + { + return new WorldObject + ( + config.getInt(name + ".width"), + new int[] + { + config.getInt(name + ".currentRegion.x"), + config.getInt(name + ".currentRegion.z") + }, + new int[] + { + config.getInt(name + ".lowerleft.x"), + config.getInt(name + ".lowerleft.z") + }, + config.getInt(name + ".n"), + config.getInt(name + ".c"), + config.getInt(name + ".D"), + config.getInt(name + ".d"), + config.getInt(name + ".B") == 1 + ); + } + + + //INSTANCE + private final String name = TaskManager.loadProcess.worldname; + public final void run() + { + config.set(".currentRegion.x", TaskManager.loadProcess.currentRegion[0]); + config.set(".currentRegion.z", TaskManager.loadProcess.currentRegion[1]); + config.set(".n", TaskManager.loadProcess.n); + config.set(".c", TaskManager.loadProcess.c); + config.set(".D", TaskManager.loadProcess.D); + config.set(".d", TaskManager.loadProcess.d); + config.set(".B", TaskManager.loadProcess.B ? 1 : 0); + plugin.saveConfig(); + } + final void finish() + { + config.set("finished", name); + config.set(name, null); + plugin.saveConfig(); + } +} diff --git a/src/iieLoadSaveEntireWorld/LoadProcess.java b/src/iieLoadSaveEntireWorld/LoadProcess.java new file mode 100644 index 0000000..c87ab31 --- /dev/null +++ b/src/iieLoadSaveEntireWorld/LoadProcess.java @@ -0,0 +1,170 @@ +package iieLoadSaveEntireWorld; + +import org.bukkit.Bukkit; +import org.bukkit.World; + +public class LoadProcess implements Runnable +{ + //=================================INIT================================= + + final World world; + final String worldname; + final int totalRegions; + int[] currentRegion; + + + LoadProcess(String name, WorldObject newWorld) + { + world = Bukkit.getWorld(name); + worldname = name; + + totalRegions = newWorld.width * newWorld.width; + currentRegion = newWorld.current; + + this.lowerleft = newWorld.lowerleft; + allChunkCoords = generateAllChunkCoords(newWorld.width, newWorld.lowerleft); + } + LoadProcess(String name) + { + final WorldObject unfinished = ConfigProcess.getUnfinished(name); + + world = Bukkit.getWorld(name); + worldname = name; + + totalRegions = unfinished.width * unfinished.width; + currentRegion = unfinished.current; + + this.lowerleft = unfinished.lowerleft; + allChunkCoords = generateAllChunkCoords(unfinished.width, unfinished.lowerleft); + + this.n = unfinished.n; + this.c = unfinished.c; + this.D = unfinished.D; + this.d = unfinished.d; + this.B = unfinished.B; + } + + + //===============================PATTERN================================ + + /* 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. + */ + + int n = 1; //number + int c = 1; //direction of travel: E,N,W,S - 1,2,3,4 + int D = 1; //distance to travel + int d = 0; //distance already traveled + boolean B = false; //OK to change direction? + + private final void setNextRegion() + { + n++; + if (d != D) d++; + else + { + d = 0; + D++; + switch (c){ + case 1 : currentRegion[0]++; + case 2 : currentRegion[1]++; + case 3 : currentRegion[0]--; + case 4 : + currentRegion[1]--; + c = B ? 1 : c + 1; + } + B = !B; + } + } + final boolean isFinished(){ + return n == totalRegions; + } + + + //===============================CHUNK MAP============================== + + private final int[] lowerleft; + private final int[][][][][] allChunkCoords; + private final int[][][][][] generateAllChunkCoords(int w,int[] lowerleft) + { + int[][][][][] allChunkCoords = new int[w][w][32][32][2]; + + int regionX = lowerleft[0]; + int regionZ = lowerleft[1]; + boolean negX = true; + boolean negZ = true; + int chunkX = 0; + int chunkZ = 0; + for (int[][][][] xRowRegions : allChunkCoords) + { + regionZ = lowerleft[1]; + negZ = true; + for (int[][][] region : xRowRegions) + { + chunkX = 0; + for (int[][] xRowChunks : region) + { + 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; + } + return allChunkCoords; + } + private final int[][][] getChunksCurrentRegion(){ + return + allChunkCoords + [ currentRegion[0] - lowerleft[0] ] + [ currentRegion[1] - lowerleft[1] ]; + } + + + //==================================RUN================================= + + boolean ready = true; + public final void run() + { + if (!ready) return; + else ready = false; + + final int[][][] r = getChunksCurrentRegion(); + for (int[][] xRow : r) + { + for (int[] chunk : xRow) + { + world.loadChunk(chunk[0], chunk[1], true); + world.unloadChunk(chunk[0], chunk[1]); + } + } + setNextRegion(); + + if (isFinished()) TaskManager.finish(); + else ready = true; + } +} diff --git a/src/iieLoadSaveEntireWorld/Main.java b/src/iieLoadSaveEntireWorld/Main.java new file mode 100644 index 0000000..fdcc8d7 --- /dev/null +++ b/src/iieLoadSaveEntireWorld/Main.java @@ -0,0 +1,13 @@ +package iieLoadSaveEntireWorld; + +import org.bukkit.plugin.java.JavaPlugin; + +public class Main extends JavaPlugin { + + public void onEnable() + { + saveDefaultConfig(); + getCommand("beginfullmapload").setExecutor(new TaskManager.StartCommand()); + getCommand("stopfullmapload").setExecutor(new TaskManager.StopCommand()); + } +} diff --git a/src/iieLoadSaveEntireWorld/TaskManager.java b/src/iieLoadSaveEntireWorld/TaskManager.java new file mode 100644 index 0000000..88bb32f --- /dev/null +++ b/src/iieLoadSaveEntireWorld/TaskManager.java @@ -0,0 +1,107 @@ +package iieLoadSaveEntireWorld; + +import org.bukkit.Bukkit; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitTask; + +public class TaskManager { + + private static final Main plugin = new Main(); + + static boolean inProgress = false; + static LoadProcess loadProcess; + static ConfigProcess configProcess; + static BukkitTask loadTask; + static BukkitTask configTask; + + //===================================CONTROLS=================================== + private static final void start(LoadProcess loadProcess) + { + inProgress = true; + TaskManager.loadProcess = loadProcess; + TaskManager.loadTask = Bukkit.getScheduler().runTaskTimer( plugin, loadProcess, 0, 10 ); + TaskManager.configTask = Bukkit.getScheduler().runTaskTimer( plugin, new ConfigProcess(), 0, 200 ); + } + static final void finish() + { + configProcess.finish(); + loadTask.cancel(); + configTask.cancel(); + + loadProcess = null; + configProcess = null; + loadTask = null; + configTask = null; + + inProgress = false; + } + static final boolean stop() + { + if (inProgress) + { + if (loadProcess.isFinished()) finish(); + else + { + loadTask.cancel(); + configTask.cancel(); + configProcess.run(); + + loadProcess = null; + configProcess = null; + loadTask = null; + configTask = null; + + inProgress = false; + } + return true; + } + return false; + } + + + //===================================COMMANDS=================================== + + static final class StartCommand implements CommandExecutor + { + @Override + public final boolean onCommand(CommandSender sender, Command label, String command, String[] args) + { + String name = ((Player)sender).getWorld().getName(); + if (inProgress) + { + sender.sendMessage("a process is already running (" + name + "). /StopLoadSave to stop."); + return false; + } + else inProgress = true; + + if (ConfigProcess.isNew(name)) + { + sender.sendMessage("starting..."); + start(new LoadProcess(name, WorldObject.generate(args))); + } + else + { + sender.sendMessage("resuming..."); + start(new LoadProcess(name)); + } + return true; + } + } + static final class StopCommand implements CommandExecutor + { + @Override + public final boolean onCommand(CommandSender sender, Command label, String command, String[] args) + { + if (stop()) + { + sender.sendMessage("stopped."); + return true; + } + sender.sendMessage("nothing to stop."); + return false; + } + } +} diff --git a/src/iieLoadSaveEntireWorld/WorldObject.java b/src/iieLoadSaveEntireWorld/WorldObject.java new file mode 100644 index 0000000..9380c0c --- /dev/null +++ b/src/iieLoadSaveEntireWorld/WorldObject.java @@ -0,0 +1,208 @@ +package iieLoadSaveEntireWorld; + +public class WorldObject { + + final int width; + final int[] lowerleft; + int[] current; + int n; + int c; + int D; + int d; + boolean B; + + WorldObject() + { + width = 44; + lowerleft = new int[] { -22, -22 }; + current = new int[] { -1, -1 }; + } + WorldObject(int width, int[] lowerleft, int[] center) + { + this.width = width; + this.lowerleft = lowerleft; + this.current = center; + } + WorldObject( + int width, int[] lowerleft, int[] current, + int n, int c, int D, int d, boolean B + ) + { + this.width = width; + this.lowerleft = lowerleft; + this.current = current; + this.n = n; + this.c = c; + this.D = D; + this.D = d; + this.B = B; + } + + static final WorldObject generate(String[] args) + { + if (args.length == 0) + { + return new WorldObject(); + } + int[] bounds = regionBounds(new ParsedArgs(args)); + + return new WorldObject( + bounds[2] - bounds[0], + new int[]{ bounds[0], bounds[2] }, + new int[]{ + bounds[0] - 1 + (bounds[1]-bounds[0] + 1)/2, + bounds[2] - 1 + (bounds[3]-bounds[2] + 1)/2 + } + ); + } + //============================================================================== + private static final class ParsedArgs + { + private static final int defaultRadius = 11264; + private static final int[] defaultCenter = new int[]{0,0}; + + final int radius; + final int[] center; + ParsedArgs (String[] args) + { + if (isInt(args[0]) && args[0] != "0") + { + radius = Integer.parseInt(args[0]); + } + else + { + radius = defaultRadius; + } + if (args.length > 2 && isInt(args[1]) && isInt(args[2])) + { + center = new int[]{ Integer.parseInt(args[1]), + Integer.parseInt(args[2]) }; + } + else + { + center = defaultCenter; + } + } + private static final boolean isInt(String arg) + { + int length = arg.length(); + int i = 0; + if (arg.charAt(0) == '-') + { + if (length == 1) return false; + else i = 1; + } + for (; i < length; i++) + { + char c = arg.charAt(i); + if (c < '0' || c > '9') + return false; + } + return true; + } + } + //============================================================================== + private static final int[] regionBounds(ParsedArgs a) + { + int[] bounds = new int[] + { + // [ get region ] [ get block ] + Math.floorDiv( a.center[0] - a.radius, 512 ), + Math.floorDiv( a.center[0] + a.radius, 512 ), + Math.floorDiv( a.center[1] - a.radius, 512 ), + Math.floorDiv( a.center[1] + a.radius, 512 ) + }; + + //add margins------------ + + final int[] edges = new int[4]; + final int[] radii = new int[4]; + final boolean[] margin = new boolean[4]; + + //get block edge farthest from center + edges[0] = bounds[0] *512; + edges[0] = (bounds[1]+1) *512 - 1; + edges[0] = bounds[2] *512; + edges[0] = (bounds[3]+1) *512 - 1; + + //get radius from center to far block edge of region + radii[0] = Math.abs(a.center[0] - edges[0]); + radii[1] = Math.abs(a.center[0] - edges[1]); + radii[2] = Math.abs(a.center[1] - edges[2]); + radii[3] = Math.abs(a.center[1] - edges[3]); + + //compare to original block radius, if difference is < 4 chunks add a region width + if (radii[0] - a.radius < 64) { bounds[0] -= 1; margin[0] = true; } + if (radii[1] - a.radius < 64) { bounds[1] += 1; margin[1] = true; } + if (radii[2] - a.radius < 64) { bounds[2] -= 1; margin[2] = true; } + if (radii[3] - a.radius < 64) { bounds[3] += 1; margin[3] = true; } + + //resquare the selection + if (!margin[0]) + if (!margin[1]) + if (!margin[2]) + if (!margin[3])//-----------0000 + return bounds; + else//----------------------0001 + if (radii[0] < radii[1]) + bounds[0]++; + else + bounds[1]++; + else + if (!margin[3])//-----------0010 + if (radii[0] < radii[1]) + bounds[0]++; + else + bounds[1]++; + else//----------------------0011 + { + bounds[0]++; + bounds[1]++; + } + else + if (!margin[2]) + if (!margin[3])//-----------0100 + if (radii[2] < radii[3]) + bounds[2]++; + else + bounds[3]++; + else//----------------------0101 + return bounds; + else + if (!margin[3])//-----------0110 + return bounds; + else//----------------------0111 + bounds[0]++; + else + if (margin[1]) + if (margin[2]) + if (margin[3])//------------1111 + return bounds; + else//----------------------1110 + bounds[3]++; + else + if (margin[3])//------------1101 + bounds[2]++; + else//----------------------1100 + { + bounds[2]++; + bounds[3]++; + } + else + if (margin[2]) + if (margin[3])//------------1011 + bounds[1]++; + else//----------------------1010 + return bounds; + else + if (margin[3])//------------1001 + return bounds; + else//----------------------1000 + if (radii[2] == radii[3]) + bounds[0]++; + else + bounds[1]++; + + return bounds; + } +} diff --git a/src/unused/CacheOld.java b/src/unused/CacheOld.java new file mode 100644 index 0000000..2267c14 --- /dev/null +++ b/src/unused/CacheOld.java @@ -0,0 +1,123 @@ +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 cacheUnfinished; + static void generate() + { + maxNameLength = Main.config.getInt("max name length"); + Set 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 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 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; + } + } +*/ +} diff --git a/src/unused/LoadSaveProcessOld.java b/src/unused/LoadSaveProcessOld.java new file mode 100644 index 0000000..c141df4 --- /dev/null +++ b/src/unused/LoadSaveProcessOld.java @@ -0,0 +1,236 @@ +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; + } + } +} diff --git a/target/config.yml b/target/config.yml new file mode 100644 index 0000000..e69de29 diff --git a/target/plugin.yml b/target/plugin.yml new file mode 100644 index 0000000..4d5b3c3 --- /dev/null +++ b/target/plugin.yml @@ -0,0 +1,6 @@ + main: iieLoadSaveEntireWorld.Main + version: 1.0.0 + name: LoadSaveEntireWorld + commands: + loadsaveentireworld: + description: loads and saves the entire map, in 32x32 chunk sections \ No newline at end of file