From 7558d94d3c99b1e6d2ba94aec1bc05f80c92e42f Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 7 Jun 2020 21:44:55 +1000 Subject: [PATCH] Allow using relative coords for gb/lb min/max (Thanks 1Leiz) --- MCGalaxy/Commands/CPE/CustomBlockCommand.cs | 14 ++++--- MCGalaxy/Commands/CommandParser.cs | 42 ++++++++++++--------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/MCGalaxy/Commands/CPE/CustomBlockCommand.cs b/MCGalaxy/Commands/CPE/CustomBlockCommand.cs index d597cc19e..ef9c57f9f 100644 --- a/MCGalaxy/Commands/CPE/CustomBlockCommand.cs +++ b/MCGalaxy/Commands/CPE/CustomBlockCommand.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; using MCGalaxy.Blocks; using MCGalaxy.Commands.Building; +using MCGalaxy.Maths; using BlockID = System.UInt16; using BlockRaw = System.Byte; @@ -643,12 +644,15 @@ namespace MCGalaxy.Commands.CPE { string[] coords = parts.SplitSpaces(); if (coords.Length != 3) return false; - int tx = 0, ty = 0, tz = 0; - if (!CommandParser.GetInt(p, coords[0], "X", ref tx, -127, 127)) return false; - if (!CommandParser.GetInt(p, coords[1], "Y", ref ty, -127, 127)) return false; - if (!CommandParser.GetInt(p, coords[2], "Z", ref tz, -127, 127)) return false; + // TODO: Having to cast to sbyte here is yucky. blockdefs code should be fixed instead + Vec3S32 P = new Vec3S32((sbyte)x, (sbyte)z, (sbyte)y); // blockdef files have z being height, we use y being height + if (!CommandParser.GetCoords(p, coords, 0, ref P)) return false; - x = (byte)tx; z = (byte)ty; y = (byte)tz; // blockdef files have z being height, we use y being height + if (!CommandParser.CheckRange(p, P.X, "X", -127, 127)) return false; + if (!CommandParser.CheckRange(p, P.Y, "Y", -127, 127)) return false; + if (!CommandParser.CheckRange(p, P.Z, "Z", -127, 127)) return false; + + x = (byte)P.X; z = (byte)P.Y; y = (byte)P.Z; // blockdef files have z being height, we use y being height return true; } diff --git a/MCGalaxy/Commands/CommandParser.cs b/MCGalaxy/Commands/CommandParser.cs index 2a0dfe23b..2c2390c1b 100644 --- a/MCGalaxy/Commands/CommandParser.cs +++ b/MCGalaxy/Commands/CommandParser.cs @@ -77,6 +77,20 @@ namespace MCGalaxy.Commands { public const string TimespanHelp = "For example, to {0} 25 and a half hours, use \"1d1h30m\"."; + public static bool CheckRange(Player p, int value, string argName, int min, int max) { + if (value >= min && value <= max) return true; + + // Try to provide more helpful range messages + if (max == int.MaxValue) { + p.Message("%W{0} must be {1} or greater", argName, min); + } else if (min == int.MinValue) { + p.Message("%W{0} must be {1} or less", argName, max); + } else { + p.Message("%W{0} must be between {1} and {2}", argName, min, max); + } + return false; + } + /// Attempts to parse the given argument as an integer. public static bool GetInt(Player p, string input, string argName, ref int result, int min = int.MinValue, int max = int.MaxValue) { @@ -85,18 +99,7 @@ namespace MCGalaxy.Commands { p.Message("%W\"{0}\" is not a valid integer.", input); return false; } - if (value < min || value > max) { - // Try to provide more helpful range messages - if (max == int.MaxValue) { - p.Message("%W{0} must be {1} or greater", argName, min); - } else if (min == int.MinValue) { - p.Message("%W{0} must be {1} or less", argName, max); - } else { - p.Message("%W{0} must be between {1} and {2}", argName, min, max); - } - return false; - } - + if (!CheckRange(p, value, argName, min, max)) return false; result = value; return true; } @@ -145,19 +148,22 @@ namespace MCGalaxy.Commands { col = tmp; return true; } + /// Attempts to parse the 3 given arguments as coordinates. public static bool GetCoords(Player p, string[] args, int argsOffset, ref Vec3S32 P) { return - GetCoord(p, args[argsOffset + 0], P.X, "X coordinate", out P.X) && - GetCoord(p, args[argsOffset + 1], P.Y, "Y coordinate", out P.Y) && - GetCoord(p, args[argsOffset + 2], P.Z, "Z coordinate", out P.Z); + GetCoord(p, args[argsOffset + 0], "X coordinate", ref P.X) && + GetCoord(p, args[argsOffset + 1], "Y coordinate", ref P.Y) && + GetCoord(p, args[argsOffset + 2], "Z coordinate", ref P.Z); } - static bool GetCoord(Player p, string arg, int cur, string axis, out int value) { + static bool GetCoord(Player p, string arg, string axis, ref int value) { bool relative = arg[0] == '~'; if (relative) arg = arg.Substring(1); - value = 0; // ~ should work as ~0 - if (relative && arg.Length == 0) { value += cur; return true; } + if (relative && arg.Length == 0) return true; + + int cur = value; + value = 0; if (!GetInt(p, arg, axis, ref value)) return false; if (relative) value += cur;