Skip to content

Commit

Permalink
Added automatic border shrinking (for both squared & circular borders).
Browse files Browse the repository at this point in the history
Closes #26. Ping #106.

* NEW: added automatic border shrinking after a delay, even for circular borders.
* NEW: emulated a slow size evolution in the Brettflan (Bukkit plugin) WorldBorder.
  • Loading branch information
AmauryCarrade committed Jan 11, 2016
1 parent daed843 commit f56fbbd
Show file tree
Hide file tree
Showing 7 changed files with 133 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
import eu.carrade.amaury.UHCReloaded.timers.UHTimer;
import eu.carrade.amaury.UHCReloaded.utils.UHUtils;
import fr.zcraft.zlib.tools.PluginLogger;
import fr.zcraft.zlib.tools.runners.RunTask;
import fr.zcraft.zlib.tools.text.Titles;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
Expand All @@ -55,11 +57,15 @@

public class BorderManager
{
private final boolean BORDER_SHRINKING;
private final long BORDER_SHRINKING_STARTS_AFTER;
private final long BORDER_SHRINKING_DURATION;
private final double BORDER_SHRINKING_FINAL_SIZE;

private UHCReloaded p = null;
private I18n i = null;

private WorldBorder border = null;
private Integer currentBorderDiameter = null;

private Integer warningSize = 0;
private BukkitRunnable warningTask = null;
Expand All @@ -73,14 +79,12 @@ public class BorderManager

public BorderManager(UHCReloaded plugin)
{
this.p = plugin;
this.i = p.getI18n();

this.warningTimerName = i.t("borders.warning.nameTimer");
p = plugin;
i = p.getI18n();

this.currentBorderDiameter = p.getConfig().getInt("map.size");
this.mapShape = MapShape.fromString(p.getConfig().getString("map.shape"));
warningTimerName = i.t("borders.warning.nameTimer");

mapShape = MapShape.fromString(p.getConfig().getString("map.shape"));
if (mapShape == null)
{
PluginLogger.warning("Invalid shape '" + p.getConfig().getString("map.shape") + "'; using 'squared' instead.");
Expand All @@ -100,11 +104,17 @@ public BorderManager(UHCReloaded plugin)

border.setShape(mapShape);
border.setCenter(world.getSpawnLocation());
border.setDiameter(currentBorderDiameter);
border.setDiameter(p.getConfig().getInt("map.size", 2000));

border.init();

PluginLogger.info("Using {0} to set the world border.", border.getClass().getSimpleName());


BORDER_SHRINKING = p.getConfig().getBoolean("map.border.shrinking.enabled", false);
BORDER_SHRINKING_STARTS_AFTER = UHUtils.string2Time(p.getConfig().getString("map.border.shrinking.startsAfter"), 30*60); // Seconds
BORDER_SHRINKING_DURATION = UHUtils.string2Time(p.getConfig().getString("map.border.shrinking.shrinksDuring"), 60*60*2); // Same
BORDER_SHRINKING_FINAL_SIZE = p.getConfig().getDouble("map.border.shrinking.diameterAfterShrink", 200);
}

/**
Expand Down Expand Up @@ -303,10 +313,7 @@ public void cancelWarning()
{
warningTask.cancel();
}
catch (IllegalStateException e)
{

}
catch (IllegalStateException ignored) {}
}

UHTimer timer = getWarningTimer();
Expand All @@ -322,7 +329,7 @@ public void cancelWarning()
*/
public int getCurrentBorderDiameter()
{
return this.currentBorderDiameter;
return (int) border.getDiameter();
}

/**
Expand All @@ -338,7 +345,6 @@ public void setCurrentBorderDiameter(int diameter)
{
cancelWarning();

currentBorderDiameter = diameter;
border.setDiameter(diameter);
}

Expand Down Expand Up @@ -399,4 +405,28 @@ public void generateWalls(World world) throws CannotGenerateWallsException

mapShape.getWallGeneratorInstance(p, wallBlockAir, wallBlockSolid).build(world, getCurrentBorderDiameter(), wallHeight);
}

/**
* Schedules the automatic border reduction, if enabled in the configuration.
*/
public void scheduleBorderReduction()
{
if (BORDER_SHRINKING)
{
RunTask.later(new Runnable() {
@Override
public void run()
{
Integer secondsPerBlock = (int) Math.rint(BORDER_SHRINKING_DURATION / (border.getDiameter() - BORDER_SHRINKING_FINAL_SIZE)) * 2;

border.setDiameter(BORDER_SHRINKING_FINAL_SIZE, BORDER_SHRINKING_DURATION);

Titles.broadcastTitle(5, 30, 8, i.t("borders.shrinking.title.title"), i.t("borders.shrinking.title.subtitle"));

Bukkit.broadcastMessage(i.t("borders.shrinking.message.title"));
Bukkit.broadcastMessage(i.t("borders.shrinking.message.times", secondsPerBlock, BORDER_SHRINKING_FINAL_SIZE));
}
}, BORDER_SHRINKING_STARTS_AFTER * 20l);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@
import com.wimbli.WorldBorder.Config;
import eu.carrade.amaury.UHCReloaded.UHCReloaded;
import eu.carrade.amaury.UHCReloaded.borders.MapShape;
import fr.zcraft.zlib.tools.runners.RunTask;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.scheduler.BukkitTask;


/**
Expand All @@ -58,6 +60,9 @@ public class BrettflanWorldBorder extends WorldBorder

private Double diameter = 0d;

private BukkitTask slowReductionTask = null;


public BrettflanWorldBorder(World world)
{
this.world = world;
Expand Down Expand Up @@ -110,13 +115,47 @@ public double getDiameter()
public void setDiameter(double diameter)
{
setDiameterInternal(diameter);

if (slowReductionTask != null)
{
slowReductionTask.cancel();
slowReductionTask = null;
}
}

@Override
public void setDiameter(double diameter, long time)
public void setDiameter(final double diameter, final long time)
{
// TODO emulate the vanilla world border, to allow slowly shrinking circular borders
setDiameterInternal(diameter);
// The behavior of the vanilla reduction is emulated.
final double currentDiameter = getDiameter();

final long ticksPerBlockRemoved = (int) Math.rint(time / (currentDiameter - diameter)) * 20l;
final long movement = (diameter >= currentDiameter) ? 1 : -1;

if (slowReductionTask != null)
{
slowReductionTask.cancel();
slowReductionTask = null;
}

slowReductionTask = RunTask.timer(new Runnable() {
@Override
public void run()
{
Double newDiameter = getDiameter() + movement;

// If the final size is achieved, we set the exact requested size and we stop here.
// Calling setDiameter cancels this task.
if ((movement < 0 && newDiameter <= diameter) || (movement > 0 && newDiameter >= diameter))
{
setDiameter(diameter);
}
else
{
setDiameterInternal(newDiameter);
}
}
}, ticksPerBlockRemoved, ticksPerBlockRemoved);
}

private void setDiameterInternal(double diameter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,9 @@ public void onGameStarts(UHGameStartsEvent ev)
// Commands
p.getRuntimeCommandsExecutor().registerCommandsInScheduler(RuntimeCommandsExecutor.AFTER_GAME_START);

// Border shrinking
p.getBorderManager().scheduleBorderReduction();

// MOTD
p.getMOTDManager().updateMOTDDuringGame();

Expand Down
25 changes: 25 additions & 0 deletions src/main/java/eu/carrade/amaury/UHCReloaded/utils/UHUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
package eu.carrade.amaury.UHCReloaded.utils;

import fr.zcraft.zlib.tools.Callback;
import fr.zcraft.zlib.tools.PluginLogger;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.FireworkEffect;
Expand Down Expand Up @@ -125,6 +126,30 @@ else if (split.length == 2) // "mm:ss"
}
}

/**
* Converts a string to a number of seconds.
*
* Prints a warning if the format is invalid.
*
* @param text The text to be converted.
* @param defaultValue The default value returned if the format is invalid.
*
* @return The extracted seconds, or the default value if invalid.
* @see #string2Time(String)
*/
public static int string2Time(String text, Integer defaultValue)
{
try
{
return string2Time(text);
}
catch (IllegalArgumentException e)
{
PluginLogger.warning("Invalid duration '{0}', using {1} seconds instead.", text, defaultValue);
return defaultValue;
}
}

/**
* Converts a string to a boolean.
*
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ map:
# You can display the border size in the scoreboard; see `scoreboard.border`.


# Automatic and progressive border shrinking
# Automatic and progressive border shrinking.
# Notice: if the border is circular, the WorldBorder Bukkit plugin by Brettflan (see above)
# is REQUIRED. Without, the border shrinking will not work.
shrinking:
enabled: false

Expand Down
8 changes: 8 additions & 0 deletions src/main/resources/i18n/en_US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,14 @@ keys:
itemPlayerClose: "{lightpurple} - {yellow}{0}{ci} (close to the border)"
itemPlayerVeryClose: "{lightpurple} - {green}{0}{ci} (very close to the border)"

shrinking:
title:
title: "{red}Warning!"
subtitle: "{white}The border begins to shrink..."
message:
title: "{red}{bold}The border begins to shrink..."
times: "{gray}It will shrink by one block every {0} second(s) until {1} blocks in diameter."

timers:
syntaxError: "{ce}Syntax error, see /uh timers."
durationSyntaxError: "{ce}The duration' syntax is invalid; accepted formats are mm, mm:ss or hh:mm:ss."
Expand Down
8 changes: 8 additions & 0 deletions src/main/resources/i18n/fr_FR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,14 @@ keys:
itemPlayerFar: "{lightpurple} - {red}{0}{ci} (loin de la bordure)"
itemPlayerClose: "{lightpurple} - {yellow}{0}{ci} (proche de la bordure)"
itemPlayerVeryClose: "{lightpurple} - {green}{0}{ci} (très proche de la bordure)"

shrinking:
title:
title: "{red}Attention !"
subtitle: "{white}La bordure commence à se réduire..."
message:
title: "{red}{bold}La bordure commence à se réduire..."
times: "{gray}Elle réduira d'un bloc toutes les {0} seconde(s) jusqu'à atteindre {1} blocs de diamètre."

timers:
syntaxError: "{ce}Erreur de syntaxe, consultez /uh timers."
Expand Down

0 comments on commit f56fbbd

Please sign in to comment.