Print the names of nearby gates when executing /gate nb.

Fixed a serious bug when trying to print a very long title.
Made the info command work without a supplied gate id. It then will print information about the closest gate. (Issue #13)
This commit is contained in:
Tobias Ottenweller 2013-09-17 17:57:31 +02:00
parent e9a454182a
commit 12a0bba6cc
6 changed files with 209 additions and 67 deletions

View File

@ -68,6 +68,35 @@ public class GatesManager
} }
/**
* 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<Gate> 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) public Gate getGateAtLocation(final Location location)
{ {
SimpleLocation simpleLocation = new SimpleLocation(location); SimpleLocation simpleLocation = new SimpleLocation(location);

View File

@ -17,10 +17,12 @@
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.TextUtil; import de.craftinc.gates.util.TextUtil;
import org.bukkit.entity.Player;
public class CommandInfo extends BaseCommand public class CommandInfo extends BaseCommand
@ -30,21 +32,50 @@ public class CommandInfo extends BaseCommand
aliases.add("info"); aliases.add("info");
aliases.add("i"); 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; requiredPermission = Plugin.permissionInfo;
needsPermissionAtCurrentLocation = false; needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = false; shouldPersistToDisk = false;
senderMustBePlayer = false; senderMustBePlayer = false;
hasGateParam = false;
} }
public void perform() public void perform()
{ {
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 + "'")); 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"; String openHiddenMessage = ChatColor.DARK_AQUA + "This gate is";
@ -73,5 +104,10 @@ public class CommandInfo extends BaseCommand
gate.getExit().getWorld().getName()); gate.getExit().getWorld().getName());
else else
sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no exit"); sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no exit");
if (this.sender instanceof Player) {
GateBlockChangeSender.temporaryHighlightGateFrame((Player)this.sender, this.gate);
}
} }
} }

View File

@ -1,8 +1,14 @@
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.Gate;
import de.craftinc.gates.GatesManager;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.GateBlockChangeSender; 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 public class CommandNearby extends BaseLocationCommand
{ {
@ -24,6 +30,24 @@ public class CommandNearby extends BaseLocationCommand
public void perform() public void perform()
{ {
GateBlockChangeSender.temporaryHighlightGatesFrames(player); GatesManager manager = Plugin.getPlugin().getGatesManager();
Set<Gate> nearbyGates = manager.getNearbyGates(player.getLocation().getChunk());
if (nearbyGates == null) {
player.sendMessage("There are no gates near you!");
}
else {
GateBlockChangeSender.temporaryHighlightGatesFrames(player, nearbyGates);
ArrayList<String> gateNames = new ArrayList<String>();
for (Gate g : nearbyGates) {
gateNames.add(g.getId());
}
player.sendMessage("Nearby gates: " + TextUtil.implode(gateNames, ", "));
}
} }
} }

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.util; package de.craftinc.gates.util;

View File

@ -29,6 +29,8 @@ import org.bukkit.entity.Player;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Set; import java.util.Set;
import static de.craftinc.gates.util.ConfigurationUtil.*;
public class GateBlockChangeSender public class GateBlockChangeSender
{ {
@ -39,36 +41,16 @@ public class GateBlockChangeSender
* @param player The player for whom the frame should be highlighted. * @param player The player for whom the frame should be highlighted.
* Must not be null! * Must not be null!
*/ */
public static void temporaryHighlightGatesFrames(final Player player) public static void temporaryHighlightGatesFrames(final Player player, final Set<Gate> gates)
{ {
if (player == null) { if (player == null) {
throw new IllegalArgumentException("'player' must not be 'null'!"); throw new IllegalArgumentException("'player' must not be 'null'!");
} }
Location location = player.getLocation(); if (gates == null) {
final Set<Gate> gatesNearby = Plugin.getPlugin().getGatesManager().getNearbyGates(location.getChunk()); throw new IllegalArgumentException("'gate' must not be 'null!");
if (gatesNearby == null) {
return; // no gates nearby
} }
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<Gate> gates)
{
for (Gate g : gates) { for (Gate g : gates) {
Set<Block> frameBlocks = g.getGateFrameBlocks(); Set<Block> frameBlocks = g.getGateFrameBlocks();
@ -76,10 +58,48 @@ public class GateBlockChangeSender
player.sendBlockChange(b.getLocation(), Material.GLOWSTONE, (byte)0); 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<Gate> 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<Block> 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<Gate> gates)
{ {
for (Gate g : gates) { for (Gate g : gates) {
Set<Block> frameBlocks = g.getGateFrameBlocks(); Set<Block> frameBlocks = g.getGateFrameBlocks();
@ -91,6 +111,16 @@ public class GateBlockChangeSender
} }
protected static void dehighlightGateFrame(final Player player, final Gate gate)
{
Set<Block> 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 * Sends gate blocks to player at a given location. Will send the updates either immediately or
* immediately and after a short delay. * immediately and after a short delay.
@ -110,7 +140,7 @@ public class GateBlockChangeSender
} }
Set<Gate> gatesNearby = Plugin.getPlugin().getGatesManager().getNearbyGates(location.getChunk()); Set<Gate> gatesNearby = Plugin.getPlugin().getGatesManager().getNearbyGates(location.getChunk());
GateMaterial gateMaterial = ConfigurationUtil.getPortalMaterial(); GateMaterial gateMaterial = getPortalMaterial();
if (gatesNearby == null) { if (gatesNearby == null) {
return; // no gates nearby return; // no gates nearby
@ -188,7 +218,7 @@ public class GateBlockChangeSender
ArrayList<Player> playersNearby = new ArrayList<Player>(); ArrayList<Player> playersNearby = new ArrayList<Player>();
int searchRadius = Plugin.getPlugin().getConfig().getInt(ConfigurationUtil.confPlayerGateBlockUpdateRadiusKey); int searchRadius = Plugin.getPlugin().getConfig().getInt(confPlayerGateBlockUpdateRadiusKey);
for (Player p : Plugin.getPlugin().getServer().getOnlinePlayers()) { for (Player p : Plugin.getPlugin().getServer().getOnlinePlayers()) {
@ -197,7 +227,7 @@ public class GateBlockChangeSender
} }
} }
GateMaterial gateMaterial = ConfigurationUtil.getPortalMaterial(); GateMaterial gateMaterial = getPortalMaterial();
Material material; Material material;
byte data = 0; byte data = 0;

View File

@ -24,14 +24,21 @@ 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 + " ]."; String center = ".[ " + ChatColor.YELLOW + str + ChatColor.GOLD + " ].";
if (center.length() >= 60) {
return ChatColor.GOLD + center;
}
else {
String line = ChatColor.GOLD + repeat("_", 60);
int pivot = line.length() / 2; int pivot = line.length() / 2;
int eatLeft = center.length() / 2; int eatLeft = center.length() / 2;
int eatRight = center.length() - eatLeft; int eatRight = center.length() - eatLeft;
return line.substring(0, pivot - eatLeft) + center + line.substring(pivot + eatRight); return line.substring(0, pivot - eatLeft) + center + line.substring(pivot + eatRight);
} }
}
public static String repeat(String s, int times) public static String repeat(String s, int times)