Make /tpzone list use the multipage output code.

This commit is contained in:
UnknownShadow200 2016-09-06 17:59:23 +10:00
parent a86425c731
commit 922ec37511
5 changed files with 85 additions and 107 deletions

View File

@ -33,8 +33,8 @@ namespace MCGalaxy.Commands {
public override void Use(Player p, string message) {
string[] files = Directory.GetFiles("levels", "*.lvl");
Player.Message(p, "Unloaded maps (&c[no] %Sif not accessible): ");
MultiPageOutput.Output(p, GetMaps(files), map => FormatMap(p, map),
"unloaded", "maps", message);
MultiPageOutput.Output(p, GetMaps(files), (map, i) => FormatMap(p, map),
"unloaded", "maps", message, false);
}
static List<string> GetMaps(string[] files) {

View File

@ -48,8 +48,8 @@ namespace MCGalaxy.Commands {
Player.Message(p, "No one has the rank of " + grp.ColoredName);
} else {
Player.Message(p, "People with the rank of " + grp.ColoredName + ":");
MultiPageOutput.Output(p, list, name => name,
"viewranks " + args[0], "players", modifer);
MultiPageOutput.Output(p, list, (name, i) => name,
"viewranks " + args[0], "players", modifer, false);
}
}

View File

@ -15,10 +15,9 @@
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
namespace MCGalaxy.Commands
{
public sealed class CmdTpZone : Command
{
namespace MCGalaxy.Commands {
public sealed class CmdTpZone : Command {
public override string name { get { return "tpzone"; } }
public override string shortcut { get { return ""; } }
public override string type { get { return CommandTypes.Other; } }
@ -26,77 +25,39 @@ namespace MCGalaxy.Commands
public override LevelPermission defaultRank { get { return LevelPermission.Builder; } }
public CmdTpZone() { }
public override void Use(Player p, string message)
{
if (message == "") message = "list";
string[] parameters = message.Split(' ');
if (parameters[0].ToLower() == "list")
{
if (parameters.Length > 1)
{
int pageNum, currentNum;
try
{
pageNum = int.Parse(parameters[1]) * 10; currentNum = pageNum - 10;
}
catch { Help(p); return; }
if (currentNum < 0) { Player.Message(p, "Must be greater than 0"); return; }
if (pageNum > p.level.ZoneList.Count) pageNum = p.level.ZoneList.Count;
if (currentNum > p.level.ZoneList.Count) { Player.Message(p, "No Zones beyond number " + (p.level.ZoneList.Count - 1)); return; }
Player.Message(p, "Zones (" + currentNum + " to " + (pageNum - 1) + "):");
for (int i = currentNum; i < pageNum; i++)
{
Level.Zone zone = p.level.ZoneList[i];
Player.Message(p, "&c" + i + " &b(" +
zone.smallX + "-" + zone.bigX + ", " +
zone.smallY + "-" + zone.bigY + ", " +
zone.smallZ + "-" + zone.bigZ + ") &f" +
zone.Owner);
}
}
else
{
for (int i = 0; i < p.level.ZoneList.Count; i++)
{
Level.Zone zone = p.level.ZoneList[i];
Player.Message(p, "&c" + i + " &b(" +
zone.smallX + "-" + zone.bigX + ", " +
zone.smallY + "-" + zone.bigY + ", " +
zone.smallZ + "-" + zone.bigZ + ") &f" +
zone.Owner);
}
Player.Message(p, "For a more structured list, use /tpzone list <1/2/3/..>");
}
}
else
{
int zoneID;
if (!int.TryParse(message, out zoneID)) {
Help(p); return;
public override void Use(Player p, string message) {
string[] args = message.Split(' ');
if (args[0] == "" || args[0].CaselessEq("list")) {
string modifier = args.Length > 1 ? args[1] : "";
MultiPageOutput.Output(p, p.level.ZoneList, FormatZone,
"tpzone list", "zones", modifier, true);
} else {
int id;
if (!int.TryParse(message, out id)) { Help(p); return; }
if (id <= 0 || id > p.level.ZoneList.Count) {
Player.Message(p, "This zone doesn't exist"); return;
}
if (zoneID < 0 || zoneID > p.level.ZoneList.Count)
{
Player.Message(p, "This zone doesn't exist");
return;
}
Level.Zone zone = p.level.ZoneList[id - 1];
p.SendOwnFeetPos((ushort)(zone.bigX * 32 + 16), (ushort)(zone.bigY * 32 + 32),
(ushort)(zone.bigZ * 32 + 16), p.rot[0], p.rot[1]);
Level.Zone zone = p.level.ZoneList[zoneID];
p.SendPos(0xFF, (ushort)(zone.bigX * 32 + 16), (ushort)(zone.bigY * 32 + 32), (ushort)(zone.bigZ * 32 + 16), p.rot[0], p.rot[1]);
Player.Message(p, "Teleported to zone &c" + zoneID + " &b(" +
Player.Message(p, "Teleported to zone &c" + id + " &b(" +
zone.bigX + ", " + zone.bigY + ", " + zone.bigZ + ") &f" +
zone.Owner);
}
}
public override void Help(Player p)
{
Player.Message(p, "/tpzone <id> - Teleports to the zone with ID equal to <id>");
Player.Message(p, "/tpzone list - Lists all zones");
static string FormatZone(Level.Zone zone, int i) {
return "&c" + (i + 1) + " &b(" +
zone.smallX + "-" + zone.bigX + ", " +
zone.smallY + "-" + zone.bigY + ", " +
zone.smallZ + "-" + zone.bigZ + ") &f" + zone.Owner;
}
public override void Help(Player p) {
Player.Message(p, "%T/tpzone [id] %H- Teleports to the zone with ID of [id]");
Player.Message(p, "%T/tpzone list %H- Lists all zones");
}
}
}

View File

@ -23,36 +23,34 @@ namespace MCGalaxy {
/// <summary> Outputs a large range of values across a number of 'pages'. </summary>
public static class MultiPageOutput {
const int perPage = 30;
public static void Output<T>(Player p, IList<T> items, Func<T, string> formatter,
string cmd, string type, string input) {
public static void Output<T>(Player p, IList<T> items, Func<T, int, string> formatter,
string cmd, string type, string input, bool lines) {
int page = 0, total = items.Count;
int perPage = lines ? 10 : 30;
if (input == "") {
OutputPage(p, items, formatter, cmd, type, 1);
OutputPage(p, items, formatter, cmd, type, 1, lines);
if (total <= perPage) return;
Player.Message(p, "To see all {0}, use %T/{1} all", type, cmd);
} else if (input.CaselessEq("all")) {
Player.Message(p, items.Join(formatter, ", "));
OutputItems(p, items, 0, items.Count, lines, formatter);
Player.Message(p, "Showing {0} 1-{1} (out of {1})", type, items.Count);
} else if (!int.TryParse(input, out page)) {
Player.Message(p, "Page must be either \"all\" or an integer.");
} else {
OutputPage(p, items, formatter, cmd, type, page);
OutputPage(p, items, formatter, cmd, type, page, lines);
}
}
static void OutputPage<T>(Player p, IList<T> items, Func<T, string> formatter,
string cmd, string type, int page) {
static void OutputPage<T>(Player p, IList<T> items, Func<T, int, string> formatter,
string cmd, string type, int page, bool lines) {
int perPage = lines ? 10 : 30;
int total = items.Count, maxPage = total / perPage;
page = Utils.Clamp(page - 1, 0, maxPage); // want page numbers to start at 1
int entriesEnd = Math.Min((page + 1) * perPage, total);
OutputItems(p, items, page * perPage, entriesEnd, lines, formatter);
// TODO: Redesign Join for only doing subset of list?
List<T> pageItems = new List<T>(perPage);
for (int i = page * perPage; i < entriesEnd; i++)
pageItems.Add(items[i]);
Player.Message(p, pageItems.Join(formatter, ", "));
if (page < maxPage) {
Player.Message(p, "Showing {0} {1}-{2} (out of {3}) Next: %T/{4} {5}",
type, page * perPage + 1, entriesEnd, total, cmd, page + 2);
@ -61,5 +59,24 @@ namespace MCGalaxy {
type, page * perPage + 1, entriesEnd, total);
}
}
static void OutputItems<T>(Player p, IList<T> items,
int start, int end, bool lines,
Func<T, int, string> formatter) {
if (lines) {
for (int i = start; i < end; i++)
Player.Message(p, formatter(items[i], i));
} else {
IEnumerable<string> output = Subset(items, start, end, formatter);
Player.Message(p, output.Join());
}
}
static IEnumerable<string> Subset<T>(IList<T> items, int start, int end,
Func<T, int, string> formatter) {
for (int i = start; i < end; i++)
yield return formatter(items[i], i);
yield break;
}
}
}