Rewrite DrawOps to use Action delegate instead of yield return.

This commit is contained in:
UnknownShadow200 2016-08-30 23:54:31 +10:00
parent f06e5224a8
commit 4e271d1ede
20 changed files with 141 additions and 165 deletions

View File

@ -34,7 +34,7 @@ namespace MCGalaxy.Drawing.Ops {
return (long)(Math.PI / 3 * (R * R * H));
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
Vec3S32 C = (Min + Max) / 2;
int height = Max.Y - Min.Y;
@ -53,7 +53,7 @@ namespace MCGalaxy.Drawing.Ops {
byte ctile = lvl.GetTile(x, y, z);
if (ctile != 0) continue;
yield return Place(x, y, z, brush);
output(Place(x, y, z, brush));
}
}
}
@ -69,7 +69,7 @@ namespace MCGalaxy.Drawing.Ops {
return (long)(outer - inner);
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
Vec3S32 C = (Min + Max) / 2;
int height = Max.Y - Min.Y;
@ -89,7 +89,7 @@ namespace MCGalaxy.Drawing.Ops {
byte ctile = lvl.GetTile(x, y, z);
if (ctile != 0) continue;
yield return Place(x, y, z, brush);
output(Place(x, y, z, brush));
}
}
}
@ -102,7 +102,7 @@ namespace MCGalaxy.Drawing.Ops {
return (long)(Math.PI / 3 * (R * R * H));
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
Vec3S32 C = (Min + Max) / 2;
int height = Max.Y - Min.Y;
@ -124,7 +124,7 @@ namespace MCGalaxy.Drawing.Ops {
bool layer = dist >= (curRadius - 1) * (curRadius - 1);
byte block = layer ? Block.grass : Block.lavastill;
yield return Place(x, y, z, block, 0);
output(Place(x, y, z, block, 0));
}
}
}

View File

@ -41,7 +41,7 @@ namespace MCGalaxy.Drawing.Ops {
return (long)(Math.PI * 4.0 / 3.0 * (R * R * R));
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
int upper = (Radius + 1) * (Radius + 1);
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
Vec3S32 C = (Min + Max) / 2;
@ -52,7 +52,7 @@ namespace MCGalaxy.Drawing.Ops {
{
int dist = (C.X - x) * (C.X - x) + (C.Y - y) * (C.Y - y) + (C.Z - z) * (C.Z - z);
if (dist < upper)
yield return Place(x, y, z, brush);
output(Place(x, y, z, brush));
}
}
}
@ -68,7 +68,7 @@ namespace MCGalaxy.Drawing.Ops {
return (long)(outer - inner);
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
int upper = (Radius + 1) * (Radius + 1), inner = (Radius - 1) * (Radius - 1);
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
Vec3S32 C = (Min + Max) / 2;
@ -79,7 +79,7 @@ namespace MCGalaxy.Drawing.Ops {
{
int dist = (C.X - x) * (C.X - x) + (C.Y - y) * (C.Y - y) + (C.Z - z) * (C.Z - z);
if (dist < upper && dist >= inner)
yield return Place(x, y, z, brush);
output(Place(x, y, z, brush));
}
}
}

View File

@ -34,7 +34,7 @@ namespace MCGalaxy.Drawing.Ops {
return (R * R * H) / 3;
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
Vec3S32 C = (Min + Max) / 2;
@ -52,7 +52,7 @@ namespace MCGalaxy.Drawing.Ops {
continue;
byte ctile = lvl.GetTile(x, y, z);
if (ctile != 0) continue;
yield return Place(x, y, z, brush);
output(Place(x, y, z, brush));
}
}
}
@ -68,7 +68,7 @@ namespace MCGalaxy.Drawing.Ops {
return outer - inner;
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
Vec3S32 C = (Min + Max) / 2;
int height = Max.Y - Min.Y;
@ -88,7 +88,7 @@ namespace MCGalaxy.Drawing.Ops {
byte ctile = lvl.GetTile(x, y, z);
if (ctile != 0) continue;
yield return Place(x, y, z, brush);
output(Place(x, y, z, brush));
}
}
}

View File

@ -28,13 +28,13 @@ namespace MCGalaxy.Drawing.Ops {
return (Max.X - Min.X + 1) * (Max.Y - Min.Y + 1) * (Max.Z - Min.Z + 1);
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
for (ushort y = p1.Y; y <= p2.Y; y++)
for (ushort z = p1.Z; z <= p2.Z; z++)
for (ushort x = p1.X; x <= p2.X; x++)
{
yield return Place(x, y, z, brush);
output(Place(x, y, z, brush));
}
}
}
@ -50,50 +50,48 @@ namespace MCGalaxy.Drawing.Ops {
return xQuadsVol + yQuadsVol + zQuadzVol;
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
int lenX = (p2.X - p1.X + 1), lenY = (p2.Y - p1.Y + 1);
foreach (var block in QuadY(p1.Y, p1.X, p1.Z, p2.X, p2.Z, brush))
yield return block;
foreach (var block in QuadY(p2.Y, p1.X, p1.Z, p2.X, p2.Z, brush))
yield return block;
QuadY(p1.Y, p1.X, p1.Z, p2.X, p2.Z, brush, output);
QuadY(p2.Y, p1.X, p1.Z, p2.X, p2.Z, brush, output);
if (lenY > 2) {
foreach (var block in QuadX(p1.X, (ushort)(p1.Y + 1), p1.Z, (ushort)(p2.Y - 1), p2.Z, brush))
yield return block;
foreach (var block in QuadX(p2.X, (ushort)(p1.Y + 1), p1.Z, (ushort)(p2.Y - 1), p2.Z, brush))
yield return block;
QuadX(p1.X, (ushort)(p1.Y + 1), p1.Z, (ushort)(p2.Y - 1), p2.Z, brush, output);
QuadX(p2.X, (ushort)(p1.Y + 1), p1.Z, (ushort)(p2.Y - 1), p2.Z, brush, output);
}
if (lenX > 2 && lenY > 2) {
foreach (var block in QuadZ(p1.Z, (ushort)(p1.Y + 1), (ushort)(p1.X + 1),
(ushort)(p2.Y - 1), (ushort)(p2.X - 1), brush))
yield return block;
foreach (var block in QuadZ(p2.Z, (ushort)(p1.Y + 1), (ushort)(p1.X + 1),
(ushort)(p2.Y - 1), (ushort)(p2.X - 1), brush))
yield return block;
QuadZ(p1.Z, (ushort)(p1.Y + 1), (ushort)(p1.X + 1),
(ushort)(p2.Y - 1), (ushort)(p2.X - 1), brush, output);
QuadZ(p2.Z, (ushort)(p1.Y + 1), (ushort)(p1.X + 1),
(ushort)(p2.Y - 1), (ushort)(p2.X - 1), brush, output);
}
}
protected IEnumerable<DrawOpBlock> QuadX(ushort x, ushort y1, ushort z1, ushort y2, ushort z2, Brush brush) {
protected void QuadX(ushort x, ushort y1, ushort z1, ushort y2, ushort z2,
Brush brush, Action<DrawOpBlock> output) {
for (ushort y = y1; y <= y2; y++)
for (ushort z = z1; z <= z2; z++)
{
yield return Place(x, y, z, brush);
output(Place(x, y, z, brush));
}
}
protected IEnumerable<DrawOpBlock> QuadY(ushort y, ushort x1, ushort z1, ushort x2, ushort z2, Brush brush) {
protected void QuadY(ushort y, ushort x1, ushort z1, ushort x2, ushort z2,
Brush brush, Action<DrawOpBlock> output) {
for (ushort z = z1; z <= z2; z++)
for (ushort x = x1; x <= x2; x++)
{
yield return Place(x, y, z, brush);
output(Place(x, y, z, brush));
}
}
protected IEnumerable<DrawOpBlock> QuadZ(ushort z, ushort y1, ushort x1, ushort y2, ushort x2, Brush brush) {
protected void QuadZ(ushort z, ushort y1, ushort x1, ushort y2, ushort x2,
Brush brush, Action<DrawOpBlock> output) {
for (ushort y = y1; y <= y2; y++)
for (ushort x = x1; x <= x2; x++)
{
yield return Place(x, y, z, brush);
output(Place(x, y, z, brush));
}
}
}
@ -108,19 +106,15 @@ namespace MCGalaxy.Drawing.Ops {
return xQuadsVol + zQuadsVol;
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
int lenX = (p2.X - p1.X + 1);
foreach (var block in QuadX(p1.X, p1.Y, p1.Z, p2.Y, p2.Z, brush))
yield return block;
foreach (var block in QuadX(p2.X, p1.Y, p1.Z, p2.Y, p2.Z, brush))
yield return block;
QuadX(p1.X, p1.Y, p1.Z, p2.Y, p2.Z, brush, output);
QuadX(p2.X, p1.Y, p1.Z, p2.Y, p2.Z, brush, output);
if (lenX <= 2) yield break;
foreach (var block in QuadZ(p1.Z, p1.Y, (ushort)(p1.X + 1), p2.Y, (ushort)(p2.X - 1), brush))
yield return block;
foreach (var block in QuadZ(p2.Z, p1.Y, (ushort)(p1.X + 1), p2.Y, (ushort)(p2.X - 1), brush))
yield return block;
if (lenX <= 2) return;
QuadZ(p1.Z, p1.Y, (ushort)(p1.X + 1), p2.Y, (ushort)(p2.X - 1), brush, output);
QuadZ(p2.Z, p1.Y, (ushort)(p1.X + 1), p2.Y, (ushort)(p2.X - 1), brush, output);
}
}
@ -134,27 +128,27 @@ namespace MCGalaxy.Drawing.Ops {
return horSidesvol + verSidesVol;
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
for (ushort y = p1.Y; y <= p2.Y; y++ ) {
yield return Place(p1.X, y, p1.Z, brush);
yield return Place(p2.X, y, p1.Z, brush);
yield return Place(p1.X, y, p2.Z, brush);
yield return Place(p2.X, y, p2.Z, brush);
output(Place(p1.X, y, p1.Z, brush));
output(Place(p2.X, y, p1.Z, brush));
output(Place(p1.X, y, p2.Z, brush));
output(Place(p2.X, y, p2.Z, brush));
}
for (ushort z = p1.Z; z <= p2.Z; z++) {
yield return Place(p1.X, p1.Y, z, brush);
yield return Place(p2.X, p1.Y, z, brush);
yield return Place(p1.X, p2.Y, z, brush);
yield return Place(p2.X, p2.Y, z, brush);
output(Place(p1.X, p1.Y, z, brush));
output(Place(p2.X, p1.Y, z, brush));
output(Place(p1.X, p2.Y, z, brush));
output(Place(p2.X, p2.Y, z, brush));
}
for (ushort x = p1.X; x <= p2.X; x++) {
yield return Place(x, p1.Y, p1.Z, brush);
yield return Place(x, p1.Y, p2.Z, brush);
yield return Place(x, p2.Y, p1.Z, brush);
yield return Place(x, p2.Y, p2.Z, brush);
output(Place(x, p1.Y, p1.Z, brush));
output(Place(x, p1.Y, p2.Z, brush));
output(Place(x, p2.Y, p1.Z, brush));
output(Place(x, p2.Y, p2.Z, brush));
}
}
}

View File

@ -25,7 +25,7 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Hollow"; } }
public byte Skip;
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
for (ushort y = p1.Y; y <= p2.Y; y++)
for (ushort z = p1.Z; z <= p2.Z; z++)
@ -44,7 +44,7 @@ namespace MCGalaxy.Drawing.Ops {
hollow = false;
}
if (hollow)
yield return Place(x, y, z, Block.air, 0);
output(Place(x, y, z, Block.air, 0));
}
}
@ -59,7 +59,7 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Outline"; } }
public byte Block, ExtBlock, NewBlock, NewExtBlock;
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
for (ushort y = p1.Y; y <= p2.Y; y++)
for (ushort z = p1.Z; z <= p2.Z; z++)
@ -74,7 +74,7 @@ namespace MCGalaxy.Drawing.Ops {
outline |= Check(lvl, x, (ushort)(y + 1), z);
if (outline && !Check(lvl, x, y, z))
yield return Place(x, y, z, NewBlock, NewExtBlock);
output(Place(x, y, z, NewBlock, NewExtBlock));
}
}
@ -89,7 +89,7 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Rainbow"; } }
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
int dx = Math.Abs(p1.X - p2.X), dy = Math.Abs(p1.Y - p2.Y), dz = Math.Abs(p1.Z - p2.Z);
byte stepX = 0, stepY = 0, stepZ = 0;
@ -112,7 +112,7 @@ namespace MCGalaxy.Drawing.Ops {
for (ushort x = p1.X; x <= p2.X; x++) {
i = (i + stepX) % 13;
if (lvl.GetTile(x, y, z) != Block.air)
yield return Place(x, y, z, (byte)(Block.red + i), 0);
output(Place(x, y, z, (byte)(Block.red + i), 0));
}
i = startX;
}

View File

@ -70,7 +70,7 @@ namespace MCGalaxy.Drawing.Ops {
/// Note that this estimate assumes that all possibly affected blocks will be changed by the drawing command. </summary>
public abstract long BlocksAffected(Level lvl, Vec3S32[] marks);
public abstract IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush);
public abstract void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output);
public virtual bool CanDraw(Vec3S32[] marks, Player p, long affected) {
if (p != null && affected > p.group.maxBlocks) {

View File

@ -41,12 +41,12 @@ namespace MCGalaxy.Drawing.Ops {
return true;
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
ushort x, y, z;
for (int i = 0; i < Positions.Count; i++) {
int pos = Positions[i];
lvl.IntToPos(pos, out x, out y, out z);
yield return Place(x, y, z, brush);
output(Place(x, y, z, brush));
}
}
}

View File

@ -37,7 +37,7 @@ namespace MCGalaxy.Drawing.Ops {
}
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(marks[0]), p2 = Clamp(marks[1]);
List<Vec3U16> buffer = new List<Vec3U16>();
DrawLine(p1.X, p1.Y, p1.Z, MaxLength, p2.X, p2.Y, p2.Z, buffer);
@ -50,9 +50,9 @@ namespace MCGalaxy.Drawing.Ops {
Vec3U16 pos = buffer[i];
if (WallsMode) {
for (ushort yy = p1.Y; yy <= p2.Y; yy++)
yield return Place(pos.X, yy, pos.Z, brush);
output(Place(pos.X, yy, pos.Z, brush));
} else {
yield return Place(pos.X, pos.Y, pos.Z, brush);
output(Place(pos.X, pos.Y, pos.Z, brush));
}
}
}

View File

@ -37,7 +37,7 @@ namespace MCGalaxy.Drawing.Ops {
return lenX * lenZ * 3;
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
width = Max.X - Min.X;
if (width % 2 != 0) { width++; Min.X--; }
width -= 2;
@ -46,7 +46,7 @@ namespace MCGalaxy.Drawing.Ops {
length -= 2;
if (width <= 0 || length <= 0) {
Player.Message(p, "The corners of the maze need to be further apart."); yield break;
Player.Message(p, "The corners of the maze need to be further apart."); return;
}
Player.Message(p, "Generating maze... this could take a while");
GenerateMaze();
@ -54,34 +54,26 @@ namespace MCGalaxy.Drawing.Ops {
Vec3U16 min = Clamp(Min), max = Clamp(Max);
ushort y = min.Y;
for (ushort xx = 0; xx <= width; xx++)
for (ushort zz = 0; zz <= length; zz++)
if (wall[xx, zz])
for (ushort x = 0; x <= width; x++)
for (ushort z = 0; z <= length; z++)
if (wall[x, z])
{
yield return Place((ushort)(xx + min.X + 1), y, (ushort)(zz + min.Z + 1), Block.staircasefull, 0);
yield return Place((ushort)(xx + min.X + 1), (ushort)(y + 1), (ushort)(zz + min.Z + 1), Block.leaf, 0);
yield return Place((ushort)(xx + min.X + 1), (ushort)(y + 2), (ushort)(zz + min.Z + 1), Block.leaf, 0);
output(Place((ushort)(min.X + x + 1), y, (ushort)(min.Z + z + 1), Block.staircasefull, 0));
output(Place((ushort)(min.X + x + 1), (ushort)(y + 1), (ushort)(min.Z + z + 1), Block.leaf, 0));
output(Place((ushort)(min.X + x + 1), (ushort)(y + 2), (ushort)(min.Z + z + 1), Block.leaf, 0));
}
brush = new SolidBrush(Block.staircasefull, 0);
foreach (var block in QuadX(min.X, y, min.Z, y, max.Z, brush))
yield return block;
foreach (var block in QuadX(max.X, y, min.Z, y, max.Z, brush))
yield return block;
foreach (var block in QuadZ(min.Z, y, min.X, y, max.X, brush))
yield return block;
foreach (var block in QuadZ(max.Z, y, min.X, y, max.X, brush))
yield return block;
QuadX(min.X, y, min.Z, y, max.Z, brush, output);
QuadX(max.X, y, min.Z, y, max.Z, brush, output);
QuadZ(min.Z, y, min.X, y, max.X, brush, output);
QuadZ(max.Z, y, min.X, y, max.X, brush, output);
brush = new SolidBrush(Block.leaf, 0);
foreach (var block in QuadX(min.X, (ushort)(y + 1), min.Z, (ushort)(y + 2), max.Z, brush))
yield return block;
foreach (var block in QuadX(max.X, (ushort)(y + 1), min.Z, (ushort)(y + 2), max.Z, brush))
yield return block;
foreach (var block in QuadZ(min.Z, (ushort)(y + 1), min.X, (ushort)(y + 2), max.X, brush))
yield return block;
foreach (var block in QuadZ(max.Z, (ushort)(y + 1), min.X, (ushort)(y + 2), max.X, brush))
yield return block;
QuadX(min.X, (ushort)(y + 1), min.Z, (ushort)(y + 2), max.Z, brush, output);
QuadX(max.X, (ushort)(y + 1), min.Z, (ushort)(y + 2), max.Z, brush, output);
QuadZ(min.Z, (ushort)(y + 1), min.X, (ushort)(y + 2), max.X, brush, output);
QuadZ(max.Z, (ushort)(y + 1), min.X, (ushort)(y + 2), max.X, brush, output);
Player.Message(p, "Maze painted. Build the entrance and exit yourself");
randomizer = 0;

View File

@ -28,7 +28,7 @@ namespace MCGalaxy.Drawing.Ops {
return CopyState.UsedBlocks;
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
CopyState state = CopyState;
bool pasteAir = state.PasteAir;
// Adjust for the fact that paste origin may be outside the map.
@ -41,7 +41,7 @@ namespace MCGalaxy.Drawing.Ops {
ushort x = (ushort)(locX + x1), y = (ushort)(locY + y1), z = (ushort)(locZ + z1);
if ((b != Block.air || pasteAir) && lvl.InBound(x, y, z))
yield return Place(x, y, z, b, extB);
output(Place(x, y, z, b, extB));
}
}
}
@ -57,7 +57,7 @@ namespace MCGalaxy.Drawing.Ops {
return CopyState.UsedBlocks;
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
CopyState state = CopyState;
bool pasteAir = state.PasteAir;
ExtBlock[] include = Include, exclude = Exclude;
@ -81,14 +81,14 @@ namespace MCGalaxy.Drawing.Ops {
}
}
if (!place) continue;
yield return Place(x, y, z, b, extB);
output(Place(x, y, z, b, extB));
}
if (include != null) {
for (int j = 0; j < include.Length; j++) {
ExtBlock block = include[j];
if (b == block.Block && (b != Block.custom_block || extB == block.Ext)) {
yield return Place(x, y, z, b, extB); break;
output(Place(x, y, z, b, extB)); break;
}
}
}

View File

@ -49,15 +49,14 @@ namespace MCGalaxy.Drawing.Ops {
return total;
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3S32 p1 = Min, p2 = Max;
baseOp.Level = Level;
while (true) {
foreach (var block in baseOp.Perform(marks, p, lvl, brush))
yield return block;
baseOp.Perform(marks, p, lvl, brush, output);
if (p1.Y >= lvl.Height || Math.Abs(p2.X - p1.X) <= 1 || Math.Abs(p2.Z - p1.Z) <= 1)
yield break;
return;
p1.X++; p2.X--;
p1.Z++; p2.Z--;
@ -92,25 +91,23 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Pyramid reverse"; } }
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
wallOp.Min = Min; wallOp.Max = Max;
baseOp.Min = Min; baseOp.Max = Max;
wallOp.Level = Level; baseOp.Level = Level;
while (true) {
foreach (var block in wallOp.Perform(marks, p, lvl, brush))
yield return block;
wallOp.Perform(marks, p, lvl, brush, output);
if (p1.Y >= lvl.Height || Math.Abs(p2.X - p1.X) <= 1 || Math.Abs(p2.Z - p1.Z) <= 1)
yield break;
return;
p1.X++; p2.X--;
p1.Z++; p2.Z--;
wallOp.Min = p1; wallOp.Max = p2;
baseOp.Min = p1; baseOp.Max = p2;
foreach (var block in baseOp.Perform(marks, p, lvl, airBrush))
yield return block;
baseOp.Perform(marks, p, lvl, airBrush, output);
p1.Y = (ushort)(p1.Y + yDir); p2.Y = p1.Y;
wallOp.Min = p1; wallOp.Max = p2;
baseOp.Min = p1; baseOp.Max = p2;

View File

@ -35,15 +35,14 @@ namespace MCGalaxy.Drawing.Ops {
public override long BlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
UndoCache cache = p.UndoBuffer;
using (IDisposable locker = cache.ClearLock.AccquireReadLock()) {
if (RedoBlocks(p)) yield break;
if (RedoBlocks(p)) return;
}
bool found = false;
UndoFormat.DoRedo(p, p.name.ToLower(), Start, End, ref found);
yield break;
}
bool RedoBlocks(Player p) {

View File

@ -36,7 +36,7 @@ namespace MCGalaxy.Drawing.Ops {
return (Max.X - Min.X + 1) * (Max.Y - Min.Y + 1) * (Max.Z - Min.Z + 1);
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
for (ushort y = p1.Y; y <= p2.Y; y++)
for (ushort z = p1.Z; z <= p2.Z; z++)
@ -46,7 +46,7 @@ namespace MCGalaxy.Drawing.Ops {
if (tile == Block.custom_block) extTile = lvl.GetExtTile(x, y, z);
if (tile == Include.Block && (tile != Block.custom_block || extTile == Include.Ext))
yield return Place(x, y, z, brush);
output(Place(x, y, z, brush));
}
}
}
@ -66,7 +66,7 @@ namespace MCGalaxy.Drawing.Ops {
return (Max.X - Min.X + 1) * (Max.Y - Min.Y + 1) * (Max.Z - Min.Z + 1);
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
for (ushort y = p1.Y; y <= p2.Y; y++)
for (ushort z = p1.Z; z <= p2.Z; z++)
@ -76,7 +76,7 @@ namespace MCGalaxy.Drawing.Ops {
if (tile == Block.custom_block) extTile = lvl.GetExtTile(x, y, z);
if (tile != Exclude.Block || (tile == Block.custom_block && extTile != Exclude.Ext))
yield return Place(x, y, z, brush);
output(Place(x, y, z, brush));
}
}
}

View File

@ -28,7 +28,7 @@ namespace MCGalaxy.Drawing.Ops {
return (int)(Math.PI * 4.0/3.0 * rx * ry * rz);
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
/* Courtesy of fCraft's awesome Open-Source'ness :D */
double cx = (Min.X + Max.X) / 2.0, cy = (Min.Y + Max.Y) / 2.0, cz = (Min.Z + Max.Z) / 2.0;
double rx = (Max.X - Min.X) / 2.0 + 0.25, ry = (Max.Y - Min.Y) / 2.0 + 0.25, rz = (Max.Z - Min.Z) / 2.0 + 0.25;
@ -41,7 +41,7 @@ namespace MCGalaxy.Drawing.Ops {
{
double dx = xx - cx, dy = yy - cy, dz = zz - cz;
if ((dx * dx) * rx2 + (dy * dy) * ry2 + (dz * dz) * rz2 <= 1)
yield return Place(xx, yy, zz, brush);
output(Place(xx, yy, zz, brush));
}
}
}
@ -55,7 +55,7 @@ namespace MCGalaxy.Drawing.Ops {
return (int)(Math.PI * 4.0/3.0 * rx * ry * rz);
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
/* Courtesy of fCraft's awesome Open-Source'ness :D */
double cx = (Min.X + Max.X) / 2.0, cy = (Min.Y + Max.Y) / 2.0, cz = (Min.Z + Max.Z) / 2.0;
double rx = (Max.X - Min.X) / 2.0 + 0.25, ry = (Max.Y - Min.Y) / 2.0 + 0.25, rz = (Max.Z - Min.Z) / 2.0 + 0.25;
@ -74,7 +74,7 @@ namespace MCGalaxy.Drawing.Ops {
dx *= dx; dy *= dy; dz *= dz;
bool inRange = dx * rx2 + dy * ry2 + dz * rz2 <= 1;
if (inRange && (dx * smallrx2 + dy * smallry2 + dz * smallrz2 > 1))
yield return Place(xx, yy, zz, brush);
output(Place(xx, yy, zz, brush));
}
}
}
@ -88,7 +88,7 @@ namespace MCGalaxy.Drawing.Ops {
return (int)(Math.PI * rx * rz * height);
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
/* Courtesy of fCraft's awesome Open-Source'ness :D */
double cx = (Min.X + Max.X) / 2.0, cz = (Min.Z + Max.Z) / 2.0;
double rx = (Max.X - Min.X) / 2.0 + 0.25, rz = (Max.Z - Min.Z) / 2.0 + 0.25;
@ -105,7 +105,7 @@ namespace MCGalaxy.Drawing.Ops {
dx *= dx; dz *= dz;
bool inRange = dx * rx2 + dz * rz2 <= 1;
if (inRange && (dx * smallrx2 + dz * smallrz2 > 1))
yield return Place(xx, yy, zz, brush);
output(Place(xx, yy, zz, brush));
}
}
}

View File

@ -29,7 +29,7 @@ namespace MCGalaxy.Drawing.Ops {
return (int)(2 * Math.PI * Math.PI * rTube * rTube * rCentre);
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
double cx = (Min.X + Max.X) / 2.0, cy = (Min.Y + Max.Y) / 2.0, cz = (Min.Z + Max.Z) / 2.0;
double rx = (Max.X - Min.X) / 2.0 + 0.25, ry = (Max.Y - Min.Y) / 2.0 + 0.25, rz = (Max.Z - Min.Z) / 2.0 + 0.25;
double rTube = ry, rCentre = Math.Min(rx, rz) - rTube;
@ -44,7 +44,7 @@ namespace MCGalaxy.Drawing.Ops {
double dInner = rCentre - Math.Sqrt( dx + dz );
if (dInner * dInner + dy <= rTube * rTube * 0.5 + 0.25)
yield return Place(xx, yy, zz, brush);
output(Place(xx, yy, zz, brush));
}
}
}

View File

@ -41,15 +41,14 @@ namespace MCGalaxy.Drawing.Ops {
public override long BlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
if (brush == null) brush = defBrush;
Vec3U16 P = Clamp(marks[0]);
if (Type == T_Tree) return AddTree(lvl, P.X, P.Y, P.Z, brush);
if (Type == T_NotchTree) return AddNotchTree(lvl, P.X, P.Y, P.Z, brush);
if (Type == T_NotchSwamp) return AddNotchSwampTree(lvl, P.X, P.Y, P.Z, brush);
if (Type == T_Cactus) return AddCactus(lvl, P.X, P.Y, P.Z);
return null;
if (Type == T_Tree) AddTree(lvl, P.X, P.Y, P.Z, brush, output);
if (Type == T_NotchTree) AddNotchTree(lvl, P.X, P.Y, P.Z, brush, output);
if (Type == T_NotchSwamp) AddNotchSwampTree(lvl, P.X, P.Y, P.Z, brush, output);
if (Type == T_Cactus) AddCactus(lvl, P.X, P.Y, P.Z, output);
}
public override void SetMarks(Vec3S32[] marks) {
@ -78,11 +77,11 @@ namespace MCGalaxy.Drawing.Ops {
Max.X += size; Max.Z += size;
}
IEnumerable<DrawOpBlock> AddTree(Level lvl, ushort x, ushort y, ushort z, Brush brush) {
void AddTree(Level lvl, ushort x, ushort y, ushort z, Brush brush, Action<DrawOpBlock> output) {
for (ushort dy = 0; dy < top + height - 1; dy++) {
ushort yy = (ushort)(y + dy);
if (overwrite || lvl.GetTile(x, yy, z) == Block.air || (yy == y && lvl.GetTile(x, yy, z) == Block.shrub))
yield return Place(x, yy, z, Block.trunk, 0);
output(Place(x, yy, z, Block.trunk, 0));
}
for (short dy = (short)-top; dy <= top; ++dy)
@ -94,17 +93,17 @@ namespace MCGalaxy.Drawing.Ops {
ushort xx = (ushort)(x + dx), yy = (ushort)(y + dy + height), zz = (ushort)(z + dz);
if ((xx != x || zz != z || dy >= top - 1) && (overwrite || lvl.GetTile(xx, yy, zz) == Block.air))
yield return Place(xx, yy, zz, brush);
output(Place(xx, yy, zz, brush));
}
}
}
IEnumerable<DrawOpBlock> AddNotchTree(Level lvl, ushort x, ushort y, ushort z, Brush brush) {
void AddNotchTree(Level lvl, ushort x, ushort y, ushort z, Brush brush, Action<DrawOpBlock> output) {
for (int dy = 0; dy <= height; dy++) {
ushort yy = (ushort)(y + dy);
byte tile = lvl.GetTile(x, yy, z);
if (overwrite || tile == Block.air || (yy == y && tile == Block.shrub))
yield return Place(x, yy, z, Block.trunk, 0);
output(Place(x, yy, z, Block.trunk, 0));
}
for (int dy = top; dy <= height + 1; dy++) {
@ -121,20 +120,20 @@ namespace MCGalaxy.Drawing.Ops {
if (dy > height) continue;
if (random.Next(2) == 0)
yield return Place(xx, yy, zz, brush);
output(Place(xx, yy, zz, brush));
} else {
yield return Place(xx, yy, zz, brush);
output(Place(xx, yy, zz, brush));
}
}
}
}
IEnumerable<DrawOpBlock> AddNotchSwampTree(Level lvl, ushort x, ushort y, ushort z, Brush brush) {
void AddNotchSwampTree(Level lvl, ushort x, ushort y, ushort z, Brush brush, Action<DrawOpBlock> output) {
for (int dy = 0; dy <= height; dy++) {
ushort yy = (ushort)(y + dy);
byte tile = lvl.GetTile(x, yy, z);
if (overwrite || tile == Block.air || (yy == y && tile == Block.shrub))
yield return Place(x, yy, z, Block.trunk, 0);
output(Place(x, yy, z, Block.trunk, 0));
}
for (int dy = top; dy <= height + 1; dy++) {
@ -151,18 +150,18 @@ namespace MCGalaxy.Drawing.Ops {
if (dy > height) continue;
if (random.Next(2) == 0)
yield return Place(xx, yy, zz, brush);
output(Place(xx, yy, zz, brush));
} else {
yield return Place(xx, yy, zz, brush);
output(Place(xx, yy, zz, brush));
}
}
}
}
IEnumerable<DrawOpBlock> AddCactus(Level lvl, ushort x, ushort y, ushort z) {
void AddCactus(Level lvl, ushort x, ushort y, ushort z, Action<DrawOpBlock> output) {
for (ushort dy = 0; dy <= height; dy++) {
if (overwrite || lvl.GetTile(z, (ushort)(y + dy), z) == Block.air)
yield return Place(x, (ushort)(y + dy), z, Block.green, 0);
output(Place(x, (ushort)(y + dy), z, Block.green, 0));
}
int inX = 0, inZ = 0;
@ -174,11 +173,11 @@ namespace MCGalaxy.Drawing.Ops {
for (ushort dy = height; dy <= random.Next(height + 2, height + 5); dy++) {
if (overwrite || lvl.GetTile((ushort)(x + inX), (ushort)(y + dy), (ushort)(z + inZ)) == Block.air)
yield return Place((ushort)(x + inX), (ushort)(y + dy), (ushort)(z + inZ), Block.green, 0);
output(Place((ushort)(x + inX), (ushort)(y + dy), (ushort)(z + inZ), Block.green, 0));
}
for (ushort dy = height; dy <= random.Next(height + 2, height + 5); dy++) {
if (overwrite || lvl.GetTile((ushort)(x - inX), (ushort)(y + dy), (ushort)(z - inZ)) == Block.air)
yield return Place((ushort)(x - inX), (ushort)(y + dy), (ushort)(z - inZ), Block.green, 0);
output(Place((ushort)(x - inX), (ushort)(y + dy), (ushort)(z - inZ), Block.green, 0));
}
}

View File

@ -32,7 +32,7 @@ namespace MCGalaxy.Drawing.Ops {
return (int)Math.Sqrt(s * (s - a) * (s - b) * (s - c));
}
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3F32 V1 = marks[0], V2 = marks[1], V3 = marks[2];
Vec3F32 N = Vec3F32.Cross(V2 - V1, V3 - V1);
N = Vec3F32.Normalise(N);
@ -63,9 +63,9 @@ namespace MCGalaxy.Drawing.Ops {
float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
if (u >= 0 && v >= 0 && u + v <= 1) {
yield return Place(xx, yy, zz, brush);
output(Place(xx, yy, zz, brush));
} else if (Axis(P, V1, V2) || Axis(P, V1, V3) || Axis(P, V2, V3)) {
yield return Place(xx, yy, zz, brush);
output(Place(xx, yy, zz, brush));
}
}
}

View File

@ -41,10 +41,10 @@ namespace MCGalaxy.Drawing.Ops {
public override long BlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
UndoCache cache = who.UndoBuffer;
using (IDisposable locker = cache.ClearLock.AccquireReadLock()) {
if (UndoBlocks(who)) yield break;
if (UndoBlocks(who)) return;
}
bool found = false;
string target = who.name.ToLower();
@ -53,7 +53,6 @@ namespace MCGalaxy.Drawing.Ops {
UndoFormat.DoUndoArea(p, target, Start, Min, Max, ref found);
else
UndoFormat.DoUndo(p, target, Start, End, ref found);
yield break;
}
bool UndoBlocks(Player p) {
@ -80,13 +79,12 @@ namespace MCGalaxy.Drawing.Ops {
public override long BlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
string target = whoName.ToLower();
if (Min.X != ushort.MaxValue)
UndoFormat.DoUndoArea(p, target, Start, Min, Max, ref found);
else
UndoFormat.DoUndo(p, target, Start, DateTime.MaxValue, ref found);
yield break;
}
}
@ -98,7 +96,7 @@ namespace MCGalaxy.Drawing.Ops {
public override long BlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
if (lvl.UndoBuffer.Count != Server.physUndo) {
int count = lvl.currentUndo;
for (int i = count; i >= 0; i--) {
@ -119,7 +117,6 @@ namespace MCGalaxy.Drawing.Ops {
} catch { }
}
}
yield break;
}
bool CheckBlockPhysics(Player p, Level lvl, int i) {

View File

@ -41,7 +41,7 @@ namespace MCGalaxy.Drawing.Ops {
int dirX, dirZ;
Vec3U16 pos;
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> 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;
@ -50,12 +50,11 @@ namespace MCGalaxy.Drawing.Ops {
pos = p1;
foreach (char c in Text) {
foreach (var block in DrawLetter(p, lvl, c, brush))
yield return block;
DrawLetter(p, lvl, c, brush, output);
}
}
IEnumerable<DrawOpBlock> DrawLetter(Player p, Level lvl, char c, Brush brush) {
void DrawLetter(Player p, Level lvl, char c, Brush brush, Action<DrawOpBlock> output) {
if ((int)c >= 256 || letters[(int)c] == null) {
Player.Message(p, "\"" + c + "\" is not currently supported, replacing with space.");
pos.X = (ushort)(pos.X + dirX * 4 * Scale);
@ -71,7 +70,7 @@ namespace MCGalaxy.Drawing.Ops {
for (int hor = 0; hor < Scale; hor++)
{
int x = pos.X + dirX * hor, y = pos.Y + j * Scale + ver, z = pos.Z + dirZ * hor;
yield return Place((ushort)x, (ushort)y, (ushort)z, brush);
output(Place((ushort)x, (ushort)y, (ushort)z, brush));
}
}
pos.X = (ushort)(pos.X + dirX * Scale);

View File

@ -33,7 +33,7 @@ namespace MCGalaxy.Drawing.Ops {
internal int Mode, Direction;
internal bool Layer;
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
Vec3U16 p0 = Clamp(marks[0]);
PaletteEntry[] palette = ImagePalette.GetPalette(Mode);
PaletteEntry cur = default(PaletteEntry);
@ -67,10 +67,9 @@ namespace MCGalaxy.Drawing.Ops {
}
if (col.A < 20) cur.Block = Block.air;
yield return Place(X, Y, Z, cur.Block, 0);
output(Place(X, Y, Z, cur.Block, 0));
}
Source = null;
yield break;
}
void CalcMul(bool layer, int dir,