diff --git a/src/main/java/com/wimbli/WorldBorder/BorderData.java b/src/main/java/com/wimbli/WorldBorder/BorderData.java index ce2196a..6cfa84b 100644 --- a/src/main/java/com/wimbli/WorldBorder/BorderData.java +++ b/src/main/java/com/wimbli/WorldBorder/BorderData.java @@ -321,7 +321,33 @@ public class BorderData private double getSafeY(World world, int X, int Y, int Z, boolean flying) { // artificial height limit of 127 added for Nether worlds since CraftBukkit still incorrectly returns 255 for their max height, leading to players sent to the "roof" of the Nether - final int limTop = (world.getEnvironment() == World.Environment.NETHER) ? 125 : world.getMaxHeight() - 2; + final boolean isNether = world.getEnvironment() == World.Environment.NETHER; + int limTop = isNether ? 125 : world.getMaxHeight() - 2; + final int highestBlockBoundary = Math.min(world.getHighestBlockYAt(X, Z) + 1, limTop); + + // if Y is larger than the world can be and user can fly, return Y - Unless we are in the Nether, we might not want players on the roof + if (flying && Y > limTop && !isNether) + return (double) Y; + + // make sure Y values are within the boundaries of the world. + if (Y > limTop) + { + if (isNether) + Y = limTop; // because of the roof, the nether can not rely on highestBlockBoundary, so limTop has to be used + else + { + if (flying) + Y = limTop; + else + Y = highestBlockBoundary; // there will never be a save block to stand on for Y values > highestBlockBoundary + } + } + if (Y < limBot) + Y = limBot; + + // for non Nether worlds we don't need to check upwards to the world-limit, it is enough to check up to the highestBlockBoundary, unless player is flying + if (!isNether && !flying) + limTop = highestBlockBoundary; // Expanding Y search method adapted from Acru's code in the Nether plugin for(int y1 = Y, y2 = Y; (y1 > limBot) || (y2 < limTop); y1--, y2++){ diff --git a/src/main/java/com/wimbli/WorldBorder/Events/WorldBorderFillStartEvent.java b/src/main/java/com/wimbli/WorldBorder/Events/WorldBorderFillStartEvent.java new file mode 100644 index 0000000..0ebb08b --- /dev/null +++ b/src/main/java/com/wimbli/WorldBorder/Events/WorldBorderFillStartEvent.java @@ -0,0 +1,36 @@ +package com.wimbli.WorldBorder.Events; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import com.wimbli.WorldBorder.WorldFillTask; + + +/** + * Created by Maximvdw on 12.01.2016. + */ +public class WorldBorderFillStartEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + private WorldFillTask fillTask; + + public WorldBorderFillStartEvent(WorldFillTask worldFillTask) + { + this.fillTask = worldFillTask; + } + + @Override + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + + public WorldFillTask getFillTask(){ + return this.fillTask; + } +} diff --git a/src/main/java/com/wimbli/WorldBorder/Events/WorldBorderTrimStartEvent.java b/src/main/java/com/wimbli/WorldBorder/Events/WorldBorderTrimStartEvent.java new file mode 100644 index 0000000..6b685aa --- /dev/null +++ b/src/main/java/com/wimbli/WorldBorder/Events/WorldBorderTrimStartEvent.java @@ -0,0 +1,36 @@ +package com.wimbli.WorldBorder.Events; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import com.wimbli.WorldBorder.WorldTrimTask; + + +/** + * Created by Maximvdw on 12.01.2016. + */ +public class WorldBorderTrimStartEvent extends Event +{ + private static final HandlerList handlers = new HandlerList(); + private WorldTrimTask trimTask; + + public WorldBorderTrimStartEvent(WorldTrimTask trimTask) + { + this.trimTask = trimTask; + } + + @Override + public HandlerList getHandlers() + { + return handlers; + } + + public static HandlerList getHandlerList() + { + return handlers; + } + + public WorldTrimTask getTrimTask(){ + return this.trimTask; + } +} \ No newline at end of file diff --git a/src/main/java/com/wimbli/WorldBorder/WorldFillTask.java b/src/main/java/com/wimbli/WorldBorder/WorldFillTask.java index c904445..6e48066 100644 --- a/src/main/java/com/wimbli/WorldBorder/WorldFillTask.java +++ b/src/main/java/com/wimbli/WorldBorder/WorldFillTask.java @@ -12,6 +12,7 @@ import org.bukkit.Server; import org.bukkit.World; import com.wimbli.WorldBorder.Events.WorldBorderFillFinishedEvent; +import com.wimbli.WorldBorder.Events.WorldBorderFillStartEvent; public class WorldFillTask implements Runnable @@ -117,6 +118,7 @@ public class WorldFillTask implements Runnable } this.readyToGo = true; + Bukkit.getServer().getPluginManager().callEvent(new WorldBorderFillStartEvent(this)); } // for backwards compatibility public WorldFillTask(Server theServer, Player player, String worldName, int fillDistance, int chunksPerRun, int tickFrequency) @@ -383,7 +385,7 @@ public class WorldFillTask implements Runnable private void reportProgress() { lastReport = Config.Now(); - double perc = ((double)(reportTotal + reportNum) / (double)reportTarget) * 100; + double perc = getPercentageCompleted(); if (perc > 100) perc = 100; sendMessage(reportNum + " more chunks processed (" + (reportTotal + reportNum) + " total, ~" + Config.coord.format(perc) + "%" + ")"); reportTotal += reportNum; @@ -467,4 +469,31 @@ public class WorldFillTask implements Runnable { return forceLoad; } + + /** + * Get the percentage completed for the fill task. + * + * @return Percentage + */ + public double getPercentageCompleted() { + return ((double) (reportTotal + reportNum) / (double) reportTarget) * 100; + } + + /** + * Amount of chunks completed for the fill task. + * + * @return Number of chunks processed. + */ + public int getChunksCompleted() { + return reportTotal; + } + + /** + * Total amount of chunks that need to be generated for the fill task. + * + * @return Number of chunks that need to be processed. + */ + public int getChunksTotal() { + return reportTarget; + } } diff --git a/src/main/java/com/wimbli/WorldBorder/WorldTrimTask.java b/src/main/java/com/wimbli/WorldBorder/WorldTrimTask.java index 1a0f256..6be491e 100644 --- a/src/main/java/com/wimbli/WorldBorder/WorldTrimTask.java +++ b/src/main/java/com/wimbli/WorldBorder/WorldTrimTask.java @@ -13,6 +13,7 @@ import org.bukkit.Server; import org.bukkit.World; import com.wimbli.WorldBorder.Events.WorldBorderTrimFinishedEvent; +import com.wimbli.WorldBorder.Events.WorldBorderTrimStartEvent; public class WorldTrimTask implements Runnable @@ -88,6 +89,7 @@ public class WorldTrimTask implements Runnable return; this.readyToGo = true; + Bukkit.getServer().getPluginManager().callEvent(new WorldBorderTrimStartEvent(this)); } public void setTaskID(int ID) @@ -389,7 +391,7 @@ public class WorldTrimTask implements Runnable private void reportProgress() { lastReport = Config.Now(); - double perc = ((double)(reportTotal) / (double)reportTarget) * 100; + double perc = getPercentageCompleted(); sendMessage(reportTrimmedRegions + " entire region(s) and " + reportTrimmedChunks + " individual chunk(s) trimmed so far (" + Config.coord.format(perc) + "% done" + ")"); } @@ -400,4 +402,31 @@ public class WorldTrimTask implements Runnable if (notifyPlayer != null) notifyPlayer.sendMessage("[Trim] " + text); } + + /** + * Get the percentage completed for the trim task. + * + * @return Percentage + */ + public double getPercentageCompleted() { + return ((double) (reportTotal) / (double) reportTarget) * 100; + } + + /** + * Amount of chunks completed for the trim task. + * + * @return Number of chunks processed. + */ + public int getChunksCompleted() { + return reportTotal; + } + + /** + * Total amount of chunks that need to be trimmed for the trim task. + * + * @return Number of chunks that need to be processed. + */ + public int getChunksTotal() { + return reportTarget; + } }