diff --git a/MCGalaxy/Commands/building/CmdBezier.cs b/MCGalaxy/Commands/building/CmdBezier.cs index 322de0349..a62c6397f 100644 --- a/MCGalaxy/Commands/building/CmdBezier.cs +++ b/MCGalaxy/Commands/building/CmdBezier.cs @@ -21,8 +21,11 @@ using MCGalaxy.Drawing.Ops; namespace MCGalaxy.Commands.Building { public sealed class CmdBezier : DrawCmd { public override string name { get { return "Bezier"; } } + + protected override int MarksCount { get { return 3; } } + protected override string SelectionType { get { return "points"; } } protected override string PlaceMessage { get { return "Place or break two blocks to determine the endpoints, then another for the control point"; } } - public override int MarksCount { get { return 3; } } + public override CommandAlias[] Aliases { get { return new CommandAlias[] { new CommandAlias("Curve") }; } } diff --git a/MCGalaxy/Commands/building/CmdDraw.cs b/MCGalaxy/Commands/building/CmdDraw.cs index 7df11252a..f023b612b 100644 --- a/MCGalaxy/Commands/building/CmdDraw.cs +++ b/MCGalaxy/Commands/building/CmdDraw.cs @@ -23,8 +23,10 @@ using MCGalaxy.Maths; namespace MCGalaxy.Commands.Building { public sealed class CmdDraw : DrawCmd { public override string name { get { return "Draw"; } } + + protected override int MarksCount { get { return 1; } } + protected override string SelectionType { get { return "origin"; } } protected override string PlaceMessage { get { return "Place a block to determine the origin."; } } - public override int MarksCount { get { return 1; } } protected override DrawMode GetMode(string[] parts) { string msg = parts[0]; @@ -45,38 +47,49 @@ namespace MCGalaxy.Commands.Building { protected override DrawOp GetDrawOp(DrawArgs dArgs) { AdvDrawOp op = null; switch (dArgs.Mode) { - case DrawMode.cone: op = new AdvConeDrawOp(); break; - case DrawMode.hcone: op = new AdvHollowConeDrawOp(); break; - case DrawMode.icone: op = new AdvConeDrawOp(true); break; - case DrawMode.hicone: op = new AdvHollowConeDrawOp(true); break; - case DrawMode.pyramid: op = new AdvPyramidDrawOp(); break; - case DrawMode.hpyramid: op = new AdvHollowPyramidDrawOp(); break; - case DrawMode.ipyramid: op = new AdvPyramidDrawOp(true); break; - case DrawMode.hipyramid: op = new AdvHollowPyramidDrawOp(true); break; - case DrawMode.sphere: op = new AdvSphereDrawOp(); break; - case DrawMode.hsphere: op = new AdvHollowSphereDrawOp(); break; - case DrawMode.volcano: op = new AdvVolcanoDrawOp(); break; + case DrawMode.cone: op = new AdvConeDrawOp(); break; + case DrawMode.hcone: op = new AdvHollowConeDrawOp(); break; + case DrawMode.icone: op = new AdvConeDrawOp(true); break; + case DrawMode.hicone: op = new AdvHollowConeDrawOp(true); break; + case DrawMode.pyramid: op = new AdvPyramidDrawOp(); break; + case DrawMode.hpyramid: op = new AdvHollowPyramidDrawOp(); break; + case DrawMode.ipyramid: op = new AdvPyramidDrawOp(true); break; + case DrawMode.hipyramid: op = new AdvHollowPyramidDrawOp(true); break; + case DrawMode.sphere: op = new AdvSphereDrawOp(); break; + case DrawMode.hsphere: op = new AdvHollowSphereDrawOp(); break; + case DrawMode.volcano: op = new AdvVolcanoDrawOp(); break; } if (op == null) { Help(dArgs.Player); return null; } + + AdvDrawMeta meta = new AdvDrawMeta(); + bool success = false; + string[] parts = dArgs.Message.SplitSpaces(); + Player p = dArgs.Player; - // Validate radius/height when the user first uses the command - int radius = 0, height = 0; - string[] args = dArgs.Message.SplitSpaces(); - if ((op.UsesHeight && !CheckTwoArgs(dArgs.Player, ref radius, ref height, args)) || - (!op.UsesHeight && !CheckOneArg(dArgs.Player, ref radius, args))) - return null; + if (op.UsesHeight) { + if (parts.Length < 3) { + Player.Message(p, "You need to provide the radius and the height for the {0}.", parts[0]); + } else { + success = CommandParser.GetInt(p, parts[1], "radius", ref meta.radius, 0, 2000) + && CommandParser.GetInt(p, parts[2], "height", ref meta.height, 0, 2000); + } + } else { + if (parts.Length < 2) { + Player.Message(p, "You need to provide the radius for the {0}.", parts[0]); + } else { + success = CommandParser.GetInt(p, parts[1], "radius", ref meta.radius, 0, 2000); + } + } + + if (!success) return null; + dArgs.Meta = meta; return op; } protected override void GetMarks(DrawArgs dArgs, ref Vec3S32[] m) { - int radius = 0, height = 0; - string[] args = dArgs.Message.SplitSpaces(); AdvDrawOp op = (AdvDrawOp)dArgs.Op; - - if ((op.UsesHeight && !CheckTwoArgs(dArgs.Player, ref radius, ref height, args)) || - (!op.UsesHeight && !CheckOneArg(dArgs.Player, ref radius, args))) { - m = null; return; - } + AdvDrawMeta meta = (AdvDrawMeta)dArgs.Meta; + int radius = meta.radius; Vec3S32 P = m[0]; m = new Vec3S32[] { @@ -85,7 +98,7 @@ namespace MCGalaxy.Commands.Building { }; if (op.UsesHeight) { - m[1].Y += height; + m[1].Y += meta.height; } else { m[0].Y -= radius; m[1].Y += radius; } @@ -96,20 +109,7 @@ namespace MCGalaxy.Commands.Building { dArgs.BrushArgs = dArgs.Message.Splice(argsUsed, 0); } - bool CheckTwoArgs(Player p, ref int radius, ref int height, string[] parts) { - if (parts.Length < 3) { - Player.Message(p, "You need to provide the radius and the height for the {0}.", parts[0]); return false; - } - return CommandParser.GetInt(p, parts[1], "radius", ref radius, 0, 2000) - && CommandParser.GetInt(p, parts[2], "height", ref height, 0, 2000); - } - - bool CheckOneArg(Player p, ref int radius, string[] parts) { - if (parts.Length < 2) { - Player.Message(p, "You need to provide the radius for the {0}.", parts[0]); return false; - } - return CommandParser.GetInt(p, parts[1], "radius", ref radius, 0, 2000); - } + class AdvDrawMeta { public int radius, height; } public override void Help(Player p) { Player.Message(p, "%T/Draw [object] [baseradius] [height] "); diff --git a/MCGalaxy/Commands/building/CmdFill.cs b/MCGalaxy/Commands/building/CmdFill.cs index d1f074954..12e27b007 100644 --- a/MCGalaxy/Commands/building/CmdFill.cs +++ b/MCGalaxy/Commands/building/CmdFill.cs @@ -25,13 +25,15 @@ namespace MCGalaxy.Commands.Building { public sealed class CmdFill : DrawCmd { public override string name { get { return "Fill"; } } public override string shortcut { get { return "f"; } } - public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } } - protected override string PlaceMessage { get { return "Place or break a block to mark the area you wish to fill."; } } - public override int MarksCount { get { return 1; } } + public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } } public override CommandAlias[] Aliases { get { return new[] { new CommandAlias("F3D"), new CommandAlias("F2D", "2d"), new CommandAlias("Fill3D"), new CommandAlias("Fill2D", "2d") }; } } + + protected override int MarksCount { get { return 1; } } + protected override string SelectionType { get { return "origin"; } } + protected override string PlaceMessage { get { return "Place or break a block to mark the area you wish to fill."; } } protected override DrawMode GetMode(string[] parts) { if (parts[parts.Length - 1].CaselessEq("confirm")) { diff --git a/MCGalaxy/Commands/building/CmdLine.cs b/MCGalaxy/Commands/building/CmdLine.cs index cff2717b5..905be867f 100644 --- a/MCGalaxy/Commands/building/CmdLine.cs +++ b/MCGalaxy/Commands/building/CmdLine.cs @@ -24,6 +24,8 @@ namespace MCGalaxy.Commands.Building { public sealed class CmdLine : DrawCmd { public override string name { get { return "Line"; } } public override string shortcut { get { return "l"; } } + + protected override string SelectionType { get { return "endpoints"; } } protected override string PlaceMessage { get { return "Place or break two blocks to determine the endpoints."; } } protected override DrawMode GetMode(string[] parts) { @@ -91,7 +93,7 @@ namespace MCGalaxy.Commands.Building { if (dArgs.Mode != DrawMode.wire) return true; // special for connected line mode - p.MakeSelection(MarksCount, "Selecting region for %S" + dArgs.Op.Name, dArgs, DoDraw); + p.MakeSelection(MarksCount, "Selecting endpoints for %S" + dArgs.Op.Name, dArgs, DoDraw); Vec3U16 pos = p.lastClick; p.DoBlockchangeCallback(pos.X, pos.Y, pos.Z, p.GetHeldBlock()); return false; diff --git a/MCGalaxy/Commands/building/CmdRainbow.cs b/MCGalaxy/Commands/building/CmdRainbow.cs index 85318bbb7..3d1c6558c 100644 --- a/MCGalaxy/Commands/building/CmdRainbow.cs +++ b/MCGalaxy/Commands/building/CmdRainbow.cs @@ -23,6 +23,7 @@ namespace MCGalaxy.Commands.Building { public sealed class CmdRainbow : DrawCmd { public override string name { get { return "Rainbow"; } } public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } } + protected override void GetBrush(DrawArgs dArgs) { dArgs.BrushName = "normal"; } protected override DrawOp GetDrawOp(DrawArgs dArgs) { diff --git a/MCGalaxy/Commands/building/CmdTriangle.cs b/MCGalaxy/Commands/building/CmdTriangle.cs index 3e80d14df..3d4b90732 100644 --- a/MCGalaxy/Commands/building/CmdTriangle.cs +++ b/MCGalaxy/Commands/building/CmdTriangle.cs @@ -22,11 +22,9 @@ namespace MCGalaxy.Commands.Building { public sealed class CmdTriangle : DrawCmd { public override string name { get { return "Triangle"; } } public override string shortcut { get { return "tri"; } } - public override int MarksCount { get { return 3; } } - protected override string PlaceMessage { - get { return "Place three blocks to determine the edges."; } - } + protected override int MarksCount { get { return 3; } } + protected override string PlaceMessage { get { return "Place three blocks to determine the edges."; } } protected override DrawOp GetDrawOp(DrawArgs dArgs) { return new TriangleDrawOp(); diff --git a/MCGalaxy/Commands/building/CmdWrite.cs b/MCGalaxy/Commands/building/CmdWrite.cs index 27571fb3b..8dc0f7e0c 100644 --- a/MCGalaxy/Commands/building/CmdWrite.cs +++ b/MCGalaxy/Commands/building/CmdWrite.cs @@ -16,56 +16,45 @@ permissions and limitations under the Licenses. */ using System; -using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Ops; using MCGalaxy.Maths; -using BlockID = System.UInt16; namespace MCGalaxy.Commands.Building { - public class CmdWriteText : Command { + public class CmdWriteText : DrawCmd { public override string name { get { return "WriteText"; } } public override string shortcut { get { return "wrt"; } } - public override string type { get { return CommandTypes.Building; } } - public override bool museumUsable { get { return false; } } public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } } - public override bool SuperUseable { get { return false; } } - public override void Use(Player p, string message) { + protected override string SelectionType { get { return "direction"; } } + protected override string PlaceMessage { get { return "Place or break two blocks to determine direction."; } } + + protected override DrawOp GetDrawOp(DrawArgs dArgs) { + Player p = dArgs.Player; if (!p.group.CanExecute("Write")) { - Player.Message(p, "You must be able to use /write to use /writetext."); return; + Player.Message(p, "You must be able to use %T/Write %Sto use %T/WriteText."); return null; } - if (message.Length == 0) { Help(p); return; } - string[] args = message.SplitSpaces(3); - if (args.Length < 3) { Help(p); return; } + string[] args = dArgs.Message.SplitSpaces(3); + if (args.Length < 3) { Help(p); return null; } byte scale = 1, spacing = 1; - if (!byte.TryParse(args[0], out scale)) scale = 1; - if (!byte.TryParse(args[1], out spacing)) spacing = 1; - - WriteArgs wArgs = new WriteArgs(); - wArgs.scale = scale; wArgs.spacing = spacing; - wArgs.message = args[2].ToUpper(); - Player.Message(p, "Place or break two blocks to determine direction."); - p.MakeSelection(2, "Selecting direction for %SWrite", wArgs, DoWrite); - } - - bool DoWrite(Player p, Vec3S32[] marks, object state, BlockID block) { - WriteArgs wArgs = (WriteArgs)state; - if (marks[0].X == marks[1].X && marks[0].Z == marks[1].Z) { - Player.Message(p, "No direction was selected"); return false; - } + if (!CommandParser.GetByte(p, args[0], "Scale", ref scale)) return null; + if (!CommandParser.GetByte(p, args[1], "Spacing", ref spacing)) return null; WriteDrawOp op = new WriteDrawOp(); - op.Text = wArgs.message; - op.Scale = wArgs.scale; op.Spacing = wArgs.spacing; - - Brush brush = new SolidBrush(block); - DrawOpPerformer.Do(op, brush, p, marks); - return true; + op.Scale = scale; op.Spacing = spacing; + op.Text = args[2].ToUpper(); + return op; + } + + + protected override void GetMarks(DrawArgs dArgs, ref Vec3S32[] m) { + if (m[0].X != m[1].X || m[0].Z != m[1].Z) return; + Player.Message(dArgs.Player, "No direction was selected"); + m = null; } - class WriteArgs { public byte scale, spacing; public string message; } + protected override void GetBrush(DrawArgs dArgs) { dArgs.BrushArgs = ""; } public override void Help(Player p) { Player.Message(p, "%T/WriteText [scale] [spacing] [message]"); diff --git a/MCGalaxy/Commands/building/DrawCmd.cs b/MCGalaxy/Commands/building/DrawCmd.cs index 4a80d3ec6..506fff8ec 100644 --- a/MCGalaxy/Commands/building/DrawCmd.cs +++ b/MCGalaxy/Commands/building/DrawCmd.cs @@ -26,8 +26,11 @@ namespace MCGalaxy.Commands.Building { public override string type { get { return CommandTypes.Building; } } public override bool museumUsable { get { return false; } } public override LevelPermission defaultRank { get { return LevelPermission.Builder; } } - public virtual int MarksCount { get { return 2; } } public override bool SuperUseable { get { return false; } } + + protected virtual int MarksCount { get { return 2; } } + protected virtual string SelectionType { get { return "region"; } } + protected virtual string PlaceMessage { get { return "Place or break two blocks to determine the edges."; } } protected const string BrushHelpLine = " %HFor help about brushes, type %T/Help Brush%H."; public override void Use(Player p, string message) { @@ -47,7 +50,7 @@ namespace MCGalaxy.Commands.Building { if (!factory.Validate(bArgs)) return; Player.Message(p, PlaceMessage); - p.MakeSelection(MarksCount, "Selecting region for %S" + dArgs.Op.Name, dArgs, DoDraw); + p.MakeSelection(MarksCount, "Selecting " + SelectionType + " for %S" + dArgs.Op.Name, dArgs, DoDraw); } protected virtual bool DoDraw(Player p, Vec3S32[] marks, object state, BlockID block) { @@ -73,11 +76,7 @@ namespace MCGalaxy.Commands.Building { if (args.BrushArgs.Length == 0) args.BrushArgs = args.Player.DefaultBrushArgs; return BrushFactory.Find(args.BrushName); } - - protected virtual string PlaceMessage { - get { return "Place or break two blocks to determine the edges."; } - } - + protected virtual DrawMode GetMode(string[] parts) { return DrawMode.normal; } @@ -97,6 +96,7 @@ namespace MCGalaxy.Commands.Building { public DrawOp Op; public Player Player; + public object Meta; } } diff --git a/MCGalaxy/Commands/building/ReplaceCmd.cs b/MCGalaxy/Commands/building/ReplaceCmds.cs similarity index 100% rename from MCGalaxy/Commands/building/ReplaceCmd.cs rename to MCGalaxy/Commands/building/ReplaceCmds.cs diff --git a/MCGalaxy/Drawing/DrawOps/WriteDrawOp.cs b/MCGalaxy/Drawing/DrawOps/WriteDrawOp.cs index 2553400ca..1a14dbc7f 100644 --- a/MCGalaxy/Drawing/DrawOps/WriteDrawOp.cs +++ b/MCGalaxy/Drawing/DrawOps/WriteDrawOp.cs @@ -47,16 +47,16 @@ namespace MCGalaxy.Drawing.Ops { return blocks; } - int dirX, dirZ; - Vec3U16 pos; + Vec3S32 dir, pos; public override void Perform(Vec3S32[] marks, Brush brush, DrawOpOutput output) { - Vec3U16 p1 = Clamp(marks[0]), p2 = Clamp(marks[1]); - if (Math.Abs(p2.X - p1.X) > Math.Abs(p2.Z - p1.Z)) - dirX = p2.X > p1.X? 1 : -1; - else - dirZ = p2.Z > p1.Z ? 1 : -1; - pos = p1; + Vec3S32 p1 = marks[0], p2 = marks[1]; + if (Math.Abs(p2.X - p1.X) > Math.Abs(p2.Z - p1.Z)) { + dir.X = p2.X > p1.X ? 1 : -1; + } else { + dir.Z = p2.Z > p1.Z ? 1 : -1; + } + pos = p1; foreach (char c in Text) { DrawLetter(Player, c, brush, output); } @@ -65,8 +65,7 @@ namespace MCGalaxy.Drawing.Ops { void DrawLetter(Player p, char c, Brush brush, DrawOpOutput output) { if ((int)c >= 256 || letters[c] == 0) { if (c != ' ') Player.Message(p, "\"{0}\" is not currently supported, replacing with space.", c); - pos.X = (ushort)(pos.X + dirX * 4 * Scale); - pos.Z = (ushort)(pos.Z + dirZ * 4 * Scale); + pos += dir * (4 * Scale); } else { ulong flags = letters[c]; int shift = 56; while (flags != 0) { @@ -79,16 +78,14 @@ namespace MCGalaxy.Drawing.Ops { for (int ver = 0; ver < Scale; ver++) for (int hor = 0; hor < Scale; hor++) { - int x = pos.X + dirX * hor, y = pos.Y + j * Scale + ver, z = pos.Z + dirZ * hor; + int x = pos.X + dir.X * hor, y = pos.Y + j * Scale + ver, z = pos.Z + dir.Z * hor; output(Place((ushort)x, (ushort)y, (ushort)z, brush)); } } - pos.X = (ushort)(pos.X + dirX * Scale); - pos.Z = (ushort)(pos.Z + dirZ * Scale); + pos += dir * Scale; } } - pos.X = (ushort)(pos.X + dirX * Spacing); - pos.Z = (ushort)(pos.Z + dirZ * Spacing); + pos += dir * Spacing; } static int CountBits(int value) { diff --git a/MCGalaxy/MCGalaxy_.csproj b/MCGalaxy/MCGalaxy_.csproj index 637c66302..fcde4bfdc 100644 --- a/MCGalaxy/MCGalaxy_.csproj +++ b/MCGalaxy/MCGalaxy_.csproj @@ -157,7 +157,7 @@ - +