mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 04:32:50 -04:00
The great drawop rewrite part 3: The final frontier
This commit is contained in:
parent
687deb946b
commit
34cb2f7c7f
@ -40,24 +40,24 @@ 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();
|
||||
case DrawMode.wire: return new CuboidWireframeDrawOp();
|
||||
case DrawMode.random: return new CuboidDrawOp();
|
||||
}
|
||||
return new CuboidDrawOp();
|
||||
}
|
||||
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>");
|
||||
|
@ -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 ||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -32,16 +32,17 @@ 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;
|
||||
if (m[0].Y != m[1].Y) {
|
||||
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();
|
||||
}
|
||||
return new PyramidSolidDrawOp();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Help(Player p) {
|
||||
Player.Message(p, "%T/pyramid [brush args] <mode>");
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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 {
|
||||
|
@ -26,7 +26,7 @@ using MCGalaxy.Drawing.Brushes;
|
||||
|
||||
namespace MCGalaxy.Drawing.Ops {
|
||||
public abstract class AdvDrawOp : DrawOp {
|
||||
public int Radius { get { return (Max.X - Min.X) / 2; } }
|
||||
public int Radius { get { return (Max.X - Min.X) / 2; } }
|
||||
|
||||
public bool Invert;
|
||||
public virtual bool UsesHeight { get { return true; } }
|
||||
|
Loading…
x
Reference in New Issue
Block a user