The great drawop rewrite part 3: The final frontier

This commit is contained in:
UnknownShadow200 2016-08-05 12:43:54 +10:00
parent 687deb946b
commit 34cb2f7c7f
10 changed files with 91 additions and 87 deletions

View File

@ -40,16 +40,8 @@ namespace MCGalaxy.Commands.Building {
return DrawMode.normal;
}
protected override BrushFactory GetBrush(Player p, DrawArgs dArgs, ref int brushOffset) {
brushOffset = dArgs.mode == DrawMode.normal ? 0 : 1;
if (dArgs.mode == DrawMode.solid) return BrushFactory.Find("normal");
if (dArgs.mode == DrawMode.holes) return BrushFactory.Find("checkered");
if (dArgs.mode == DrawMode.random) return BrushFactory.Find("random");
return BrushFactory.Find(p.BrushName);
}
protected override DrawOp GetDrawOp(DrawArgs dArgs, Vec3S32[] m) {
switch (dArgs.mode) {
switch (dArgs.Mode) {
case DrawMode.hollow: return new CuboidHollowsDrawOp();
case DrawMode.walls: return new CuboidWallsDrawOp();
case DrawMode.holes: return new CuboidDrawOp();
@ -59,6 +51,14 @@ namespace MCGalaxy.Commands.Building {
return new CuboidDrawOp();
}
protected override BrushFactory GetBrush(Player p, DrawArgs dArgs, ref int brushOffset) {
brushOffset = dArgs.Mode == DrawMode.normal ? 0 : 1;
if (dArgs.Mode == DrawMode.solid) return BrushFactory.Find("normal");
if (dArgs.Mode == DrawMode.holes) return BrushFactory.Find("checkered");
if (dArgs.Mode == DrawMode.random) return BrushFactory.Find("random");
return BrushFactory.Find(p.BrushName);
}
public override void Help(Player p) {
Player.Message(p, "%T/cuboid [brush args] <mode>");
Player.Message(p, "%HDraws a cuboid between two points.");

View File

@ -43,7 +43,7 @@ namespace MCGalaxy.Commands.Building {
}
protected override DrawOp GetDrawOp(DrawArgs dArgs, Vec3S32[] m) {
switch (dArgs.mode) {
switch (dArgs.Mode) {
case DrawMode.cone: return new AdvConeDrawOp();
case DrawMode.hcone: return new AdvHollowConeDrawOp();
case DrawMode.icone: return new AdvConeDrawOp(true);
@ -56,36 +56,34 @@ namespace MCGalaxy.Commands.Building {
case DrawMode.hsphere: return new AdvHollowSphereDrawOp();
case DrawMode.volcano: return new AdvVolcanoDrawOp();
}
Help(p); return null;
Help(dArgs.Player); return null;
}
protected override bool GetMarks(DrawArgs dArgs, Vec3S32[] m) {
ushort radius = 0, height = 0;
string[] args = dArgs.Message.Split(' ');
AdvDrawOp op = (AdvDrawOp)dArgs.Op;
if ((op.UsesHeight && !CheckTwoArgs(dArgs.Player, ref radius, ref height, args)) ||
(!op.UsesHeight && !CheckOneArg(dArgs.Player, ref radius, args))) return false;
Vec3S32 P = m[0];
m[0] = new Vec3S32(P.X - radius, P.Y, P.Z - radius);
m[1] = new Vec3S32(P.X + radius, P.Y, P.Z + radius);
if (op.UsesHeight) {
m[1].Y += height;
} else {
m[0].Y -= radius; m[1].Y += radius;
}
return true;
}
protected override BrushFactory GetBrush(Player p, DrawArgs dArgs, ref int brushOffset) {
brushOffset = dArgs.Op.UsesHeight ? 3 : 2;
brushOffset = ((AdvDrawOp)dArgs.Op).UsesHeight ? 3 : 2;
return BrushFactory.Find(p.BrushName);
}
protected override bool DoDraw(Player p, Vec3S32[] m, object state, byte type, byte extType) {
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 false;
int brushOffset = op.UsesHeight ? 3 : 2;
Brush brush = ParseBrush(p, cpos, brushOffset);
if (brush == null) return false;
Vec3S32[] marks = {
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;
}
return DrawOp.DoDrawOp(op, brush, p, marks);
}
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

@ -50,26 +50,26 @@ namespace MCGalaxy.Commands.Building {
if (oldType == Block.custom_block)
oldExtType = p.level.GetExtTile(x, y, z);
cpos.block = type; cpos.extBlock = extType;
cpos.Block = type; cpos.ExtBlock = extType;
if (!Block.canPlace(p, oldType) && !Block.BuildIn(oldType)) {
Formatter.MessageBlock(p, "fill over ", oldType); return false;
}
SparseBitSet bits = new SparseBitSet(p.level.Width, p.level.Height, p.level.Length);
List<int> buffer = new List<int>(), origins = new List<int>();
FloodFill(p, x, y, z, oldType, oldExtType, cpos.mode, bits, buffer, origins, 0);
FloodFill(p, x, y, z, oldType, oldExtType, cpos.Mode, bits, buffer, origins, 0);
int totalFill = origins.Count;
for (int i = 0; i < totalFill; i++) {
int pos = origins[i];
p.level.IntToPos(pos, out x, out y, out z);
FloodFill(p, x, y, z, oldType, oldExtType, cpos.mode, bits, buffer, origins, 0);
FloodFill(p, x, y, z, oldType, oldExtType, cpos.Mode, bits, buffer, origins, 0);
totalFill = origins.Count;
}
FillDrawOp op = new FillDrawOp();
op.Positions = buffer;
int brushOffset = cpos.mode == DrawMode.normal ? 0 : 1;
int brushOffset = cpos.Mode == DrawMode.normal ? 0 : 1;
Brush brush = ParseBrush(p, cpos, brushOffset);
if (brush == null || !DrawOp.DoDrawOp(op, brush, p, marks)) return false;
bits.Clear();

View File

@ -26,11 +26,11 @@ namespace MCGalaxy.Commands.Building {
protected override string PlaceMessage { get { return "Place two blocks to determine the endpoints."; } }
protected override void OnUse(Player p, string msg, string[] parts, ref DrawArgs dArgs) {
if (parts.Length < 2 || dArgs.mode == DrawMode.normal) return;
if (parts.Length < 2 || dArgs.Mode == DrawMode.normal) return;
string arg = parts[parts.Length - 1];
ushort len;
if (ushort.TryParse(arg, out len))
dArgs.data = len;
dArgs.Data = len;
}
protected override DrawMode GetMode(string[] parts) {
@ -53,8 +53,8 @@ namespace MCGalaxy.Commands.Building {
return DrawMode.normal;
}
protected override void GetMarks(DrawArgs dArgs, Vec3S32[] m) {
if (dArgs.mode != DrawMode.straight) return;
protected override bool GetMarks(DrawArgs dArgs, Vec3S32[] m) {
if (dArgs.Mode != DrawMode.straight) return true;
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) {
@ -64,11 +64,12 @@ namespace MCGalaxy.Commands.Building {
} else if (dz > dy && dz > dx) {
m[1].X = m[0].X; m[1].Y = m[0].Y;
}
return true;
}
protected override BrushFactory GetBrush(Player p, DrawArgs dArgs, ref int brushOffset) {
brushOffset = dArgs.mode == DrawMode.normal ? 0 : 1;
if (dArgs.data != null) brushOffset++;
brushOffset = dArgs.Mode == DrawMode.normal ? 0 : 1;
if (dArgs.Data != null) brushOffset++;
return BrushFactory.Find(p.BrushName);
}

View File

@ -33,10 +33,11 @@ namespace MCGalaxy.Commands.Building {
protected override DrawOp GetDrawOp(DrawArgs dArgs, Vec3S32[] m) {
if (m[0].Y != m[1].Y) {
Player.Message(p, "The two edges of the pyramid must be on the same level"); return null;
Player.Message(dArgs.Player, "The two edges of the pyramid must be on the same level");
return null;
}
switch (dArgs.mode) {
switch (dArgs.Mode) {
case DrawMode.hollow: return new PyramidHollowDrawOp();
case DrawMode.reverse: return new PyramidReverseDrawOp();
}

View File

@ -40,26 +40,27 @@ namespace MCGalaxy.Commands.Building {
return DrawMode.normal;
}
protected override void GetMarks(DrawArgs dArgs, Vec3S32[] m) {
Vec3S32 p0 = m[0];
Vec3S32 radius = GetRadius(cpos.mode, m);
m[0] = p0 - radius; m[1] = p0 + radius;
}
protected override BrushFactory GetBrush(Player p, DrawArgs dArgs, ref int brushOffset) {
brushOffset = dArgs.mode == DrawMode.normal ? 0 : 1;
if (dArgs.mode == DrawMode.solid) return BrushFactory.Find("normal");
return BrushFactory.Find(p.BrushName);
}
protected override DrawOp GetDrawOp(DrawArgs dArg, Vec3S32[] m) {
switch (dArgs.mode) {
protected override DrawOp GetDrawOp(DrawArgs dArgs, Vec3S32[] m) {
switch (dArgs.Mode) {
case DrawMode.hollow: return new AdvHollowSphereDrawOp();
case DrawMode.circle: return new EllipsoidDrawOp();
}
return new AdvSphereDrawOp();
}
protected override bool GetMarks(DrawArgs dArgs, Vec3S32[] m) {
Vec3S32 p0 = m[0];
Vec3S32 radius = GetRadius(dArgs.Mode, m);
m[0] = p0 - radius; m[1] = p0 + radius;
return true;
}
protected override BrushFactory GetBrush(Player p, DrawArgs dArgs, ref int brushOffset) {
brushOffset = dArgs.Mode == DrawMode.normal ? 0 : 1;
if (dArgs.Mode == DrawMode.solid) return BrushFactory.Find("normal");
return BrushFactory.Find(p.BrushName);
}
static Vec3S32 GetRadius(DrawMode mode, Vec3S32[] m) {
int dx = Math.Abs(m[0].X - m[1].X);
int dy = Math.Abs(m[0].Y - m[1].Y);

View File

@ -28,13 +28,13 @@ namespace MCGalaxy.Commands.Building {
}
protected override BrushFactory GetBrush(Player p, DrawArgs dArgs, ref int brushOffset) {
brushOffset = dArgs.mode == DrawMode.normal ? 0 : 1;
if (dArgs.mode == DrawMode.solid) return BrushFactory.Find("normal");
brushOffset = dArgs.Mode == DrawMode.normal ? 0 : 1;
if (dArgs.Mode == DrawMode.solid) return BrushFactory.Find("normal");
return BrushFactory.Find(p.BrushName);
}
protected override DrawOp GetDrawOp(DrawArgs dArgs, Vec3S32[] m) {
switch (dArgs.mode) {
switch (dArgs.Mode) {
case DrawMode.hollow: return new EllipsoidHollowDrawOp();
case DrawMode.vertical: return new CylinderDrawOp();
}

View File

@ -30,13 +30,14 @@ namespace MCGalaxy.Commands.Building {
get { return "Place a block for the centre, then another for the radius."; }
}
protected override void GetMarks(DrawArgs dArgs, Vec3S32[] m) {
protected override bool GetMarks(DrawArgs dArgs, Vec3S32[] m) {
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 p0 = m[0];
m[0] = new Vec3S32(p0.X - horR, p0.Y - verR, p0.Z - horR);
m[1] = new Vec3S32(p0.X + horR, p0.Y + verR, p0.Z + horR);
return true;
}
protected override DrawOp GetDrawOp(DrawArgs dArgs, Vec3S32[] m) {

View File

@ -31,8 +31,8 @@ namespace MCGalaxy.Commands.Building {
message = message.ToLower();
string[] parts = message.Split(' ');
DrawArgs cpos = default(DrawArgs);
cpos.message = message;
cpos.mode = GetMode(parts);
cpos.Message = message;
cpos.Mode = GetMode(parts);
OnUse(p, message, parts, ref cpos);
Player.Message(p, PlaceMessage);
@ -42,7 +42,7 @@ namespace MCGalaxy.Commands.Building {
protected virtual bool DoDraw(Player p, Vec3S32[] marks,
object state, byte block, byte extBlock) {
DrawArgs dArgs = (DrawArgs)state;
dArgs.block = block; dArgs.extBlock = extBlock;
dArgs.Block = block; dArgs.ExtBlock = extBlock;
DrawOp op = GetDrawOp(dArgs, marks);
if (op == null) return false;
@ -63,12 +63,12 @@ namespace MCGalaxy.Commands.Building {
protected virtual void OnUse(Player p, string msg, string[] parts, ref DrawArgs cpos) { }
protected virtual DrawMode GetMode(string[] parts) { return DrawMode.Normal; }
protected virtual DrawMode GetMode(string[] parts) { return DrawMode.normal; }
protected virtual void GetMarks(DrawArgs dArgs, Vec3S32[] m) { return m; }
protected virtual bool GetMarks(DrawArgs dArgs, Vec3S32[] m) { return true; }
protected virtual BrushFactory GetBrush(Player p, DrawArgs dArgs, ref int brushOffset) {
brushOffset = dArgs.mode == DrawMode.normal ? 0 : 1;
brushOffset = dArgs.Mode == DrawMode.normal ? 0 : 1;
return BrushFactory.Find(p.BrushName);
}
@ -99,26 +99,28 @@ namespace MCGalaxy.Commands.Building {
protected static Brush ParseBrush(Player p, DrawArgs dArgs,
int usedFromEnd, BrushFactory factory = null) {
int end = dArgs.message.Length;
int end = dArgs.Message.Length;
string brushMsg = "";
for (int i = 0; i < usedFromEnd; i++) {
end = dArgs.message.LastIndexOf(' ', end - 1);
end = dArgs.Message.LastIndexOf(' ', end - 1);
if (end == -1) break;
}
if (end >= 0) brushMsg = dArgs.message.Substring(0, end);
if (end >= 0) brushMsg = dArgs.Message.Substring(0, end);
if (brushMsg == "") brushMsg = p.DefaultBrushArgs;
if (factory == null) factory = BrushFactory.Find(p.BrushName);
BrushArgs args = new BrushArgs(p, brushMsg, dArgs.block, dArgs.extBlock);
BrushArgs args = new BrushArgs(p, brushMsg, dArgs.Block, dArgs.ExtBlock);
return factory.Construct(args);
}
protected struct DrawArgs {
public DrawMode mode;
public byte block, extBlock;
public object data;
public string message;
public DrawMode Mode;
public byte Block, ExtBlock;
public string Message;
public object Data;
public DrawOp Op;
public Player Player;
}
protected enum DrawMode {