mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-22 12:05:51 -04:00
Now /write works with brushes, more accurate 'selecting X' messages for a few drawops
This commit is contained in:
parent
009556797d
commit
7a23e04531
@ -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") }; }
|
||||
}
|
||||
|
@ -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; }
|
||||
|
||||
// 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;
|
||||
AdvDrawMeta meta = new AdvDrawMeta();
|
||||
bool success = false;
|
||||
string[] parts = dArgs.Message.SplitSpaces();
|
||||
Player p = dArgs.Player;
|
||||
|
||||
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] <brush args>");
|
||||
|
@ -26,13 +26,15 @@ namespace MCGalaxy.Commands.Building {
|
||||
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 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")) {
|
||||
string prev = parts.Length >= 2 ? parts[parts.Length - 2] : "";
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
class WriteArgs { public byte scale, spacing; public string message; }
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
protected override void GetBrush(DrawArgs dArgs) { dArgs.BrushArgs = ""; }
|
||||
|
||||
public override void Help(Player p) {
|
||||
Player.Message(p, "%T/WriteText [scale] [spacing] [message]");
|
||||
|
@ -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) {
|
||||
@ -74,10 +77,6 @@ namespace MCGalaxy.Commands.Building {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -157,7 +157,7 @@
|
||||
<Compile Include="Commands\building\CmdSphere.cs" />
|
||||
<Compile Include="Commands\building\CmdTransform.cs" />
|
||||
<Compile Include="Commands\building\CmdTriangle.cs" />
|
||||
<Compile Include="Commands\building\ReplaceCmd.cs" />
|
||||
<Compile Include="Commands\building\ReplaceCmds.cs" />
|
||||
<Compile Include="Commands\building\CmdRestartPhysics.cs" />
|
||||
<Compile Include="Commands\building\CmdSpheroid.cs" />
|
||||
<Compile Include="Commands\building\CmdSpin.cs" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user