Rewrite all drawops to use iterators instead.

This commit is contained in:
UnknownShadow200 2016-07-04 19:31:55 +10:00
parent 48eea6202d
commit fe4a286a6d
25 changed files with 284 additions and 244 deletions

View File

@ -21,6 +21,7 @@
// //
// ~Merlin33069 // ~Merlin33069
using System; using System;
using System.Collections.Generic;
using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Brushes;
namespace MCGalaxy.Drawing.Ops { namespace MCGalaxy.Drawing.Ops {
@ -34,7 +35,7 @@ namespace MCGalaxy.Drawing.Ops {
return (long)(Math.PI / 3 * (R * R * H)); return (long)(Math.PI / 3 * (R * R * H));
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
Vec3S32 C = (Min + Max) / 2; Vec3S32 C = (Min + Max) / 2;
int height = Max.Y - Min.Y; int height = Max.Y - Min.Y;
@ -53,7 +54,7 @@ namespace MCGalaxy.Drawing.Ops {
byte ctile = lvl.GetTile(x, y, z); byte ctile = lvl.GetTile(x, y, z);
if (ctile != 0) continue; if (ctile != 0) continue;
PlaceBlock(p, lvl, x, y, z, brush); yield return Place(x, y, z, brush);
} }
} }
} }
@ -69,7 +70,7 @@ namespace MCGalaxy.Drawing.Ops {
return (long)(outer - inner); return (long)(outer - inner);
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
Vec3S32 C = (Min + Max) / 2; Vec3S32 C = (Min + Max) / 2;
int height = Max.Y - Min.Y; int height = Max.Y - Min.Y;
@ -89,7 +90,7 @@ namespace MCGalaxy.Drawing.Ops {
byte ctile = lvl.GetTile(x, y, z); byte ctile = lvl.GetTile(x, y, z);
if (ctile != 0) continue; if (ctile != 0) continue;
PlaceBlock(p, lvl, x, y, z, brush); yield return Place(x, y, z, brush);
} }
} }
} }
@ -103,7 +104,7 @@ namespace MCGalaxy.Drawing.Ops {
return (long)(Math.PI / 3 * (R * R * H)); return (long)(Math.PI / 3 * (R * R * H));
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
Vec3S32 C = (Min + Max) / 2; Vec3S32 C = (Min + Max) / 2;
int height = Max.Y - Min.Y; int height = Max.Y - Min.Y;
@ -122,9 +123,10 @@ namespace MCGalaxy.Drawing.Ops {
byte ctile = lvl.GetTile(x, y, z); byte ctile = lvl.GetTile(x, y, z);
if (ctile != 0) continue; if (ctile != 0) continue;
bool layer = dist >= (curRadius - 1) * (curRadius - 1); bool layer = dist >= (curRadius - 1) * (curRadius - 1);
byte type = layer ? Block.grass : Block.lavastill; byte type = layer ? Block.grass : Block.lavastill;
PlaceBlock(p, lvl, x, y, z, type, 0); yield return Place(x, y, z, type, 0);
} }
} }
} }

View File

@ -21,6 +21,7 @@
// //
// ~Merlin33069 // ~Merlin33069
using System; using System;
using System.Collections.Generic;
using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Brushes;
namespace MCGalaxy.Drawing.Ops { namespace MCGalaxy.Drawing.Ops {
@ -42,7 +43,7 @@ namespace MCGalaxy.Drawing.Ops {
return (long)(Math.PI * 4.0 / 3.0 * (R * R * R)); return (long)(Math.PI * 4.0 / 3.0 * (R * R * R));
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
int upper = (Radius + 1) * (Radius + 1); int upper = (Radius + 1) * (Radius + 1);
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
Vec3S32 C = (Min + Max) / 2; Vec3S32 C = (Min + Max) / 2;
@ -53,7 +54,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); int dist = (C.X - x) * (C.X - x) + (C.Y - y) * (C.Y - y) + (C.Z - z) * (C.Z - z);
if (dist < upper) if (dist < upper)
PlaceBlock(p, lvl, x, y, z, brush); yield return Place(x, y, z, brush);
} }
} }
} }
@ -70,7 +71,7 @@ namespace MCGalaxy.Drawing.Ops {
return (long)(outer - inner); return (long)(outer - inner);
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
int upper = (Radius + 1) * (Radius + 1), inner = (Radius - 1) * (Radius - 1); int upper = (Radius + 1) * (Radius + 1), inner = (Radius - 1) * (Radius - 1);
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
Vec3S32 C = (Min + Max) / 2; Vec3S32 C = (Min + Max) / 2;
@ -81,7 +82,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); 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) if (dist < upper && dist >= inner)
PlaceBlock(p, lvl, x, y, z, brush); yield return Place(x, y, z, brush);
} }
} }
} }

View File

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

View File

@ -16,6 +16,7 @@
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System; using System;
using System.Collections.Generic;
using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Brushes;
namespace MCGalaxy.Drawing.Ops { namespace MCGalaxy.Drawing.Ops {
@ -28,13 +29,13 @@ namespace MCGalaxy.Drawing.Ops {
return (Max.X - Min.X + 1) * (Max.Y - Min.Y + 1) * (Max.Z - Min.Z + 1); return (Max.X - Min.X + 1) * (Max.Y - Min.Y + 1) * (Max.Z - Min.Z + 1);
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
for (ushort y = p1.Y; y <= p2.Y; y++) for (ushort y = p1.Y; y <= p2.Y; y++)
for (ushort z = p1.Z; z <= p2.Z; z++) for (ushort z = p1.Z; z <= p2.Z; z++)
for (ushort x = p1.X; x <= p2.X; x++) for (ushort x = p1.X; x <= p2.X; x++)
{ {
PlaceBlock(p, lvl, x, y, z, brush); yield return Place(x, y, z, brush);
} }
} }
} }
@ -51,47 +52,50 @@ namespace MCGalaxy.Drawing.Ops {
return xQuadsVol + yQuadsVol + zQuadzVol; return xQuadsVol + yQuadsVol + zQuadzVol;
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
int lenX = (p2.X - p1.X + 1), lenY = (p2.Y - p1.Y + 1); int lenX = (p2.X - p1.X + 1), lenY = (p2.Y - p1.Y + 1);
QuadY(p1.Y, p1.X, p1.Z, p2.X, p2.Z, p, lvl, brush); foreach (var block in QuadY(p1.Y, p1.X, p1.Z, p2.X, p2.Z, brush))
QuadY(p2.Y, p1.X, p1.Z, p2.X, p2.Z, p, lvl, brush); yield return block;
foreach (var block in QuadY(p2.Y, p1.X, p1.Z, p2.X, p2.Z, brush))
yield return block;
if (lenY > 2) { if (lenY > 2) {
QuadX(p1.X, (ushort)(p1.Y + 1), p1.Z, (ushort)(p2.Y - 1), p2.Z, p, lvl, brush); foreach (var block in QuadX(p1.X, (ushort)(p1.Y + 1), p1.Z, (ushort)(p2.Y - 1), p2.Z, brush))
QuadX(p2.X, (ushort)(p1.Y + 1), p1.Z, (ushort)(p2.Y - 1), p2.Z, p, lvl, 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;
} }
if (lenX > 2 && lenY > 2) { if (lenX > 2 && lenY > 2) {
QuadZ(p1.Z, (ushort)(p1.Y + 1), (ushort)(p1.X + 1), foreach (var block in QuadZ(p1.Z, (ushort)(p1.Y + 1), (ushort)(p1.X + 1),
(ushort)(p2.Y - 1), (ushort)(p2.X - 1), p, lvl, brush); (ushort)(p2.Y - 1), (ushort)(p2.X - 1), brush))
QuadZ(p2.Z, (ushort)(p1.Y + 1), (ushort)(p1.X + 1), yield return block;
(ushort)(p2.Y - 1), (ushort)(p2.X - 1), p, lvl, brush); 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;
} }
} }
protected void QuadX(ushort x, ushort y1, ushort z1, ushort y2, ushort z2, protected IEnumerable<DrawOpBlock> QuadX(ushort x, ushort y1, ushort z1, ushort y2, ushort z2, Brush brush) {
Player p, Level lvl, Brush brush) {
for (ushort y = y1; y <= y2; y++) for (ushort y = y1; y <= y2; y++)
for (ushort z = z1; z <= z2; z++) for (ushort z = z1; z <= z2; z++)
{ {
PlaceBlock(p, lvl, x, y, z, brush); yield return Place(x, y, z, brush);
} }
} }
protected void QuadY(ushort y, ushort x1, ushort z1, ushort x2, ushort z2, protected IEnumerable<DrawOpBlock> QuadY(ushort y, ushort x1, ushort z1, ushort x2, ushort z2, Brush brush) {
Player p, Level lvl, Brush brush) {
for (ushort z = z1; z <= z2; z++) for (ushort z = z1; z <= z2; z++)
for (ushort x = x1; x <= x2; x++) for (ushort x = x1; x <= x2; x++)
{ {
PlaceBlock(p, lvl, x, y, z, brush); yield return Place(x, y, z, brush);
} }
} }
protected void QuadZ(ushort z, ushort y1, ushort x1, ushort y2, ushort x2, protected IEnumerable<DrawOpBlock> QuadZ(ushort z, ushort y1, ushort x1, ushort y2, ushort x2, Brush brush) {
Player p, Level lvl, Brush brush) {
for (ushort y = y1; y <= y2; y++) for (ushort y = y1; y <= y2; y++)
for (ushort x = x1; x <= x2; x++) for (ushort x = x1; x <= x2; x++)
{ {
PlaceBlock(p, lvl, x, y, z, brush); yield return Place(x, y, z, brush);
} }
} }
} }
@ -107,15 +111,19 @@ namespace MCGalaxy.Drawing.Ops {
return xQuadsVol + zQuadsVol; return xQuadsVol + zQuadsVol;
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
int lenX = (p2.X - p1.X + 1); int lenX = (p2.X - p1.X + 1);
QuadX(p1.X, p1.Y, p1.Z, p2.Y, p2.Z, p, lvl, brush); foreach (var block in QuadX(p1.X, p1.Y, p1.Z, p2.Y, p2.Z, brush))
QuadX(p2.X, p1.Y, p1.Z, p2.Y, p2.Z, p, lvl, brush); yield return block;
if (lenX > 2) { foreach (var block in QuadX(p2.X, p1.Y, p1.Z, p2.Y, p2.Z, brush))
QuadZ(p1.Z, p1.Y, (ushort)(p1.X + 1), p2.Y, (ushort)(p2.X - 1), p, lvl, brush); yield return block;
QuadZ(p2.Z, p1.Y, (ushort)(p1.X + 1), p2.Y, (ushort)(p2.X - 1), p, lvl, brush);
} 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;
} }
} }
@ -130,27 +138,27 @@ namespace MCGalaxy.Drawing.Ops {
return horSidesvol + verSidesVol; return horSidesvol + verSidesVol;
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
for (ushort y = p1.Y; y <= p2.Y; y++ ) { for (ushort y = p1.Y; y <= p2.Y; y++ ) {
PlaceBlock(p, lvl, p1.X, y, p1.Z, brush); yield return Place(p1.X, y, p1.Z, brush);
PlaceBlock(p, lvl, p2.X, y, p1.Z, brush); yield return Place(p2.X, y, p1.Z, brush);
PlaceBlock(p, lvl, p1.X, y, p2.Z, brush); yield return Place(p1.X, y, p2.Z, brush);
PlaceBlock(p, lvl, p2.X, y, p2.Z, brush); yield return Place(p2.X, y, p2.Z, brush);
} }
for (ushort z = p1.Z; z <= p2.Z; z++) { for (ushort z = p1.Z; z <= p2.Z; z++) {
PlaceBlock(p, lvl, p1.X, p1.Y, z, brush); yield return Place(p1.X, p1.Y, z, brush);
PlaceBlock(p, lvl, p2.X, p1.Y, z, brush); yield return Place(p2.X, p1.Y, z, brush);
PlaceBlock(p, lvl, p1.X, p2.Y, z, brush); yield return Place(p1.X, p2.Y, z, brush);
PlaceBlock(p, lvl, p2.X, p2.Y, z, brush); yield return Place(p2.X, p2.Y, z, brush);
} }
for (ushort x = p1.X; x <= p2.X; x++) { for (ushort x = p1.X; x <= p2.X; x++) {
PlaceBlock(p, lvl, x, p1.Y, p1.Z, brush); yield return Place(x, p1.Y, p1.Z, brush);
PlaceBlock(p, lvl, x, p1.Y, p2.Z, brush); yield return Place(x, p1.Y, p2.Z, brush);
PlaceBlock(p, lvl, x, p2.Y, p1.Z, brush); yield return Place(x, p2.Y, p1.Z, brush);
PlaceBlock(p, lvl, x, p2.Y, p2.Z, brush); yield return Place(x, p2.Y, p2.Z, brush);
} }
} }
} }

View File

@ -16,6 +16,7 @@
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System; using System;
using System.Collections.Generic;
using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Brushes;
namespace MCGalaxy.Drawing.Ops { namespace MCGalaxy.Drawing.Ops {
@ -25,7 +26,7 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Hollow"; } } public override string Name { get { return "Hollow"; } }
public byte Skip; public byte Skip;
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
for (ushort y = p1.Y; y <= p2.Y; y++) for (ushort y = p1.Y; y <= p2.Y; y++)
for (ushort z = p1.Z; z <= p2.Z; z++) for (ushort z = p1.Z; z <= p2.Z; z++)
@ -44,7 +45,7 @@ namespace MCGalaxy.Drawing.Ops {
hollow = false; hollow = false;
} }
if (hollow) if (hollow)
PlaceBlock(p, lvl, x, y, z, Block.air, 0); yield return Place(x, y, z, Block.air, 0);
} }
} }
@ -60,7 +61,7 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Outline"; } } public override string Name { get { return "Outline"; } }
public byte Type, ExtType, NewType, NewExtType; public byte Type, ExtType, NewType, NewExtType;
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
for (ushort y = p1.Y; y <= p2.Y; y++) for (ushort y = p1.Y; y <= p2.Y; y++)
for (ushort z = p1.Z; z <= p2.Z; z++) for (ushort z = p1.Z; z <= p2.Z; z++)
@ -75,7 +76,7 @@ namespace MCGalaxy.Drawing.Ops {
outline |= Check(lvl, x, (ushort)(y + 1), z); outline |= Check(lvl, x, (ushort)(y + 1), z);
if (outline && !Check(lvl, x, y, z)) if (outline && !Check(lvl, x, y, z))
PlaceBlock(p, lvl, x, y, z, NewType, NewExtType); yield return Place(x, y, z, NewType, NewExtType);
} }
} }
@ -90,7 +91,7 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Rainbow"; } } public override string Name { get { return "Rainbow"; } }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); 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); 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; byte stepX = 0, stepY = 0, stepZ = 0;
@ -113,7 +114,7 @@ namespace MCGalaxy.Drawing.Ops {
for (ushort x = p1.X; x <= p2.X; x++) { for (ushort x = p1.X; x <= p2.X; x++) {
i = (i + stepX) % 13; i = (i + stepX) % 13;
if (lvl.GetTile(x, y, z) != Block.air) if (lvl.GetTile(x, y, z) != Block.air)
PlaceBlock(p, lvl, x, y, z, (byte)(Block.red + i), 0); yield return Place(x, y, z, (byte)(Block.red + i), 0);
} }
i = startX; i = startX;
} }

View File

@ -16,6 +16,7 @@
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System; using System;
using MCGalaxy.BlockPhysics;
using MCGalaxy.Commands; using MCGalaxy.Commands;
using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Brushes;
using MCGalaxy.Drawing.Ops; using MCGalaxy.Drawing.Ops;
@ -41,9 +42,9 @@ namespace MCGalaxy.Drawing.Ops {
return DoDrawOp(op, brush, p, marks); return DoDrawOp(op, brush, p, marks);
} }
public static bool DoDrawOp(DrawOp op, Brush brush, Player p, public static bool DoDrawOp(DrawOp op, Brush brush, Player p,
Vec3S32[] marks, bool checkLimit = true) { Vec3S32[] marks, bool checkLimit = true) {
op.SetMarks(marks); op.SetMarks(marks);
op.Level = p == null ? null : p.level; op.Level = p == null ? null : p.level;
if (op.Level != null && !op.Level.DrawingAllowed) { if (op.Level != null && !op.Level.DrawingAllowed) {
Player.Message(p, "Drawing commands are turned off on this map."); Player.Message(p, "Drawing commands are turned off on this map.");
@ -66,8 +67,13 @@ namespace MCGalaxy.Drawing.Ops {
} }
static void AppendDrawOp(Player p, DrawOp op, Brush brush, Vec3S32[] marks, long affected) { static void AppendDrawOp(Player p, DrawOp op, Brush brush, Vec3S32[] marks, long affected) {
if (p == null) { op.Perform(marks, p, op.Level, brush); return; } if (p == null) {
foreach (var block in op.Perform(marks, p, op.Level, brush))
op.Level.Blockchange(block.X, block.Y, block.Z, block.Type,
false, default(PhysicsArgs), block.ExtType);
return;
}
PendingDrawOp item = new PendingDrawOp(); PendingDrawOp item = new PendingDrawOp();
item.Op = op; item.Op = op;
item.Brush = brush; item.Brush = brush;
@ -107,23 +113,62 @@ namespace MCGalaxy.Drawing.Ops {
int timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds; int timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;
entry.Start = Server.StartTime.AddTicks(timeDelta * TimeSpan.TicksPerSecond); entry.Start = Server.StartTime.AddTicks(timeDelta * TimeSpan.TicksPerSecond);
bool needReveal = item.Op.DetermineDrawOpMethod(item.Level, item.Affected); if (item.Brush != null) item.Brush.Configure(item.Op, p);
if (item.Brush != null) DoDrawOp(item, p);
item.Brush.Configure(item.Op, p);
item.Op.Perform(item.Marks, p, item.Level, item.Brush);
timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds; timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;
entry.End = Server.StartTime.AddTicks(timeDelta * TimeSpan.TicksPerSecond); entry.End = Server.StartTime.AddTicks(timeDelta * TimeSpan.TicksPerSecond);
p.DrawOps.Add(entry); p.DrawOps.Add(entry);
if (p.DrawOps.Count > 200) if (p.DrawOps.Count > 200)
p.DrawOps.RemoveFirst(); p.DrawOps.RemoveFirst();
DoReload(p, item.Level, needReveal); if (item.Affected > Server.DrawReloadLimit)
DoReload(p, item.Level);
} }
} }
static void DoReload(Player p, Level lvl, bool needReveal) { static void DoDrawOp(PendingDrawOp item, Player p) {
if (!needReveal) return; Level lvl = item.Level;
Level.BlockPos bP = default(Level.BlockPos);
if (item.Affected > Server.DrawReloadLimit) {
foreach (var b in item.Op.Perform(item.Marks, p, lvl, item.Brush)) {
if (b.Type == Block.Zero) continue;
byte old = lvl.GetTile(b.X, b.Y, b.Z);
if (old == Block.Zero || !lvl.CheckAffectPermissions(p, b.X, b.Y, b.Z, old, b.Type))
continue;
lvl.SetTile(b.X, b.Y, b.Z, b.Type, p, b.ExtType);
p.loginBlocks++;
p.overallBlocks++;
}
} else if (item.Level.bufferblocks) {
foreach (var b in item.Op.Perform(item.Marks, p, lvl, item.Brush)) {
if (b.Type == Block.Zero) continue;
if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Type, b.ExtType)) continue;
bP.name = p.name;
bP.index = lvl.PosToInt(b.X, b.Y, b.Z);
bP.SetData(b.Type, b.ExtType, b.Type == 0);
if (lvl.UseBlockDB)
lvl.blockCache.Add(bP);
BlockQueue.Addblock(p, bP.index, b.Type, b.ExtType);
}
} else {
foreach (var b in item.Op.Perform(item.Marks, p, item.Level, item.Brush)) {
if (b.Type == Block.Zero) continue;
if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Type, b.ExtType)) continue;
bP.name = p.name;
bP.index = lvl.PosToInt(b.X, b.Y, b.Z);
bP.SetData(b.Type, b.ExtType, b.Type == 0);
if (lvl.UseBlockDB)
lvl.blockCache.Add(bP);
Player.GlobalBlockchange(lvl, b.X, b.Y, b.Z, b.Type, b.ExtType);
}
}
}
static void DoReload(Player p, Level lvl) {
Player[] players = PlayerInfo.Online.Items; Player[] players = PlayerInfo.Online.Items;
foreach (Player pl in players) { foreach (Player pl in players) {
if (pl.level.name.CaselessEq(lvl.name)) if (pl.level.name.CaselessEq(lvl.name))

View File

@ -16,6 +16,7 @@
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System; using System;
using System.Collections.Generic;
using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Brushes;
namespace MCGalaxy { namespace MCGalaxy {
@ -29,6 +30,11 @@ namespace MCGalaxy {
Type = type; ExtType = extType; Type = type; ExtType = extType;
} }
} }
public struct DrawOpBlock {
public ushort X, Y, Z;
public byte Type, ExtType;
}
} }
namespace MCGalaxy.Drawing.Ops { namespace MCGalaxy.Drawing.Ops {
@ -50,7 +56,8 @@ namespace MCGalaxy.Drawing.Ops {
public Vec3S32 Origin; public Vec3S32 Origin;
/// <summary> Coordinates of the current block being processed by the drawing command. </summary> /// <summary> Coordinates of the current block being processed by the drawing command. </summary>
public Vec3U16 Coords; /// <remarks> Note: You should treat this as coordinates, it is a DrawOpBlock struct for performance reasons. </remarks>
public DrawOpBlock Coords;
/// <summary> Level the draw operation is being performed upon. </summary> /// <summary> Level the draw operation is being performed upon. </summary>
public Level Level; public Level Level;
@ -62,7 +69,7 @@ namespace MCGalaxy.Drawing.Ops {
/// Note that this estimate assumes that all possibly affected blocks will be changed by the drawing command. </summary> /// Note that this estimate assumes that all possibly affected blocks will be changed by the drawing command. </summary>
public abstract long GetBlocksAffected(Level lvl, Vec3S32[] marks); public abstract long GetBlocksAffected(Level lvl, Vec3S32[] marks);
public abstract void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush); public abstract IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush);
public virtual bool CanDraw(Vec3S32[] marks, Player p, out long affected) { public virtual bool CanDraw(Vec3S32[] marks, Player p, out long affected) {
affected = GetBlocksAffected(Level, marks); affected = GetBlocksAffected(Level, marks);
@ -74,16 +81,6 @@ namespace MCGalaxy.Drawing.Ops {
return true; return true;
} }
public virtual bool DetermineDrawOpMethod(Level lvl, long affected) {
if (affected > Server.DrawReloadLimit) {
method = M_PSetTile;
return true;
} else {
method = lvl.bufferblocks ? M_PBlockQueue : M_PBlockChange;
return false;
}
}
public virtual void SetMarks(Vec3S32[] marks) { public virtual void SetMarks(Vec3S32[] marks) {
Origin = marks[0]; Min = marks[0]; Max = marks[0]; Origin = marks[0]; Min = marks[0]; Max = marks[0];
for (int i = 1; i < marks.Length; i++) { for (int i = 1; i < marks.Length; i++) {
@ -97,63 +94,21 @@ namespace MCGalaxy.Drawing.Ops {
TotalModified = 0; TotalModified = 0;
} }
protected void PlaceBlock(Player p, Level lvl, ushort x, ushort y, ushort z, Brush brush) { protected DrawOpBlock Place(ushort x, ushort y, ushort z, Brush brush) {
Coords.X = x; Coords.Y = y; Coords.Z = z; Coords.X = x; Coords.Y = y; Coords.Z = z;
byte type = brush.NextBlock(this); Coords.Type = brush.NextBlock(this);
if (type == Block.Zero) return;
PlaceBlock(p, lvl, x, y, z, type, brush.NextExtBlock(this)); if (Coords.Type != Block.Zero)
Coords.ExtType = brush.NextExtBlock(this);
return Coords;
} }
protected void PlaceBlock(Player p, Level lvl, ushort x, ushort y, ushort z, byte type, byte extType) { protected DrawOpBlock Place(ushort x, ushort y, ushort z, byte type, byte extType) {
Level.BlockPos bP = default(Level.BlockPos); Coords.X = x; Coords.Y = y; Coords.Z = z;
switch (method) { Coords.Type = type; Coords.ExtType = extType;
case M_PBlockQueue: return Coords;
if (!lvl.DoBlockchange(p, x, y, z, type, extType)) return;
bP.name = p.name;
bP.index = lvl.PosToInt(x, y, z);
bP.SetData(type, extType, type == 0);
if (lvl.UseBlockDB)
lvl.blockCache.Add(bP);
BlockQueue.Addblock(p, bP.index, type, extType);
TotalModified++;
break;
case M_PBlockChange:
if (!lvl.DoBlockchange(p, x, y, z, type, extType)) return;
bP.name = p.name;
bP.index = lvl.PosToInt(x, y, z);
bP.SetData(type, extType, type == 0);
if (lvl.UseBlockDB)
lvl.blockCache.Add(bP);
Player.GlobalBlockchange(lvl, x, y, z, type, extType);
TotalModified++;
break;
case M_PSetTile:
byte old = lvl.GetTile(x, y, z);
if (old == Block.Zero || !lvl.CheckAffectPermissions(p, x, y, z, old, type))
return;
lvl.SetTile(x, y, z, type, p, extType);
p.loginBlocks++;
p.overallBlocks++;
TotalModified++;
break;
case M_BlockChange:
lvl.Blockchange(x, y, z, type, extType);
TotalModified++;
break;
case M_SetTile:
lvl.SetTile(x, y, z, type);
if (type == Block.custom_block)
lvl.SetExtTile(x, y, z, extType);
TotalModified++;
break;
}
} }
internal const int M_PBlockQueue = 0, M_PBlockChange = 1, M_PSetTile = 2;
internal const int M_BlockChange = 3, M_SetTile = 4;
protected Vec3U16 Clamp(Vec3S32 pos) { protected Vec3U16 Clamp(Vec3S32 pos) {
pos.X = Math.Max(0, Math.Min(pos.X, Level.Width - 1)); pos.X = Math.Max(0, Math.Min(pos.X, Level.Width - 1));
pos.Y = Math.Max(0, Math.Min(pos.Y, Level.Height - 1)); pos.Y = Math.Max(0, Math.Min(pos.Y, Level.Height - 1));

View File

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

View File

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

View File

@ -39,7 +39,7 @@ namespace MCGalaxy.Drawing.Ops {
return lenX * lenZ * 3; return lenX * lenZ * 3;
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
width = Max.X - Min.X; width = Max.X - Min.X;
if (width % 2 != 0) { width++; Min.X--; } if (width % 2 != 0) { width++; Min.X--; }
width -= 2; width -= 2;
@ -48,7 +48,7 @@ namespace MCGalaxy.Drawing.Ops {
length -= 2; length -= 2;
if (width <= 0 || length <= 0) { if (width <= 0 || length <= 0) {
Player.Message(p, "The corners of the maze need to be further apart."); return; Player.Message(p, "The corners of the maze need to be further apart."); yield break;
} }
Player.Message(p, "Generating maze... this could take a while"); Player.Message(p, "Generating maze... this could take a while");
//substract 2 cause we will just make the inner. the outer wall is made seperately //substract 2 cause we will just make the inner. the outer wall is made seperately
@ -89,22 +89,30 @@ namespace MCGalaxy.Drawing.Ops {
for (ushort zz = 0; zz <= length; zz++) for (ushort zz = 0; zz <= length; zz++)
if (wall[xx, zz]) if (wall[xx, zz])
{ {
PlaceBlock(p, lvl, (ushort)(xx + min.X + 1), y, (ushort)(zz + min.Z + 1), Block.staircasefull, 0); yield return Place((ushort)(xx + min.X + 1), y, (ushort)(zz + min.Z + 1), Block.staircasefull, 0);
PlaceBlock(p, lvl, (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 + 1), (ushort)(zz + min.Z + 1), Block.leaf, 0);
PlaceBlock(p, lvl, (ushort)(xx + min.X + 1), (ushort)(y + 2), (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);
} }
brush = new SolidBrush(Block.staircasefull, 0); brush = new SolidBrush(Block.staircasefull, 0);
QuadX(min.X, y, min.Z, y, max.Z, p, lvl, brush); foreach (var block in QuadX(min.X, y, min.Z, y, max.Z, brush))
QuadX(max.X, y, min.Z, y, max.Z, p, lvl, brush); yield return block;
QuadZ(min.Z, y, min.X, y, max.X, p, lvl, brush); foreach (var block in QuadX(max.X, y, min.Z, y, max.Z, brush))
QuadZ(max.Z, y, min.X, y, max.X, p, lvl, 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;
brush = new SolidBrush(Block.leaf, 0); brush = new SolidBrush(Block.leaf, 0);
QuadX(min.X, (ushort)(y + 1), min.Z, (ushort)(y + 2), max.Z, p, lvl, brush); foreach (var block in QuadX(min.X, (ushort)(y + 1), min.Z, (ushort)(y + 2), max.Z, brush))
QuadX(max.X, (ushort)(y + 1), min.Z, (ushort)(y + 2), max.Z, p, lvl, brush); yield return block;
QuadZ(min.Z, (ushort)(y + 1), min.X, (ushort)(y + 2), max.X, p, lvl, brush); foreach (var block in QuadX(max.X, (ushort)(y + 1), min.Z, (ushort)(y + 2), max.Z, brush))
QuadZ(max.Z, (ushort)(y + 1), min.X, (ushort)(y + 2), max.X, p, lvl, 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;
Player.Message(p, "Maze painted. Build the entrance and exit yourself"); Player.Message(p, "Maze painted. Build the entrance and exit yourself");
randomizer = 0; randomizer = 0;

View File

@ -31,7 +31,7 @@ namespace MCGalaxy.Drawing.Ops {
return CopyState.UsedBlocks; return CopyState.UsedBlocks;
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
CopyState state = CopyState; CopyState state = CopyState;
bool pasteAir = state.PasteAir; bool pasteAir = state.PasteAir;
// Adjust for the fact that paste origin may be outside the map. // Adjust for the fact that paste origin may be outside the map.
@ -48,7 +48,7 @@ namespace MCGalaxy.Drawing.Ops {
bool place = lvl.InBound(x, y, z) && (b != type || (b == Block.custom_block && extB != extType)); bool place = lvl.InBound(x, y, z) && (b != type || (b == Block.custom_block && extB != extType));
if ((b != Block.air || pasteAir) && place) if ((b != Block.air || pasteAir) && place)
PlaceBlock(p, lvl, x, y, z, b, extB); yield return Place(x, y, z, b, extB);
} }
} }
} }
@ -64,7 +64,7 @@ namespace MCGalaxy.Drawing.Ops {
return CopyState.UsedBlocks; return CopyState.UsedBlocks;
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(marks[0]); Vec3U16 p1 = Clamp(marks[0]);
CopyState state = CopyState; CopyState state = CopyState;
bool pasteAir = state.PasteAir; bool pasteAir = state.PasteAir;
@ -92,14 +92,14 @@ namespace MCGalaxy.Drawing.Ops {
} }
} }
if (!place) continue; if (!place) continue;
PlaceBlock(p, lvl, x, y, z, b, extB); yield return Place(x, y, z, b, extB);
} }
if (include != null) { if (include != null) {
for (int j = 0; j < include.Length; j++) { for (int j = 0; j < include.Length; j++) {
ExtBlock block = include[j]; ExtBlock block = include[j];
if (b == block.Type && (b != Block.custom_block || extB == block.ExtType)) { if (b == block.Type && (b != Block.custom_block || extB == block.ExtType)) {
PlaceBlock(p, lvl, x, y, z, b, extB); break; yield return Place(x, y, z, b, extB); break;
} }
} }
} }

View File

@ -16,6 +16,7 @@
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System; using System;
using System.Collections.Generic;
using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Brushes;
namespace MCGalaxy.Drawing.Ops { namespace MCGalaxy.Drawing.Ops {
@ -29,10 +30,6 @@ namespace MCGalaxy.Drawing.Ops {
this.yDir = yDir; this.yDir = yDir;
} }
public override bool DetermineDrawOpMethod(Level lvl, long affected) {
return baseOp.DetermineDrawOpMethod(lvl, affected);
}
public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) { public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) {
Vec3S32 oMin = Min, oMax = Max; Vec3S32 oMin = Min, oMax = Max;
baseOp.Min = oMin; baseOp.Max = oMax; baseOp.Min = oMin; baseOp.Max = oMax;
@ -52,14 +49,16 @@ namespace MCGalaxy.Drawing.Ops {
return total; return total;
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3S32 p1 = Min, p2 = Max; Vec3S32 p1 = Min, p2 = Max;
baseOp.Level = Level; baseOp.Level = Level;
while (true) { while (true) {
baseOp.Perform(marks, p, lvl, brush); foreach (var block in baseOp.Perform(marks, p, lvl, brush))
yield return block;
if (p1.Y >= lvl.Height || Math.Abs(p2.X - p1.X) <= 1 || Math.Abs(p2.Z - p1.Z) <= 1) if (p1.Y >= lvl.Height || Math.Abs(p2.X - p1.X) <= 1 || Math.Abs(p2.Z - p1.Z) <= 1)
break; yield break;
p1.X++; p2.X--; p1.X++; p2.X--;
p1.Z++; p2.Z--; p1.Z++; p2.Z--;
p1.Y = (ushort)(p1.Y + yDir); p2.Y = p1.Y; p1.Y = (ushort)(p1.Y + yDir); p2.Y = p1.Y;
@ -95,22 +94,25 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Pyramid reverse"; } } public override string Name { get { return "Pyramid reverse"; } }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
wallOp.Min = Min; wallOp.Max = Max; wallOp.Min = Min; wallOp.Max = Max;
baseOp.Min = Min; baseOp.Max = Max; baseOp.Min = Min; baseOp.Max = Max;
wallOp.Level = Level; baseOp.Level = Level; wallOp.Level = Level; baseOp.Level = Level;
while (true) { while (true) {
wallOp.Perform(marks, p, lvl, brush); foreach (var block in wallOp.Perform(marks, p, lvl, brush))
yield return block;
if (p1.Y >= lvl.Height || Math.Abs(p2.X - p1.X) <= 1 || Math.Abs(p2.Z - p1.Z) <= 1) if (p1.Y >= lvl.Height || Math.Abs(p2.X - p1.X) <= 1 || Math.Abs(p2.Z - p1.Z) <= 1)
break; yield break;
p1.X++; p2.X--; p1.X++; p2.X--;
p1.Z++; p2.Z--; p1.Z++; p2.Z--;
wallOp.Min = p1; wallOp.Max = p2; wallOp.Min = p1; wallOp.Max = p2;
baseOp.Min = p1; baseOp.Max = p2; baseOp.Min = p1; baseOp.Max = p2;
baseOp.Perform(marks, p, lvl, airBrush); foreach (var block in baseOp.Perform(marks, p, lvl, airBrush))
yield return block;
p1.Y = (ushort)(p1.Y + yDir); p2.Y = p1.Y; p1.Y = (ushort)(p1.Y + yDir); p2.Y = p1.Y;
wallOp.Min = p1; wallOp.Max = p2; wallOp.Min = p1; wallOp.Max = p2;
baseOp.Min = p1; baseOp.Max = p2; baseOp.Min = p1; baseOp.Max = p2;

View File

@ -35,10 +35,10 @@ namespace MCGalaxy.Drawing.Ops {
public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) { return -1; } public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
UndoCache cache = p.UndoBuffer; UndoCache cache = p.UndoBuffer;
UndoCacheNode node = cache.Tail; UndoCacheNode node = cache.Tail;
if (node == null) return; if (node == null) yield break;
int timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds; int timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;
while (node != null) { while (node != null) {
@ -56,7 +56,7 @@ namespace MCGalaxy.Drawing.Ops {
DateTime time = node.BaseTime.AddTicks(item.TimeDelta * TimeSpan.TicksPerSecond); DateTime time = node.BaseTime.AddTicks(item.TimeDelta * TimeSpan.TicksPerSecond);
if (time > End) continue; if (time > End) continue;
if (time < Start) { buffer.CheckIfSend(true); return; } if (time < Start) { buffer.CheckIfSend(true); yield break; }
byte tile, extTile; byte tile, extTile;
item.GetBlock(out tile, out extTile); item.GetBlock(out tile, out extTile);
@ -68,6 +68,7 @@ namespace MCGalaxy.Drawing.Ops {
buffer.CheckIfSend(true); buffer.CheckIfSend(true);
node = node.Prev; node = node.Prev;
} }
yield break;
} }
} }
} }

View File

@ -16,6 +16,7 @@
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System; using System;
using System.Collections.Generic;
using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Brushes;
namespace MCGalaxy.Drawing.Ops { namespace MCGalaxy.Drawing.Ops {
@ -34,7 +35,7 @@ namespace MCGalaxy.Drawing.Ops {
return (Max.X - Min.X + 1) * (Max.Y - Min.Y + 1) * (Max.Z - Min.Z + 1); return (Max.X - Min.X + 1) * (Max.Y - Min.Y + 1) * (Max.Z - Min.Z + 1);
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
for (ushort y = p1.Y; y <= p2.Y; y++) for (ushort y = p1.Y; y <= p2.Y; y++)
for (ushort z = p1.Z; z <= p2.Z; z++) for (ushort z = p1.Z; z <= p2.Z; z++)
@ -44,7 +45,7 @@ namespace MCGalaxy.Drawing.Ops {
if (tile == Block.custom_block) extTile = lvl.GetExtTile(x, y, z); if (tile == Block.custom_block) extTile = lvl.GetExtTile(x, y, z);
if (tile == Include.Type && (tile != Block.custom_block || extTile == Include.ExtType)) if (tile == Include.Type && (tile != Block.custom_block || extTile == Include.ExtType))
PlaceBlock(p, lvl, x, y, z, brush); yield return Place(x, y, z, brush);
} }
} }
} }
@ -63,7 +64,7 @@ namespace MCGalaxy.Drawing.Ops {
return (Max.X - Min.X + 1) * (Max.Y - Min.Y + 1) * (Max.Z - Min.Z + 1); return (Max.X - Min.X + 1) * (Max.Y - Min.Y + 1) * (Max.Z - Min.Z + 1);
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max); Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
for (ushort y = p1.Y; y <= p2.Y; y++) for (ushort y = p1.Y; y <= p2.Y; y++)
for (ushort z = p1.Z; z <= p2.Z; z++) for (ushort z = p1.Z; z <= p2.Z; z++)
@ -72,9 +73,8 @@ namespace MCGalaxy.Drawing.Ops {
byte tile = lvl.GetTile(x, y, z), extTile = 0; byte tile = lvl.GetTile(x, y, z), extTile = 0;
if (tile == Block.custom_block) extTile = lvl.GetExtTile(x, y, z); if (tile == Block.custom_block) extTile = lvl.GetExtTile(x, y, z);
if (tile != Exclude.Type || (tile == Block.custom_block && extTile != Exclude.ExtType)) { if (tile != Exclude.Type || (tile == Block.custom_block && extTile != Exclude.ExtType))
PlaceBlock(p, lvl, x, y, z, brush); yield return Place(x, y, z, brush);
}
} }
} }
} }

View File

@ -16,6 +16,7 @@
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System; using System;
using System.Collections.Generic;
using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Brushes;
namespace MCGalaxy.Drawing.Ops { namespace MCGalaxy.Drawing.Ops {
@ -29,7 +30,7 @@ namespace MCGalaxy.Drawing.Ops {
return (int)(Math.PI * 4.0/3.0 * rx * ry * rz); return (int)(Math.PI * 4.0/3.0 * rx * ry * rz);
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
/* Courtesy of fCraft's awesome Open-Source'ness :D */ /* 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 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 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;
@ -42,7 +43,7 @@ namespace MCGalaxy.Drawing.Ops {
{ {
double dx = xx - cx, dy = yy - cy, dz = zz - cz; double dx = xx - cx, dy = yy - cy, dz = zz - cz;
if ((dx * dx) * rx2 + (dy * dy) * ry2 + (dz * dz) * rz2 <= 1) if ((dx * dx) * rx2 + (dy * dy) * ry2 + (dz * dz) * rz2 <= 1)
PlaceBlock(p, lvl, xx, yy, zz, brush); yield return Place(xx, yy, zz, brush);
} }
} }
} }
@ -56,7 +57,7 @@ namespace MCGalaxy.Drawing.Ops {
return (int)(Math.PI * 4.0/3.0 * rx * ry * rz); return (int)(Math.PI * 4.0/3.0 * rx * ry * rz);
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
/* Courtesy of fCraft's awesome Open-Source'ness :D */ /* 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 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 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;
@ -75,7 +76,7 @@ namespace MCGalaxy.Drawing.Ops {
dx *= dx; dy *= dy; dz *= dz; dx *= dx; dy *= dy; dz *= dz;
bool inRange = dx * rx2 + dy * ry2 + dz * rz2 <= 1; bool inRange = dx * rx2 + dy * ry2 + dz * rz2 <= 1;
if (inRange && (dx * smallrx2 + dy * smallry2 + dz * smallrz2 > 1)) if (inRange && (dx * smallrx2 + dy * smallry2 + dz * smallrz2 > 1))
PlaceBlock(p, lvl, xx, yy, zz, brush); yield return Place(xx, yy, zz, brush);
} }
} }
} }
@ -90,7 +91,7 @@ namespace MCGalaxy.Drawing.Ops {
return (int)(Math.PI * rx * rz * height); return (int)(Math.PI * rx * rz * height);
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
/* Courtesy of fCraft's awesome Open-Source'ness :D */ /* 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 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; double rx = (Max.X - Min.X) / 2.0 + 0.25, rz = (Max.Z - Min.Z) / 2.0 + 0.25;
@ -107,7 +108,7 @@ namespace MCGalaxy.Drawing.Ops {
dx *= dx; dz *= dz; dx *= dx; dz *= dz;
bool inRange = dx * rx2 + dz * rz2 <= 1; bool inRange = dx * rx2 + dz * rz2 <= 1;
if (inRange && (dx * smallrx2 + dz * smallrz2 > 1)) if (inRange && (dx * smallrx2 + dz * smallrz2 > 1))
PlaceBlock(p, lvl, xx, yy, zz, brush); yield return Place(xx, yy, zz, brush);
} }
} }
} }

View File

@ -16,6 +16,7 @@
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System; using System;
using System.Collections.Generic;
using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Brushes;
namespace MCGalaxy.Drawing.Ops { namespace MCGalaxy.Drawing.Ops {
@ -30,7 +31,7 @@ namespace MCGalaxy.Drawing.Ops {
return (int)(2 * Math.PI * Math.PI * rTube * rTube * rCentre); return (int)(2 * Math.PI * Math.PI * rTube * rTube * rCentre);
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
double cx = (Min.X + Max.X) / 2.0, cy = (Min.Y + Max.Y) / 2.0, cz = (Min.Z + Max.Z) / 2.0; 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 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; double rTube = ry, rCentre = Math.Min(rx, rz) - rTube;
@ -45,7 +46,7 @@ namespace MCGalaxy.Drawing.Ops {
double dInner = rCentre - Math.Sqrt( dx + dz ); double dInner = rCentre - Math.Sqrt( dx + dz );
if (dInner * dInner + dy <= rTube * rTube * 0.5 + 0.25) if (dInner * dInner + dy <= rTube * rTube * 0.5 + 0.25)
PlaceBlock(p, lvl, xx, yy, zz, brush); yield return Place(xx, yy, zz, brush);
} }
} }
} }

View File

@ -25,6 +25,7 @@ Ideas, concepts, and code were used from the following two sources:
*/ */
using System; using System;
using System.Collections.Generic;
using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Brushes;
namespace MCGalaxy.Drawing.Ops { namespace MCGalaxy.Drawing.Ops {
@ -42,13 +43,15 @@ namespace MCGalaxy.Drawing.Ops {
public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) { return -1; } public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
if (brush == null) brush = defBrush; if (brush == null) brush = defBrush;
Vec3U16 P = Clamp(marks[0]); Vec3U16 P = Clamp(marks[0]);
if (Type == T_Tree) AddTree(p, lvl, P.X, P.Y, P.Z, brush);
if (Type == T_NotchTree) AddNotchTree(p, lvl, P.X, P.Y, P.Z, brush); if (Type == T_Tree) return AddTree(p, lvl, P.X, P.Y, P.Z, brush);
if (Type == T_NotchSwamp) AddNotchSwampTree(p, lvl, P.X, P.Y, P.Z, brush); if (Type == T_NotchTree) return AddNotchTree(p, lvl, P.X, P.Y, P.Z, brush);
if (Type == T_Cactus) AddCactus(p, lvl, P.X, P.Y, P.Z); if (Type == T_NotchSwamp) return AddNotchSwampTree(p, lvl, P.X, P.Y, P.Z, brush);
if (Type == T_Cactus) return AddCactus(p, lvl, P.X, P.Y, P.Z);
return null;
} }
public override void SetMarks(Vec3S32[] marks) { public override void SetMarks(Vec3S32[] marks) {
@ -77,11 +80,11 @@ namespace MCGalaxy.Drawing.Ops {
Max.X += size; Max.Z += size; Max.X += size; Max.Z += size;
} }
void AddTree(Player p, Level lvl, ushort x, ushort y, ushort z, Brush brush) { IEnumerable<DrawOpBlock> AddTree(Player p, Level lvl, ushort x, ushort y, ushort z, Brush brush) {
for (ushort dy = 0; dy < top + height - 1; dy++) { for (ushort dy = 0; dy < top + height - 1; dy++) {
ushort yy = (ushort)(y + dy); ushort yy = (ushort)(y + dy);
if (overwrite || lvl.GetTile(x, yy, z) == Block.air || (yy == y && lvl.GetTile(x, yy, z) == Block.shrub)) if (overwrite || lvl.GetTile(x, yy, z) == Block.air || (yy == y && lvl.GetTile(x, yy, z) == Block.shrub))
PlaceBlock(p, lvl, x, yy, z, Block.trunk, 0); yield return Place(x, yy, z, Block.trunk, 0);
} }
for (short dy = (short)-top; dy <= top; ++dy) for (short dy = (short)-top; dy <= top; ++dy)
@ -93,17 +96,17 @@ namespace MCGalaxy.Drawing.Ops {
ushort xx = (ushort)(x + dx), yy = (ushort)(y + dy + height), zz = (ushort)(z + dz); 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)) if ((xx != x || zz != z || dy >= top - 1) && (overwrite || lvl.GetTile(xx, yy, zz) == Block.air))
PlaceBlock(p, lvl, xx, yy, zz, brush); yield return Place(xx, yy, zz, brush);
} }
} }
} }
void AddNotchTree(Player p, Level lvl, ushort x, ushort y, ushort z, Brush brush) { IEnumerable<DrawOpBlock> AddNotchTree(Player p, Level lvl, ushort x, ushort y, ushort z, Brush brush) {
for (int dy = 0; dy <= height; dy++) { for (int dy = 0; dy <= height; dy++) {
ushort yy = (ushort)(y + dy); ushort yy = (ushort)(y + dy);
byte tile = lvl.GetTile(x, yy, z); byte tile = lvl.GetTile(x, yy, z);
if (overwrite || tile == Block.air || (yy == y && tile == Block.shrub)) if (overwrite || tile == Block.air || (yy == y && tile == Block.shrub))
PlaceBlock(p, lvl, x, yy, z, Block.trunk, 0); yield return Place(x, yy, z, Block.trunk, 0);
} }
for (int dy = top; dy <= height + 1; dy++) { for (int dy = top; dy <= height + 1; dy++) {
@ -120,20 +123,20 @@ namespace MCGalaxy.Drawing.Ops {
if (dy > height) continue; if (dy > height) continue;
if (random.Next(2) == 0) if (random.Next(2) == 0)
PlaceBlock(p, lvl, xx, yy, zz, brush); yield return Place(xx, yy, zz, brush);
} else { } else {
PlaceBlock(p, lvl, xx, yy, zz, brush); yield return Place(xx, yy, zz, brush);
} }
} }
} }
} }
void AddNotchSwampTree(Player p, Level lvl, ushort x, ushort y, ushort z, Brush brush) { IEnumerable<DrawOpBlock> AddNotchSwampTree(Player p, Level lvl, ushort x, ushort y, ushort z, Brush brush) {
for (int dy = 0; dy <= height; dy++) { for (int dy = 0; dy <= height; dy++) {
ushort yy = (ushort)(y + dy); ushort yy = (ushort)(y + dy);
byte tile = lvl.GetTile(x, yy, z); byte tile = lvl.GetTile(x, yy, z);
if (overwrite || tile == Block.air || (yy == y && tile == Block.shrub)) if (overwrite || tile == Block.air || (yy == y && tile == Block.shrub))
PlaceBlock(p, lvl, x, yy, z, Block.trunk, 0); yield return Place(x, yy, z, Block.trunk, 0);
} }
for (int dy = top; dy <= height + 1; dy++) { for (int dy = top; dy <= height + 1; dy++) {
@ -150,18 +153,18 @@ namespace MCGalaxy.Drawing.Ops {
if (dy > height) continue; if (dy > height) continue;
if (random.Next(2) == 0) if (random.Next(2) == 0)
PlaceBlock(p, lvl, xx, yy, zz, brush); yield return Place(xx, yy, zz, brush);
} else { } else {
PlaceBlock(p, lvl, xx, yy, zz, brush); yield return Place(xx, yy, zz, brush);
} }
} }
} }
} }
void AddCactus(Player p, Level lvl, ushort x, ushort y, ushort z) { IEnumerable<DrawOpBlock> AddCactus(Player p, Level lvl, ushort x, ushort y, ushort z) {
for (ushort dy = 0; dy <= height; dy++) { for (ushort dy = 0; dy <= height; dy++) {
if (overwrite || lvl.GetTile(z, (ushort)(y + dy), z) == Block.air) if (overwrite || lvl.GetTile(z, (ushort)(y + dy), z) == Block.air)
PlaceBlock(p, lvl, x, (ushort)(y + dy), z, Block.green, 0); yield return Place(x, (ushort)(y + dy), z, Block.green, 0);
} }
int inX = 0, inZ = 0; int inX = 0, inZ = 0;
@ -173,11 +176,11 @@ namespace MCGalaxy.Drawing.Ops {
for (ushort dy = height; dy <= random.Next(height + 2, height + 5); dy++) { 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) if (overwrite || lvl.GetTile((ushort)(x + inX), (ushort)(y + dy), (ushort)(z + inZ)) == Block.air)
PlaceBlock(p, lvl, (ushort)(x + inX), (ushort)(y + dy), (ushort)(z + inZ), Block.green, 0); yield return 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++) { 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) if (overwrite || lvl.GetTile((ushort)(x - inX), (ushort)(y + dy), (ushort)(z - inZ)) == Block.air)
PlaceBlock(p, lvl, (ushort)(x - inX), (ushort)(y + dy), (ushort)(z - inZ), Block.green, 0); yield return Place((ushort)(x - inX), (ushort)(y + dy), (ushort)(z - inZ), Block.green, 0);
} }
} }

View File

@ -16,6 +16,7 @@
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System; using System;
using System.Collections.Generic;
using MCGalaxy.Drawing.Brushes; using MCGalaxy.Drawing.Brushes;
namespace MCGalaxy.Drawing.Ops { namespace MCGalaxy.Drawing.Ops {
@ -33,7 +34,7 @@ namespace MCGalaxy.Drawing.Ops {
return (int)Math.Sqrt(s * (s - a) * (s - b) * (s - c)); return (int)Math.Sqrt(s * (s - a) * (s - b) * (s - c));
} }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3F32 V1 = marks[0], V2 = marks[1], V3 = marks[2]; Vec3F32 V1 = marks[0], V2 = marks[1], V3 = marks[2];
Vec3F32 N = Vec3F32.Cross(V2 - V1, V3 - V1); Vec3F32 N = Vec3F32.Cross(V2 - V1, V3 - V1);
N = Vec3F32.Normalise(N); N = Vec3F32.Normalise(N);
@ -64,9 +65,9 @@ namespace MCGalaxy.Drawing.Ops {
float v = (dot00 * dot12 - dot01 * dot02) * invDenom; float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
if (u >= 0 && v >= 0 && u + v <= 1) { if (u >= 0 && v >= 0 && u + v <= 1) {
PlaceBlock(p, lvl, xx, yy, zz, brush); yield return Place(xx, yy, zz, brush);
} else if (Axis(P, V1, V2) || Axis(P, V1, V3) || Axis(P, V2, V3)) { } else if (Axis(P, V1, V2) || Axis(P, V1, V3) || Axis(P, V2, V3)) {
PlaceBlock(p, lvl, xx, yy, zz, brush); yield return Place(xx, yy, zz, brush);
} }
} }
} }

View File

@ -42,11 +42,12 @@ namespace MCGalaxy.Drawing.Ops {
public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) { return -1; } public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
PerformUndo(p, ref saveLevel); PerformUndo(p, ref saveLevel);
bool foundUser = false; bool foundUser = false;
Vec3S32[] bounds = { Min, Max }; Vec3S32[] bounds = { Min, Max };
UndoFile.UndoPlayer(p, who.name.ToLower(), bounds, Start, ref foundUser); UndoFile.UndoPlayer(p, who.name.ToLower(), bounds, Start, ref foundUser);
yield break;
} }
void PerformUndo(Player p, ref Level saveLvl) { void PerformUndo(Player p, ref Level saveLvl) {
@ -106,9 +107,10 @@ namespace MCGalaxy.Drawing.Ops {
public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) { return -1; } public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3S32[] bounds = { Min, Max }; Vec3S32[] bounds = { Min, Max };
UndoFile.UndoPlayer(p, whoName.ToLower(), bounds, Start, ref foundUser); UndoFile.UndoPlayer(p, whoName.ToLower(), bounds, Start, ref foundUser);
yield break;
} }
} }
@ -120,7 +122,7 @@ namespace MCGalaxy.Drawing.Ops {
public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) { return -1; } public override long GetBlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
if (lvl.UndoBuffer.Count != Server.physUndo) { if (lvl.UndoBuffer.Count != Server.physUndo) {
int count = lvl.currentUndo; int count = lvl.currentUndo;
for (int i = count; i >= 0; i--) { for (int i = count; i >= 0; i--) {
@ -141,6 +143,7 @@ namespace MCGalaxy.Drawing.Ops {
} catch { } } catch { }
} }
} }
yield break;
} }
bool CheckBlockPhysics(Player p, Level lvl, long seconds, int i) { bool CheckBlockPhysics(Player p, Level lvl, long seconds, int i) {

View File

@ -43,21 +43,26 @@ namespace MCGalaxy.Drawing.Ops {
} }
int dirX, dirZ; int dirX, dirZ;
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) { Vec3U16 pos;
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush) {
Vec3U16 p1 = Clamp(marks[0]), p2 = Clamp(marks[1]); Vec3U16 p1 = Clamp(marks[0]), p2 = Clamp(marks[1]);
if (Math.Abs(p2.X - p1.X) > Math.Abs(p2.Z - p1.Z)) if (Math.Abs(p2.X - p1.X) > Math.Abs(p2.Z - p1.Z))
dirX = p2.X > p1.X? 1 : -1; dirX = p2.X > p1.X? 1 : -1;
else else
dirZ = p2.Z > p1.Z ? 1 : -1; dirZ = p2.Z > p1.Z ? 1 : -1;
foreach (char c in Text) pos = p1;
DrawLetter(p, lvl, c, ref p1.X, p1.Y, ref p1.Z, brush);
foreach (char c in Text) {
foreach (var block in DrawLetter(p, lvl, c, brush))
yield return block;
}
} }
void DrawLetter(Player p, Level lvl, char c, ref ushort x, ushort y, ref ushort z, Brush brush) { IEnumerable<DrawOpBlock> DrawLetter(Player p, Level lvl, char c, Brush brush) {
if ((int)c >= 256 || letters[(int)c] == null) { if ((int)c >= 256 || letters[(int)c] == null) {
Player.Message(p, "\"" + c + "\" is not currently supported, replacing with space."); Player.Message(p, "\"" + c + "\" is not currently supported, replacing with space.");
x = (ushort)(x + dirX * 4 * Scale); pos.X = (ushort)(pos.X + dirX * 4 * Scale);
z = (ushort)(z + dirZ * 4 * Scale); pos.Z = (ushort)(pos.Z + dirZ * 4 * Scale);
} else { } else {
byte[] flags = letters[(int)c]; byte[] flags = letters[(int)c];
for (int i = 0; i < flags.Length; i++) { for (int i = 0; i < flags.Length; i++) {
@ -68,16 +73,16 @@ namespace MCGalaxy.Drawing.Ops {
for (int ver = 0; ver < Scale; ver++) for (int ver = 0; ver < Scale; ver++)
for (int hor = 0; hor < Scale; hor++) for (int hor = 0; hor < Scale; hor++)
{ {
int xx = x + dirX * hor, yy = y + j * Scale + ver, zz = z + dirZ * hor; int x = pos.X + dirX * hor, y = pos.Y + j * Scale + ver, z = pos.Z + dirZ * hor;
PlaceBlock(p, lvl, (ushort)xx, (ushort)yy, (ushort)zz, brush); yield return Place((ushort)x, (ushort)y, (ushort)z, brush);
} }
} }
x = (ushort)(x + dirX * Scale); pos.X = (ushort)(pos.X + dirX * Scale);
z = (ushort)(z + dirZ * Scale); pos.Z = (ushort)(pos.Z + dirZ * Scale);
} }
} }
x = (ushort)(x + dirX * Spacing); pos.X = (ushort)(pos.X + dirX * Spacing);
z = (ushort)(z + dirZ * Spacing); pos.Z = (ushort)(pos.Z + dirZ * Spacing);
} }
static int HighestBit(int value) { static int HighestBit(int value) {

View File

@ -52,7 +52,6 @@ namespace MCGalaxy {
treeDrawer = new TreeDrawOp(); treeDrawer = new TreeDrawOp();
treeDrawer.Level = Lvl; treeDrawer.Level = Lvl;
treeDrawer.random = rand; treeDrawer.random = rand;
treeDrawer.method = DrawOp.M_SetTile;
treeCoords = new Vec3S32[1]; treeCoords = new Vec3S32[1];
} }
@ -149,7 +148,9 @@ namespace MCGalaxy {
treeDrawer.Type = genParams.UseCactus ? TreeDrawOp.T_Cactus : TreeDrawOp.T_Tree; treeDrawer.Type = genParams.UseCactus ? TreeDrawOp.T_Cactus : TreeDrawOp.T_Tree;
treeCoords[0].X = x; treeCoords[0].Y = (ushort)(y + 1); treeCoords[0].Z = z; treeCoords[0].X = x; treeCoords[0].Y = (ushort)(y + 1); treeCoords[0].Z = z;
treeDrawer.SetMarks(treeCoords); treeDrawer.SetMarks(treeCoords);
treeDrawer.Perform(treeCoords, null, Lvl, null);
foreach (var block in treeDrawer.Perform(treeCoords, null, Lvl, null))
Lvl.SetTile(block.X, block.Y, block.Z, block.Type);
} }
} }
} }

View File

@ -153,7 +153,7 @@ namespace MCGalaxy {
for (int i = 0; i < ListCheck.Count; i++) { for (int i = 0; i < ListCheck.Count; i++) {
Check C = ListCheck.Items[i]; Check C = ListCheck.Items[i];
IntToPos(C.b, out x, out y, out z); IntToPos(C.b, out x, out y, out z);
try { //try {
if (PhysicsUpdate != null) if (PhysicsUpdate != null)
PhysicsUpdate(x, y, z, C.data, this); PhysicsUpdate(x, y, z, C.data, this);
if (OnPhysicsUpdateEvent.events.Count > 0) if (OnPhysicsUpdateEvent.events.Count > 0)
@ -167,10 +167,10 @@ namespace MCGalaxy {
C.data.Data = 255; C.data.Data = 255;
} }
ListCheck.Items[i] = C; ListCheck.Items[i] = C;
} catch { //} catch {
listCheckExists.Set(x, y, z, false); // listCheckExists.Set(x, y, z, false);
ListCheck.RemoveAt(i); // ListCheck.RemoveAt(i);
} // }
} }
} }
RemoveExpiredChecks(); RemoveExpiredChecks();
@ -181,14 +181,14 @@ namespace MCGalaxy {
for (int i = 0; i < ListUpdate.Count; i++) { for (int i = 0; i < ListUpdate.Count; i++) {
Update C = ListUpdate.Items[i]; Update C = ListUpdate.Items[i];
try { //try {
byte type = C.data.Data; byte type = C.data.Data;
C.data.Data = 0; C.data.Data = 0;
if (DoPhysicsBlockchange(C.b, type, false, C.data, 0, true)) if (DoPhysicsBlockchange(C.b, type, false, C.data, 0, true))
bulkSender.Add(C.b, type, 0); bulkSender.Add(C.b, type, 0);
} catch { //} catch {
Server.s.Log("Phys update issue"); // Server.s.Log("Phys update issue");
} // }
bulkSender.CheckIfSend(false); bulkSender.CheckIfSend(false);
} }
if (bulkSender != null) if (bulkSender != null)

View File

@ -122,10 +122,10 @@ namespace MCGalaxy.BlockPhysics {
TreeDrawOp op = new TreeDrawOp(); TreeDrawOp op = new TreeDrawOp();
op.random = rand; op.random = rand;
op.method = DrawOp.M_BlockChange;
Vec3S32[] marks = new [] { new Vec3S32(x, y, z) }; Vec3S32[] marks = new [] { new Vec3S32(x, y, z) };
op.SetMarks(marks); op.SetMarks(marks);
op.Perform(marks, null, lvl, null); foreach (var block in op.Perform(marks, null, lvl, null))
lvl.Blockchange(block.X, block.Y, block.Z, 0);
C.data.Data = 255; C.data.Data = 255;
} }

View File

@ -476,7 +476,6 @@
<Compile Include="Games\ZombieSurvival\ZombieGame.Game.cs" /> <Compile Include="Games\ZombieSurvival\ZombieGame.Game.cs" />
<Compile Include="Games\ZombieSurvival\ZombieGame.Props.cs" /> <Compile Include="Games\ZombieSurvival\ZombieGame.Props.cs" />
<Compile Include="Generator\ImprovedNoise.cs" /> <Compile Include="Generator\ImprovedNoise.cs" />
<Compile Include="Levels\BufferedBlockSender.cs" />
<Compile Include="Generator\MapGen.cs" /> <Compile Include="Generator\MapGen.cs" />
<Compile Include="Generator\NoiseGen.cs" /> <Compile Include="Generator\NoiseGen.cs" />
<Compile Include="Generator\MapGenParams.cs" /> <Compile Include="Generator\MapGenParams.cs" />
@ -579,6 +578,7 @@
<Compile Include="Server\Server.Threads.cs" /> <Compile Include="Server\Server.Threads.cs" />
<Compile Include="Server\Updater.cs" /> <Compile Include="Server\Updater.cs" />
<Compile Include="API\WebServer.cs" /> <Compile Include="API\WebServer.cs" />
<Compile Include="util\BufferedBlockSender.cs" />
<Compile Include="util\FastList.cs" /> <Compile Include="util\FastList.cs" />
<Compile Include="util\App.cs" /> <Compile Include="util\App.cs" />
<Compile Include="util\LineWrapper.cs" /> <Compile Include="util\LineWrapper.cs" />