diff --git a/src/de/craftinc/gates/GatesManager.java b/src/de/craftinc/gates/GatesManager.java index c1c3cf3..ba149bf 100644 --- a/src/de/craftinc/gates/GatesManager.java +++ b/src/de/craftinc/gates/GatesManager.java @@ -66,7 +66,36 @@ public class GatesManager SimpleChunk simpleChunk = new SimpleChunk(chunk); return gatesByChunk.get(simpleChunk); } - + + + /** + * Returns the closest gate. + * @param location The location at which to look for a gate. + * @return Might return null if there are no nearby gates. + */ + public Gate getNearestGate(final Location location) + { + Set nearbyGates = getNearbyGates(location.getChunk()); + + if (nearbyGates == null) { + return null; + } + + double minDist = Double.MAX_VALUE; + Gate nearestGate = null; + + for (Gate g : nearbyGates) { + double dist = location.distance(g.getLocation()); + + if (dist < minDist) { + minDist = dist; + nearestGate = g; + } + } + + return nearestGate; + } + public Gate getGateAtLocation(final Location location) { diff --git a/src/de/craftinc/gates/commands/CommandInfo.java b/src/de/craftinc/gates/commands/CommandInfo.java index 9395db2..d276e5e 100644 --- a/src/de/craftinc/gates/commands/CommandInfo.java +++ b/src/de/craftinc/gates/commands/CommandInfo.java @@ -17,10 +17,12 @@ package de.craftinc.gates.commands; +import de.craftinc.gates.util.GateBlockChangeSender; import org.bukkit.ChatColor; import de.craftinc.gates.Plugin; import de.craftinc.gates.util.TextUtil; +import org.bukkit.entity.Player; public class CommandInfo extends BaseCommand @@ -30,48 +32,82 @@ public class CommandInfo extends BaseCommand aliases.add("info"); aliases.add("i"); - requiredParameters.add("id"); + optionalParameters.add("id"); - helpDescription = "Print detailed information about a certain gate."; + helpDescription = "Print detailed information about a certain or the closest gate."; requiredPermission = Plugin.permissionInfo; needsPermissionAtCurrentLocation = false; shouldPersistToDisk = false; senderMustBePlayer = false; + hasGateParam = false; } public void perform() { - sendMessage(TextUtil.titleize("Information about: '" + ChatColor.WHITE + gate.getId() + ChatColor.YELLOW + "'")); - - String openHiddenMessage = ChatColor.DARK_AQUA + "This gate is"; - - if (gate.isOpen()) - openHiddenMessage += ChatColor.AQUA + " open"; - else - openHiddenMessage += ChatColor.AQUA + " closed"; - - if (gate.isHidden()) - openHiddenMessage += ChatColor.DARK_AQUA +" and" + ChatColor.AQUA + " hidden"; - - openHiddenMessage += ".\n"; - - sendMessage(openHiddenMessage); - - if (gate.getLocation() != null) - sendMessage(ChatColor.DARK_AQUA + "location: " + ChatColor.AQUA + "( " + (int)gate.getLocation().getX() + - " | " + (int)gate.getLocation().getY() + " | " + (int)gate.getLocation().getZ() + " ) in " + - gate.getLocation().getWorld().getName()); - else - sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no location"); - - if (gate.getExit() != null) - sendMessage(ChatColor.DARK_AQUA + "exit: " + ChatColor.AQUA + "( " + (int)gate.getExit().getX() + " | " - + (int)gate.getExit().getY() + " | " + (int)gate.getExit().getZ() + " ) in " + - gate.getExit().getWorld().getName()); - else - sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no exit"); + if (this.parameters.size() > 0) { + + if (!this.setGateUsingParameter(this.parameters.get(0))) { + sendMessage(ChatColor.RED + "You either provided a invalid gate or do not have permission to " + this.helpDescription.toLowerCase()); + return; + } + + sendMessage(TextUtil.titleize("Information about: '" + ChatColor.WHITE + gate.getId() + ChatColor.YELLOW + "'")); + } + else { + boolean senderIsPlayer = this.sender instanceof Player; + + if (!senderIsPlayer) { + sendMessage(ChatColor.RED + "Only ingame players can perform this command without a supplied gate id!"); + return; + } + + Player p = (Player)this.sender; + this.gate = Plugin.getPlugin().getGatesManager().getNearestGate(p.getLocation()); + + if (!this.hasPermission() || this.gate == null) { + sendMessage(ChatColor.RED + "There is either no gate nearby or you do not have permission to " + this.helpDescription.toLowerCase()); + return; + } + + Plugin.log(this.gate.toString()); + + sendMessage(TextUtil.titleize("Information about closest gate: '" + ChatColor.WHITE + gate.getId() + ChatColor.YELLOW + "'")); + } + + String openHiddenMessage = ChatColor.DARK_AQUA + "This gate is"; + + if (gate.isOpen()) + openHiddenMessage += ChatColor.AQUA + " open"; + else + openHiddenMessage += ChatColor.AQUA + " closed"; + + if (gate.isHidden()) + openHiddenMessage += ChatColor.DARK_AQUA +" and" + ChatColor.AQUA + " hidden"; + + openHiddenMessage += ".\n"; + + sendMessage(openHiddenMessage); + + if (gate.getLocation() != null) + sendMessage(ChatColor.DARK_AQUA + "location: " + ChatColor.AQUA + "( " + (int)gate.getLocation().getX() + + " | " + (int)gate.getLocation().getY() + " | " + (int)gate.getLocation().getZ() + " ) in " + + gate.getLocation().getWorld().getName()); + else + sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no location"); + + if (gate.getExit() != null) + sendMessage(ChatColor.DARK_AQUA + "exit: " + ChatColor.AQUA + "( " + (int)gate.getExit().getX() + " | " + + (int)gate.getExit().getY() + " | " + (int)gate.getExit().getZ() + " ) in " + + gate.getExit().getWorld().getName()); + else + sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no exit"); + + + if (this.sender instanceof Player) { + GateBlockChangeSender.temporaryHighlightGateFrame((Player)this.sender, this.gate); + } } } diff --git a/src/de/craftinc/gates/commands/CommandNearby.java b/src/de/craftinc/gates/commands/CommandNearby.java index 25943f5..a15b528 100644 --- a/src/de/craftinc/gates/commands/CommandNearby.java +++ b/src/de/craftinc/gates/commands/CommandNearby.java @@ -1,8 +1,14 @@ package de.craftinc.gates.commands; +import de.craftinc.gates.Gate; +import de.craftinc.gates.GatesManager; import de.craftinc.gates.Plugin; import de.craftinc.gates.util.GateBlockChangeSender; +import de.craftinc.gates.util.TextUtil; + +import java.util.ArrayList; +import java.util.Set; public class CommandNearby extends BaseLocationCommand { @@ -24,6 +30,24 @@ public class CommandNearby extends BaseLocationCommand public void perform() { - GateBlockChangeSender.temporaryHighlightGatesFrames(player); + GatesManager manager = Plugin.getPlugin().getGatesManager(); + Set nearbyGates = manager.getNearbyGates(player.getLocation().getChunk()); + + if (nearbyGates == null) { + player.sendMessage("There are no gates near you!"); + } + else { + GateBlockChangeSender.temporaryHighlightGatesFrames(player, nearbyGates); + + ArrayList gateNames = new ArrayList(); + + for (Gate g : nearbyGates) { + gateNames.add(g.getId()); + } + + player.sendMessage("Nearby gates: " + TextUtil.implode(gateNames, ", ")); + } + + } } diff --git a/src/de/craftinc/gates/util/ConfigurationUtil.java b/src/de/craftinc/gates/util/ConfigurationUtil.java index 4ea0e9a..0419629 100644 --- a/src/de/craftinc/gates/util/ConfigurationUtil.java +++ b/src/de/craftinc/gates/util/ConfigurationUtil.java @@ -1,3 +1,19 @@ +/* Craft Inc. Gates + Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program (LGPLv3). If not, see . +*/ package de.craftinc.gates.util; diff --git a/src/de/craftinc/gates/util/GateBlockChangeSender.java b/src/de/craftinc/gates/util/GateBlockChangeSender.java index 6f87bfe..9791407 100644 --- a/src/de/craftinc/gates/util/GateBlockChangeSender.java +++ b/src/de/craftinc/gates/util/GateBlockChangeSender.java @@ -29,6 +29,8 @@ import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.Set; +import static de.craftinc.gates.util.ConfigurationUtil.*; + public class GateBlockChangeSender { @@ -39,36 +41,16 @@ public class GateBlockChangeSender * @param player The player for whom the frame should be highlighted. * Must not be null! */ - public static void temporaryHighlightGatesFrames(final Player player) + public static void temporaryHighlightGatesFrames(final Player player, final Set gates) { if (player == null) { throw new IllegalArgumentException("'player' must not be 'null'!"); } - Location location = player.getLocation(); - final Set gatesNearby = Plugin.getPlugin().getGatesManager().getNearbyGates(location.getChunk()); - - if (gatesNearby == null) { - return; // no gates nearby + if (gates == null) { + throw new IllegalArgumentException("'gate' must not be 'null!"); } - highlightGatesFrames(player, gatesNearby); - - - Plugin plugin = Plugin.getPlugin(); - long highlightDuration = 20 * plugin.getConfig().getLong(ConfigurationUtil.confHighlightDurationKey); - - Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { - @Override - public void run() { - dehighlightGateFrame(player, gatesNearby); - } - }, highlightDuration); - } - - - protected static void highlightGatesFrames(final Player player, final Set gates) - { for (Gate g : gates) { Set frameBlocks = g.getGateFrameBlocks(); @@ -76,10 +58,48 @@ public class GateBlockChangeSender player.sendBlockChange(b.getLocation(), Material.GLOWSTONE, (byte)0); } } + + Plugin plugin = Plugin.getPlugin(); + long highlightDuration = 20 * plugin.getConfig().getLong(confHighlightDurationKey); + + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + @Override + public void run() { + dehighlightGatesFrames(player, gates); + } + }, highlightDuration); } - protected static void dehighlightGateFrame(final Player player, final Set gates) + public static void temporaryHighlightGateFrame(final Player player, final Gate gate) + { + if (gate == null) { + throw new IllegalArgumentException("'gate' must not be 'null!"); + } + + if (player == null) { + throw new IllegalArgumentException("'player' must not be 'null'!"); + } + + Set frameBlocks = gate.getGateFrameBlocks(); + + for (Block b : frameBlocks) { + player.sendBlockChange(b.getLocation(), Material.GLOWSTONE, (byte)0); + } + + Plugin plugin = Plugin.getPlugin(); + long highlightDuration = 20 * plugin.getConfig().getLong(confHighlightDurationKey); + + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { + @Override + public void run() { + dehighlightGateFrame(player, gate); + } + }, highlightDuration); + } + + + protected static void dehighlightGatesFrames(final Player player, final Set gates) { for (Gate g : gates) { Set frameBlocks = g.getGateFrameBlocks(); @@ -91,6 +111,16 @@ public class GateBlockChangeSender } + protected static void dehighlightGateFrame(final Player player, final Gate gate) + { + Set frameBlocks = gate.getGateFrameBlocks(); + + for (Block b : frameBlocks) { + player.sendBlockChange(b.getLocation(), b.getType(), (byte)0); + } + } + + /** * Sends gate blocks to player at a given location. Will send the updates either immediately or * immediately and after a short delay. @@ -110,7 +140,7 @@ public class GateBlockChangeSender } Set gatesNearby = Plugin.getPlugin().getGatesManager().getNearbyGates(location.getChunk()); - GateMaterial gateMaterial = ConfigurationUtil.getPortalMaterial(); + GateMaterial gateMaterial = getPortalMaterial(); if (gatesNearby == null) { return; // no gates nearby @@ -188,7 +218,7 @@ public class GateBlockChangeSender ArrayList playersNearby = new ArrayList(); - int searchRadius = Plugin.getPlugin().getConfig().getInt(ConfigurationUtil.confPlayerGateBlockUpdateRadiusKey); + int searchRadius = Plugin.getPlugin().getConfig().getInt(confPlayerGateBlockUpdateRadiusKey); for (Player p : Plugin.getPlugin().getServer().getOnlinePlayers()) { @@ -197,7 +227,7 @@ public class GateBlockChangeSender } } - GateMaterial gateMaterial = ConfigurationUtil.getPortalMaterial(); + GateMaterial gateMaterial = getPortalMaterial(); Material material; byte data = 0; diff --git a/src/de/craftinc/gates/util/TextUtil.java b/src/de/craftinc/gates/util/TextUtil.java index ec0fb6f..77d93cc 100644 --- a/src/de/craftinc/gates/util/TextUtil.java +++ b/src/de/craftinc/gates/util/TextUtil.java @@ -22,15 +22,22 @@ import java.util.List; public class TextUtil { - public static String titleize(String str) + public static String titleize(String str) { - String line = ChatColor.GOLD + repeat("_", 60); String center = ".[ " + ChatColor.YELLOW + str + ChatColor.GOLD + " ]."; - int pivot = line.length() / 2; - int eatLeft = center.length() / 2; - int eatRight = center.length() - eatLeft; - - return line.substring(0, pivot - eatLeft) + center + line.substring(pivot + eatRight); + + if (center.length() >= 60) { + return ChatColor.GOLD + center; + } + else { + String line = ChatColor.GOLD + repeat("_", 60); + + int pivot = line.length() / 2; + int eatLeft = center.length() / 2; + int eatRight = center.length() - eatLeft; + + return line.substring(0, pivot - eatLeft) + center + line.substring(pivot + eatRight); + } }