Refactor drawing commands to use MakeSelection

This commit is contained in:
UnknownShadow200 2016-06-27 12:37:32 +10:00
parent 94687c57bb
commit 154d534f4b
13 changed files with 106 additions and 201 deletions

View File

@ -29,54 +29,42 @@ namespace MCGalaxy.Commands {
public override void Use(Player p, string message) {
if (message.IndexOf(' ') != -1) { Help(p); return; }
CatchPos cpos = default(CatchPos);
byte toIgnore = Block.air;
if (message != "") {
cpos.toIgnore = Block.Byte(message);
if (cpos.toIgnore == Block.Zero) {
toIgnore = Block.Byte(message);
if (toIgnore == Block.Zero) {
Player.Message(p, "Could not find block specified"); return;
}
}
p.blockchangeObject = cpos;
Player.Message(p, "Place two blocks to determine the edges.");
p.ClearBlockchange();
p.Blockchange += PlacedMark1;
p.MakeSelection(2, toIgnore, DoMeasure);
}
void PlacedMark1(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos bp = (CatchPos)p.blockchangeObject;
bp.x = x; bp.y = y; bp.z = z; p.blockchangeObject = bp;
p.Blockchange += PlacedMark2;
}
void PlacedMark2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos cpos = (CatchPos)p.blockchangeObject;
ushort minX = Math.Min(cpos.x, x), maxX = Math.Max(cpos.x, x);
ushort minY = Math.Min(cpos.y, y), maxY = Math.Max(cpos.y, y);
ushort minZ = Math.Min(cpos.z, z), maxZ = Math.Max(cpos.z, z);
int foundBlocks = 0;
bool DoMeasure(Player p, Vec3S32[] m, object state, byte type, byte extType) {
byte toIgnore = (byte)state;
int minX = Math.Min(m[0].X, m[1].X), maxX = Math.Max(m[0].X, m[1].X);
int minY = Math.Min(m[0].Y, m[1].Y), maxY = Math.Max(m[0].Y, m[1].Y);
int minZ = Math.Min(m[0].Z, m[1].Z), maxZ = Math.Max(m[0].Z, m[1].Z);
int found = 0;
for (ushort yy = minY; yy <= maxY; yy++)
for (ushort zz = minZ; zz <= maxZ; zz++)
for (ushort xx = minX; xx <= maxX; xx++)
for (int y = minY; y <= maxY; y++)
for (int z = minZ; z <= maxZ; z++)
for (int x = minX; x <= maxX; x++)
{
if (p.level.GetTile(xx, yy, zz) != cpos.toIgnore) foundBlocks++;
if (p.level.GetTile((ushort)x, (ushort)y, (ushort)z) != toIgnore)
found++;
}
int width = maxX - minX + 1, height = maxY - minY + 1, length = maxZ - minZ + 1;
Player.Message(p, "Measuring between (" + minX + ", " + minY + ", " + minZ +
") and (" + maxX + ", " + maxY + ", " + maxZ + ")");
Player.Message(p, "Area is " + width + " wide, " + height + " high, " + length + " long." +
" Volume is " + (width * height * length) + " blocks." );
string name = " non-" + Block.Name(cpos.toIgnore);
Player.Message(p, "There are " + foundBlocks + name + " blocks in the area.");
if (p.staticCommands) p.Blockchange += PlacedMark1;
Player.Message(p, "Measuring from &a({0}, {1}, {2})%S to &a({3}, {4}, {5})",
minX, minY, minZ, maxX, maxY, maxZ);
Player.Message(p, "Area is {0} wide, {1} high, {2} long. Volume is {3} blocks.",
width, height, length, width * height * length);
Player.Message(p, "There are {0} {1} blocks in the area.", found, "non-" + Block.Name(toIgnore));
return true;
}
struct CatchPos { public ushort x, y, z; public byte toIgnore; }
public override void Help(Player p) {
Player.Message(p, "%T/measure [ignore]");
Player.Message(p, "%HMeasures all the blocks between two points");

View File

@ -18,10 +18,8 @@
using System;
using MCGalaxy.Levels.IO;
namespace MCGalaxy.Commands {
public sealed class CmdRestoreSelection : Command {
namespace MCGalaxy.Commands {
public sealed class CmdRestoreSelection : Command {
public override string name { get { return "rs"; } }
public override string shortcut { get { return ""; } }
public override string type { get { return CommandTypes.Moderation; } }
@ -32,40 +30,26 @@ namespace MCGalaxy.Commands {
if (message == "") { Help(p); return; }
if (LevelInfo.ExistsBackup(p.level.name, message)) {
p.blockchangeObject = new CatchPos() { backup = message };
p.ClearBlockchange();
p.Blockchange += PlacedMark1;
p.SendMessage("Select two corners for restore.");
p.MakeSelection(2, message, DoRestore);
} else {
Player.Message(p, "Backup " + message + " does not exist.");
}
}
void PlacedMark1(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos bp = (CatchPos)p.blockchangeObject;
bp.x = x; bp.y = y; bp.z = z; p.blockchangeObject = bp;
p.Blockchange += PlacedMark2;
}
void PlacedMark2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos cpos = (CatchPos)p.blockchangeObject;
string path = LevelInfo.BackupPath(p.level.name, cpos.backup);
bool DoRestore(Player p, Vec3S32[] marks, object state, byte type, byte extType) {
string path = LevelInfo.BackupPath(p.level.name, (string)state);
try {
using(Level other = LvlFile.Load("tempLevel", path)) {
if (!CopyBlocks(p, other, x, y, z, cpos)) return;
}
if (p.staticCommands)
p.Blockchange += PlacedMark1;
using (Level other = LvlFile.Load("tempLevel", path))
return CopyBlocks(p, other, marks);
} catch (Exception ex) {
Server.ErrorLog(ex);
Server.s.Log("Restore selection failed");
return false;
}
}
static bool CopyBlocks(Player p, Level other, ushort x, ushort y, ushort z, CatchPos cpos) {
static bool CopyBlocks(Player p, Level other, Vec3S32[] m) {
byte[] blocks = other.blocks;
if (blocks.Length != p.level.blocks.Length) {
p.SendMessage("Cant restore selection of different size maps.");
@ -73,21 +57,21 @@ namespace MCGalaxy.Commands {
}
int width = other.Width, length = other.Length;
for (ushort yy = Math.Min(cpos.y, y); yy <= Math.Max(cpos.y, y); ++yy)
for (ushort zz = Math.Min(cpos.z, z); zz <= Math.Max(cpos.z, z); ++zz)
for (ushort xx = Math.Min(cpos.x, x); xx <= Math.Max(cpos.x, x); ++xx)
for (int y = Math.Min(m[0].Y, m[1].Y); y <= Math.Max(m[0].Y, m[1].Y); y++)
for (int z = Math.Min(m[0].Z, m[1].Z); z <= Math.Max(m[0].Z, m[1].Z); z++)
for (int x = Math.Min(m[0].X, m[1].X); x <= Math.Max(m[0].X, m[1].X); x++)
{
byte tile = blocks[xx + width * (zz + yy * length)], extTile = 0;
if (tile == Block.custom_block) extTile = other.GetExtTile(xx, yy, zz);
p.level.UpdateBlock(p, xx, yy, zz, tile, extTile);
byte tile = blocks[x + width * (z + y * length)], extTile = 0;
if (tile == Block.custom_block)
extTile = other.GetExtTile((ushort)x, (ushort)y, (ushort)z);
p.level.UpdateBlock(p, (ushort)x, (ushort)y, (ushort)z, tile, extTile);
}
return true;
}
struct CatchPos { public string backup; public ushort x, y, z; }
public override void Help(Player p) {
Player.Message(p, "/restoreselection <number> - restores a previous backup of the current selection");
Player.Message(p, "%T/restoreselection <number>");
Player.Message(p, "%Hrestores a previous backup of the current selection");
}
}
}

View File

@ -30,9 +30,8 @@ namespace MCGalaxy.Commands.Building {
new CommandAlias("box"), new CommandAlias("hbox", null, "hollow") }; }
}
protected override void PlacedMark2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos cpos = (CatchPos)p.blockchangeObject;
protected override bool DoDraw(Player p, Vec3S32[] marks, object state, byte type, byte extType) {
CatchPos cpos = (CatchPos)state;
GetRealBlock(type, extType, p, ref cpos);
DrawOp op = null;
Func<BrushArgs, Brush> constructor = null;
@ -59,11 +58,8 @@ namespace MCGalaxy.Commands.Building {
int brushOffset = cpos.mode == DrawMode.normal ? 0 : 1;
Brush brush = GetBrush(p, cpos, brushOffset, constructor);
if (brush == null) return;
if (!DrawOp.DoDrawOp(op, brush, p, cpos.x, cpos.y, cpos.z, x, y, z))
return;
if (p.staticCommands)
p.Blockchange += PlacedMark1;
if (brush == null) return false;
return DrawOp.DoDrawOp(op, brush, p, marks);
}
protected override DrawMode ParseMode(string msg) {

View File

@ -25,6 +25,7 @@ namespace MCGalaxy.Commands.Building {
public override string name { get { return "draw"; } }
public override string shortcut { get { return ""; } }
protected override string PlaceMessage { get { return "Place a block to determine the origin."; } }
public override int MarksCount { get { return 1; } }
protected override DrawMode ParseMode(string msg) {
if (msg == "cone") return DrawMode.cone;
@ -41,9 +42,8 @@ namespace MCGalaxy.Commands.Building {
return DrawMode.normal;
}
protected override void PlacedMark1(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos cpos = (CatchPos)p.blockchangeObject;
protected override bool DoDraw(Player p, Vec3S32[] m, object state, byte type, byte extType) {
CatchPos cpos = (CatchPos)state;
GetRealBlock(type, extType, p, ref cpos);
AdvDrawOp op = null;
switch (cpos.mode) {
@ -70,34 +70,28 @@ namespace MCGalaxy.Commands.Building {
case DrawMode.volcano:
op = new AdvVolcanoDrawOp(); break;
default:
Help(p); return;
Help(p); return false;
}
ushort radius = 0, height = 0;
string[] args = cpos.message.Split(' ');
if ((op.UsesHeight && !CheckTwoArgs(p, ref radius, ref height, args)) ||
(!op.UsesHeight && !CheckOneArg(p, ref radius, args))) return;
(!op.UsesHeight && !CheckOneArg(p, ref radius, args))) return false;
int brushOffset = op.UsesHeight ? 3 : 2;
Brush brush = GetBrush(p, cpos, brushOffset);
if (brush == null) return;
if (brush == null) return false;
Vec3S32[] marks = {
new Vec3S32(x - radius, y, z - radius),
new Vec3S32(x + radius, y, z + radius) };
new Vec3S32(m[0].X - radius, m[0].Y, m[0].Z - radius),
new Vec3S32(m[0].X + radius, m[0].Y, m[0].Z + radius) };
if (op.UsesHeight) {
marks[1].Y += height;
} else {
marks[0].Y -= radius; marks[1].Y += radius;
}
if (!DrawOp.DoDrawOp(op, brush, p, marks))
return;
if (p.staticCommands)
p.Blockchange += PlacedMark1;
}
return DrawOp.DoDrawOp(op, brush, p, marks);
}
protected override void PlacedMark2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) { }
bool CheckTwoArgs(Player p, ref ushort radius, ref ushort height, string[] parts) {
if (parts.Length < 3) { Help(p); return false; }
if (!ushort.TryParse(parts[parts.Length - 3], out height) || height > 2000 ||

View File

@ -26,6 +26,7 @@ namespace MCGalaxy.Commands.Building {
public override string shortcut { get { return "f"; } }
public override LevelPermission defaultRank { get { return LevelPermission.AdvBuilder; } }
protected override string PlaceMessage { get { return "Destroy the block you wish to fill."; } }
public override int MarksCount { get { return 1; } }
protected override DrawMode ParseMode(string msg) {
if (msg == "normal") return DrawMode.solid;
@ -37,16 +38,16 @@ namespace MCGalaxy.Commands.Building {
return DrawMode.normal;
}
protected override void PlacedMark1(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
p.ClearBlockchange();
CatchPos cpos = (CatchPos)p.blockchangeObject;
protected override bool DoDraw(Player p, Vec3S32[] marks, object state, byte type, byte extType) {
CatchPos cpos = (CatchPos)state;
ushort x = (ushort)marks[0].X, y = (ushort)marks[0].Y, z = (ushort)marks[0].Z;
byte oldType = p.level.GetTile(x, y, z), oldExtType = 0;
if (oldType == Block.custom_block)
oldExtType = p.level.GetExtTile(x, y, z);
p.RevertBlock(x, y, z);
GetRealBlock(type, extType, p, ref cpos);
if (!Block.canPlace(p, oldType) && !Block.BuildIn(oldType)) {
Player.Message(p, "Cannot fill with that."); return;
Player.Message(p, "Cannot fill with that."); return false;
}
SparseBitSet bits = new SparseBitSet(p.level.Width, p.level.Height, p.level.Length);
@ -65,17 +66,11 @@ namespace MCGalaxy.Commands.Building {
op.Positions = buffer;
int brushOffset = cpos.mode == DrawMode.normal ? 0 : 1;
Brush brush = GetBrush(p, cpos, brushOffset);
if (brush == null) return;
if (!DrawOp.DoDrawOp(op, brush, p, cpos.x, cpos.y, cpos.z, cpos.x, cpos.y, cpos.z))
return;
if (brush == null || !DrawOp.DoDrawOp(op, brush, p, marks)) return false;
bits.Clear();
op.Positions = null;
if (p.staticCommands)
p.Blockchange += PlacedMark1;
return true;
}
protected override void PlacedMark2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) { }
void FloodFill(Player p, ushort x, ushort y, ushort z, byte oldType, byte oldExtType, DrawMode fillType,
SparseBitSet bits, List<int> buffer, List<int> origins, int depth) {

View File

@ -52,20 +52,19 @@ namespace MCGalaxy.Commands.Building {
return ParseMode(parts[parts.Length - 2]);
}
protected override void PlacedMark2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos cpos = (CatchPos)p.blockchangeObject;
protected override bool DoDraw(Player p, Vec3S32[] m, object state, byte type, byte extType) {
CatchPos cpos = (CatchPos)state;
GetRealBlock(type, extType, p, ref cpos);
if (cpos.mode == DrawMode.straight) {
int dx = Math.Abs(cpos.x - x), dy = Math.Abs(cpos.y - y), dz = Math.Abs(cpos.z - z);
int dx = Math.Abs(m[0].X - m[1].X), dy = Math.Abs(m[0].Y - m[1].Y), dz = Math.Abs(m[0].Z - m[1].Z);
if (dx > dy && dx > dz) {
y = cpos.y; z = cpos.z;
m[1].Y = m[0].Y; m[1].Z = m[0].Z;
} else if (dy > dx && dy > dz) {
x = cpos.x; z = cpos.z;
m[1].X = m[0].X; m[1].Z = m[0].Z;
} else if (dz > dy && dz > dx) {
y = cpos.y; x = cpos.x;
m[1].X = m[0].X; m[1].Y = m[0].Y;
}
}
@ -76,12 +75,8 @@ namespace MCGalaxy.Commands.Building {
drawOp.MaxLength = (ushort)cpos.data; brushOffset++;
}
Brush brush = GetBrush(p, cpos, brushOffset);
if (brush == null) return;
if (!DrawOp.DoDrawOp(drawOp, brush, p, cpos.x, cpos.y, cpos.z, x, y, z))
return;
if (p.staticCommands)
p.Blockchange += PlacedMark1;
if (brush == null) return false;
return DrawOp.DoDrawOp(drawOp, brush, p, m);
}
public override void Help(Player p) {

View File

@ -25,18 +25,16 @@ namespace MCGalaxy.Commands.Building {
public override string name { get { return "pyramid"; } }
public override string shortcut { get { return "pd"; } }
protected override void PlacedMark2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos cpos = (CatchPos)p.blockchangeObject;
protected override bool DoDraw(Player p, Vec3S32[] marks, object state, byte type, byte extType) {
CatchPos cpos = (CatchPos)state;
GetRealBlock(type, extType, p, ref cpos);
DrawOp drawOp = null;
int brushOffset = cpos.mode == DrawMode.normal ? 0 : 1;
Brush brush = GetBrush(p, cpos, brushOffset);
if (brush == null) return;
if (brush == null) return false;
if (y != cpos.y) {
Player.Message(p, "The two edges of the pyramid must be on the same level");
return;
if (marks[0].Y != marks[1].Y) {
Player.Message(p, "The two edges of the pyramid must be on the same level"); return false;
}
switch (cpos.mode) {
@ -47,12 +45,8 @@ namespace MCGalaxy.Commands.Building {
drawOp = new PyramidHollowDrawOp(); break;
case DrawMode.reverse:
drawOp = new PyramidReverseDrawOp(); break;
}
if (!DrawOp.DoDrawOp(drawOp, brush, p, cpos.x, cpos.y, cpos.z, x, y, z))
return;
if (p.staticCommands)
p.Blockchange += PlacedMark1;
}
return DrawOp.DoDrawOp(drawOp, brush, p, marks);
}
protected override DrawMode ParseMode(string msg) {

View File

@ -33,8 +33,7 @@ namespace MCGalaxy.Commands.Building {
}
bool DoRainbow(Player p, Vec3S32[] marks, object state, byte type, byte extType) {
RainbowDrawOp op = new RainbowDrawOp();
return DrawOp.DoDrawOp(op, null, p, marks);
return DrawOp.DoDrawOp(new RainbowDrawOp(), null, p, marks);
}
public override void Help(Player p) {

View File

@ -35,9 +35,8 @@ namespace MCGalaxy.Commands.Building {
return DrawMode.normal;
}
protected override void PlacedMark2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos cpos = (CatchPos)p.blockchangeObject;
protected override bool DoDraw(Player p, Vec3S32[] m, object state, byte type, byte extType) {
CatchPos cpos = (CatchPos)state;
GetRealBlock(type, extType, p, ref cpos);
DrawOp op = null;
@ -53,17 +52,14 @@ namespace MCGalaxy.Commands.Building {
}
int brushOffset = cpos.mode == DrawMode.normal ? 0 : 1;
Brush brush = GetBrush(p, cpos, brushOffset, constructor);
if (brush == null) return;
if (brush == null) return false;
int dx = cpos.x - x, dy = cpos.y - y, dz = cpos.z - z;
int dx = m[0].X - m[1].X, dy = m[0].Y - m[1].Y, dz = m[0].Z - m[1].Z;
int R = (int)Math.Sqrt(dx * dx + dy * dy + dz * dz);
Vec3S32[] marks = { new Vec3S32(cpos.x - R, cpos.y - R, cpos.z - R),
new Vec3S32(cpos.x + R, cpos.y + R, cpos.z + R) };
Vec3S32[] marks = { new Vec3S32(m[0].X - R, m[0].Y - R, m[0].Z - R),
new Vec3S32(m[0].X + R, m[0].Y + R, m[0].Z + R) };
if (!DrawOp.DoDrawOp(op, brush, p, marks))
return;
if (p.staticCommands)
p.Blockchange += PlacedMark1;
return DrawOp.DoDrawOp(op, brush, p, m);
}
public override void Help(Player p) {

View File

@ -27,14 +27,13 @@ namespace MCGalaxy.Commands.Building {
get { return new[] { new CommandAlias("eh", null, "hollow"), new CommandAlias("cylinder", null, "vertical") }; }
}
protected override void PlacedMark2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos cpos = (CatchPos)p.blockchangeObject;
protected override bool DoDraw(Player p, Vec3S32[] marks, object state, byte type, byte extType) {
CatchPos cpos = (CatchPos)state;
GetRealBlock(type, extType, p, ref cpos);
DrawOp op = null;
int brushOffset = cpos.mode == DrawMode.normal ? 0 : 1;
Brush brush = GetBrush(p, cpos, brushOffset);
if (brush == null) return;
if (brush == null) return false;
switch (cpos.mode) {
case DrawMode.solid:
@ -44,12 +43,8 @@ namespace MCGalaxy.Commands.Building {
op = new EllipsoidHollowDrawOp(); break;
case DrawMode.vertical:
op = new CylinderDrawOp(); break;
}
if (!DrawOp.DoDrawOp(op, brush, p, cpos.x, cpos.y, cpos.z, x, y, z))
return;
if (p.staticCommands)
p.Blockchange += PlacedMark1;
}
return DrawOp.DoDrawOp(op, brush, p, marks);
}
protected override DrawMode ParseMode(string msg) {

View File

@ -29,24 +29,20 @@ namespace MCGalaxy.Commands.Building {
}
protected override string PlaceMessage { get { return "Place a block for the centre, then another for the radius."; } }
protected override void PlacedMark2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos cpos = (CatchPos)p.blockchangeObject;
protected override bool DoDraw(Player p, Vec3S32[] m, object state, byte type, byte extType) {
CatchPos cpos = (CatchPos)state;
GetRealBlock(type, extType, p, ref cpos);
DrawOp drawOp = new TorusDrawOp();
Brush brush = GetBrush(p, cpos, 0);
if (brush == null) return;
if (brush == null) return false;
int dx = cpos.x - x, dy = cpos.y - y, dz = cpos.z - z;
int dx = m[0].X - m[1].X, dy = m[0].Y - m[1].Y, dz = m[0].Z - m[1].Z;
int horR = (int)Math.Sqrt(dx * dx + dz * dz), verR = Math.Abs(dy);
Vec3S32[] marks = { new Vec3S32(cpos.x - horR, cpos.y - verR, cpos.z - horR),
new Vec3S32(cpos.x + horR, cpos.y + verR, cpos.z + horR) };
Vec3S32[] marks = { new Vec3S32(m[0].X - horR, m[0].Y - verR, m[0].Z - horR),
new Vec3S32(m[0].X + horR, m[0].Y + verR, m[0].Z + horR) };
if (!DrawOp.DoDrawOp(drawOp, brush, p, marks))
return;
if (p.staticCommands)
p.Blockchange += PlacedMark1;
return DrawOp.DoDrawOp(drawOp, brush, p, m);
}
protected override DrawMode ParseMode(string msg) { return DrawMode.normal; }

View File

@ -23,36 +23,21 @@ 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 void PlacedMark2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos bp = (CatchPos)p.blockchangeObject;
bp.x2 = x; bp.y2 = y; bp.z2 = z;
p.blockchangeObject = bp;
p.Blockchange += PlacedMark3;
}
void PlacedMark3(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos cpos = (CatchPos)p.blockchangeObject;
protected override bool DoDraw(Player p, Vec3S32[] marks, object state, byte type, byte extType) {
CatchPos cpos = (CatchPos)state;
GetRealBlock(type, extType, p, ref cpos);
Vec3S32[] marks = { new Vec3S32(cpos.x, cpos.y, cpos.z),
new Vec3S32(cpos.x2, cpos.y2, cpos.z2), new Vec3S32(x, y, z) };
Brush brush = GetBrush(p, cpos, 0, null);
if (brush == null) return;
if (!DrawOp.DoDrawOp(new TriangleDrawOp(), brush, p, marks))
return;
if (p.staticCommands)
p.Blockchange += PlacedMark1;
if (brush == null) return false;
return DrawOp.DoDrawOp(new TriangleDrawOp(), brush, p, marks);
}
protected override DrawMode ParseMode(string msg) {
return DrawMode.normal;
}
protected override DrawMode ParseMode(string msg) { return DrawMode.normal; }
public override void Help(Player p) {
Player.Message(p, "%T/triangle [brush args]");

View File

@ -23,6 +23,7 @@ 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 void Use(Player p, string message) {
if (Player.IsSuper(p)) { MessageInGameOnly(p); return; }
@ -33,25 +34,14 @@ namespace MCGalaxy.Commands.Building {
cpos.mode = GetMode(message, parts);
OnUse(p, message, parts, ref cpos);
p.blockchangeObject = cpos;
Player.Message(p, PlaceMessage);
p.ClearBlockchange();
p.Blockchange += PlacedMark1;
p.MakeSelection(MarksCount, cpos, DoDraw);
}
// most draw commands use two coordinates, so implement this here to simplify implementation.
protected virtual void PlacedMark1(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
RevertAndClearState(p, x, y, z);
CatchPos bp = (CatchPos)p.blockchangeObject;
bp.x = x; bp.y = y; bp.z = z;
p.blockchangeObject = bp;
p.Blockchange += PlacedMark2;
}
protected abstract bool DoDraw(Player p, Vec3S32[] marks, object state, byte type, byte extType);
protected virtual string PlaceMessage { get { return "Place two blocks to determine the edges."; } }
protected abstract void PlacedMark2(Player p, ushort x, ushort y, ushort z, byte type, byte extType);
protected abstract DrawMode ParseMode(string mode);
protected virtual void OnUse(Player p, string msg, string[] parts, ref CatchPos cpos) { }
@ -105,8 +95,6 @@ namespace MCGalaxy.Commands.Building {
protected struct CatchPos {
public DrawMode mode;
public byte type, extType;
public ushort x, y, z;
public ushort x2, y2, z2; // for triangle
public object data;
public string message;
}