diff --git a/src/main/java/net/aufdemrand/denizen/scripts/commands/BukkitCommandRegistry.java b/src/main/java/net/aufdemrand/denizen/scripts/commands/BukkitCommandRegistry.java index 65bda5ee39..c5c7388588 100644 --- a/src/main/java/net/aufdemrand/denizen/scripts/commands/BukkitCommandRegistry.java +++ b/src/main/java/net/aufdemrand/denizen/scripts/commands/BukkitCommandRegistry.java @@ -1489,16 +1489,17 @@ public void registerCoreMembers() { // <--[command] // @Name Light - // @Syntax light [] [<#>/reset] + // @Syntax light [] [<#>/reset] (duration:) // @Required 2 // @Stable stable - // @Short Creates a light source at the location. + // @Short Creates a light source at the location with a specified brightness. // @Author Morphan1 // @Group world // @Description // This command can create and reset a light source at a specified location, regardless of the type - // of block. It will be shown to all players near the location until it is reset, with certain - // exceptions. + // of block. It will be shown to all players near the location until it is reset. + // The brightness must be between 0 and 15, inclusive. + // Optionally, specify the amount of time the light should exist before being removed. // @Tags // // @@ -1510,7 +1511,7 @@ public void registerCoreMembers() { // - light l@MyFancyLightOfWool reset // --> registerCoreMember(LightCommand.class, - "LIGHT", "light [] [<#>/reset]", 2); + "LIGHT", "light [] [<#>/reset] (duration:)", 2); // <--[command] diff --git a/src/main/java/net/aufdemrand/denizen/scripts/commands/world/LightCommand.java b/src/main/java/net/aufdemrand/denizen/scripts/commands/world/LightCommand.java index 4fa9f2159e..31855802bb 100644 --- a/src/main/java/net/aufdemrand/denizen/scripts/commands/world/LightCommand.java +++ b/src/main/java/net/aufdemrand/denizen/scripts/commands/world/LightCommand.java @@ -5,6 +5,7 @@ import net.aufdemrand.denizen.utilities.debugging.dB; import net.aufdemrand.denizencore.exceptions.CommandExecutionException; import net.aufdemrand.denizencore.exceptions.InvalidArgumentsException; +import net.aufdemrand.denizencore.objects.Duration; import net.aufdemrand.denizencore.objects.Element; import net.aufdemrand.denizencore.objects.aH; import net.aufdemrand.denizencore.scripts.ScriptEntry; @@ -29,6 +30,11 @@ else if (!scriptEntry.hasObject("reset") && arg.matches("reset")) scriptEntry.addObject("reset", new Element(true)); + else if (!scriptEntry.hasObject("duration") + && arg.matchesPrefix("d", "duration") + && arg.matchesArgumentType(Duration.class)) + scriptEntry.addObject("duration", arg.asType(Duration.class)); + } if (!scriptEntry.hasObject("location") || @@ -45,12 +51,20 @@ public void execute(ScriptEntry scriptEntry) throws CommandExecutionException { dLocation location = scriptEntry.getdObject("location"); Element light = scriptEntry.getElement("light"); Element reset = scriptEntry.getElement("reset"); + Duration duration = scriptEntry.getdObject("duration"); - dB.report(scriptEntry, getName(), location.debug() + (light != null ? light.debug() : "") + reset.debug()); + dB.report(scriptEntry, getName(), location.debug() + reset.debug() + + (light != null ? light.debug() : "") + (duration != null ? duration.debug() : "")); - if (!reset.asBoolean()) - BlockLight.createLight(location, light.asInt()); - else + if (!reset.asBoolean()) { + int brightness = light.asInt(); + if (brightness < 0 || brightness > 15) { + throw new CommandExecutionException("Light brightness must be between 0 and 15, inclusive!"); + } + BlockLight.createLight(location, brightness, duration); + } + else { BlockLight.removeLight(location); + } } } diff --git a/src/main/java/net/aufdemrand/denizen/utilities/blocks/BlockLight.java b/src/main/java/net/aufdemrand/denizen/utilities/blocks/BlockLight.java index 47632d58c6..e6845e0a3c 100644 --- a/src/main/java/net/aufdemrand/denizen/utilities/blocks/BlockLight.java +++ b/src/main/java/net/aufdemrand/denizen/utilities/blocks/BlockLight.java @@ -2,6 +2,7 @@ import net.aufdemrand.denizen.utilities.DenizenAPI; import net.aufdemrand.denizen.utilities.debugging.dB; +import net.aufdemrand.denizencore.objects.Duration; import net.minecraft.server.v1_8_R1.*; import org.bukkit.Bukkit; import org.bukkit.Location; @@ -78,8 +79,9 @@ public void run() { private final int originalLight; private int currentLight; private int cachedLight; + private BukkitTask removeTask; - private BlockLight(Location location) { + private BlockLight(final Location location, Duration duration) { this.craftWorld = (CraftWorld) location.getWorld(); this.worldServer = craftWorld.getHandle(); this.craftChunk = (CraftChunk) location.getChunk(); @@ -89,17 +91,23 @@ private BlockLight(Location location) { this.originalLight = block.getLightLevel(); this.currentLight = originalLight; this.cachedLight = originalLight; + this.removeLater(duration); } - public static BlockLight createLight(Location location, int lightLevel) { + public static BlockLight createLight(Location location, int lightLevel, Duration duration) { location = location.getBlock().getLocation(); BlockLight blockLight; if (lightsByLocation.containsKey(location)) { blockLight = lightsByLocation.get(location); + if (blockLight.removeTask != null) { + blockLight.removeTask.cancel(); + blockLight.removeTask = null; + } blockLight.reset(true); + blockLight.removeLater(duration); } else { - blockLight = new BlockLight(location); + blockLight = new BlockLight(location, duration); lightsByLocation.put(location, blockLight); if (!lightsByChunk.containsKey(blockLight.chunk)) lightsByChunk.put(blockLight.chunk, new ArrayList()); @@ -114,6 +122,8 @@ public static void removeLight(Location location) { if (lightsByLocation.containsKey(location)) { BlockLight blockLight = lightsByLocation.get(location); blockLight.reset(true); + if (blockLight.removeTask != null) + blockLight.removeTask.cancel(); lightsByLocation.remove(location); lightsByChunk.get(blockLight.chunk).remove(blockLight); if (lightsByChunk.get(blockLight.chunk).isEmpty()) @@ -121,6 +131,21 @@ public static void removeLight(Location location) { } } + private void removeLater(Duration duration) { + if (duration != null) { + long ticks = duration.getTicks(); + if (ticks > 0) { + this.removeTask = new BukkitRunnable() { + @Override + public void run() { + removeTask = null; + removeLight(block.getLocation()); + } + }.runTaskLater(DenizenAPI.getCurrentInstance(), ticks); + } + } + } + private void reset(boolean updateChunk) { this.update(originalLight, updateChunk); }