Refactor drawing operations, in preparation for TriangleDrawOp.

This commit is contained in:
UnknownShadow200 2016-03-21 21:03:13 +11:00
parent 10acb965a0
commit 1112e4aa36
14 changed files with 205 additions and 176 deletions

View File

@ -18,6 +18,7 @@
using System;
using System.Collections;
using System.Security.Cryptography;
using MCGalaxy.Drawing;
using MCGalaxy.Drawing.Brushes;
using MCGalaxy.Drawing.Ops;
@ -128,18 +129,21 @@ namespace MCGalaxy.Commands
CuboidWallsDrawOp drawOp = new CuboidWallsDrawOp();
drawOp.method = DrawOp.MethodBlockChange;
SolidBrush brush = new SolidBrush(Block.staircasefull, 0);
drawOp.Perform(minX, y, minZ, maxX, y, maxZ, p, p.level, brush);
SolidBrush brush = new SolidBrush(Block.staircasefull, 0);
Vector3U16[] marks = { new Vector3U16(minX, y, minZ), new Vector3U16(maxX, y, maxZ) };
drawOp.Perform(marks, p, p.level, brush);
brush = new SolidBrush(Block.leaf, 0);
drawOp.Perform(minX, (ushort)(y + 1), minZ, maxX, (ushort)(y + 2), maxZ, p, p.level, brush);
marks[0].Y = (ushort)(y + 1); marks[1].Y = (ushort)(y + 2);
drawOp.Perform(marks, p, p.level, brush);
Player.SendMessage(p, "Maze painted. Build your entrance and exit yourself");
randomizer = 0;
}
public override void Help(Player p)
{
public override void Help(Player p) {
Player.SendMessage(p, "/maze: generates a maze");
}
private class CatchPos
{
public ushort X;

View File

@ -24,15 +24,16 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Cuboid"; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
return (x2 - x1 + 1) * (y2 - y1 + 1) * (z2 - z1 + 1);
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
Vector3U16 p1 = marks[0], p2 = marks[1];
return (p2.X - p1.X + 1) * (p2.Y - p1.Y + 1) * (p2.Z - p1.Z + 1);
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
for (ushort y = y1; y <= y2; y++)
for (ushort z = z1; z <= z2; z++)
for (ushort x = x1; x <= x2; x++)
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[1];
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++)
{
PlaceBlock(p, lvl, x, y, z, brush);
}
@ -43,28 +44,29 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Cuboid Hollow"; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
int lenX = (x2 - x1 + 1), lenY = (y2 - y1 + 1), lenZ = (z2 - z2 + 1);
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
Vector3U16 p1 = marks[0], p2 = marks[1];
int lenX = (p2.X - p1.X + 1), lenY = (p2.Y - p1.Y + 1), lenZ = (p2.Z - p1.Z + 1);
int xQuadsVol = Math.Min(lenX, 2) * (lenY * lenZ);
int yQuadsVol = Math.Max(0, Math.Min(lenY, 2) * ((lenX - 2) * lenZ)); // we need to avoid double counting overlaps
int zQuadzVol = Math.Max(0, Math.Min(lenZ, 2) * ((lenX - 2) * (lenY - 2)));
return xQuadsVol + yQuadsVol + zQuadzVol;
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
int lenX = (x2 - x1 + 1), lenY = (y2 - y1 + 1);
QuadY(y1, x1, z1, x2, z2, p, lvl, brush);
QuadY(y2, x1, z1, x2, z2, p, lvl, brush);
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[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);
QuadY(p2.Y, p1.X, p1.Z, p2.X, p2.Z, p, lvl, brush);
if (lenY > 2) {
QuadX(x1, (ushort)(y1 + 1), z1, (ushort)(y2 - 1), z2, p, lvl, brush);
QuadX(x2, (ushort)(y1 + 1), z1, (ushort)(y2 - 1), z2, p, lvl, brush);
QuadX(p1.X, (ushort)(p1.Y + 1), p1.Z, (ushort)(p2.Y - 1), p2.Z, p, lvl, brush);
QuadX(p2.X, (ushort)(p1.Y + 1), p1.Z, (ushort)(p2.Y - 1), p2.Z, p, lvl, brush);
}
if (lenX > 2 && lenY > 2) {
QuadZ(z1, (ushort)(x1 + 1), (ushort)(y1 + 1),
(ushort)(x2 - 1), (ushort)(y2 - 1), p, lvl, brush);
QuadZ(z2, (ushort)(x1 + 1), (ushort)(y1 + 1),
(ushort)(x2 - 1), (ushort)(y2 - 1), p, lvl, brush);
QuadZ(p1.Z, (ushort)(p1.X + 1), (ushort)(p1.Y + 1),
(ushort)(p2.X - 1), (ushort)(p2.Y - 1), p, lvl, brush);
QuadZ(p2.Z, (ushort)(p1.X + 1), (ushort)(p1.Y + 1),
(ushort)(p2.X - 1), (ushort)(p2.Y - 1), p, lvl, brush);
}
}
@ -100,21 +102,22 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Cuboid Walls"; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
int lenX = (x2 - x1 + 1), lenY = (y2 - y1 + 1), lenZ = (z2 - z2 + 1);
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
Vector3U16 p1 = marks[0], p2 = marks[1];
int lenX = (p2.X - p1.X + 1), lenY = (p2.Y - p1.Y + 1), lenZ = (p2.Z - p1.Z + 1);
int xQuadsVol = Math.Min(lenX, 2) * (lenY * lenZ);
int zQuadsVol = Math.Max(0, Math.Min(lenZ, 2) * ((lenX - 2) * lenY)); // we need to avoid double counting overlaps
return xQuadsVol + zQuadsVol;
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
int lenX = (x2 - x1 + 1);
QuadX(x1, y1, z1, y2, z2, p, lvl, brush);
QuadX(x2, y1, z1, y2, z2, p, lvl, brush);
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[1];
int lenX = (p2.X - p1.X + 1);
QuadX(p1.X, p1.Y, p1.Z, p2.Y, p2.Z, p, lvl, brush);
QuadX(p2.X, p1.Y, p1.Z, p2.Y, p2.Z, p, lvl, brush);
if (lenX > 2) {
QuadZ(z1, (ushort)(x1 + 1), y1, (ushort)(x2 - 1), y2, p, lvl, brush);
QuadZ(z2, (ushort)(x1 + 1), y1, (ushort)(x2 - 1), y2, p, lvl, brush);
QuadZ(p1.Z, (ushort)(p1.X + 1), p1.Y, (ushort)(p2.X - 1), p2.Y, p, lvl, brush);
QuadZ(p2.Z, (ushort)(p1.X + 1), p1.Y, (ushort)(p2.X - 1), p2.Y, p, lvl, brush);
}
}
}
@ -123,34 +126,35 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Cuboid Wireframe"; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
int lenX = (x2 - x1 + 1), lenY = (y2 - y1 + 1), lenZ = (z2 - z2 + 1);
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
Vector3U16 p1 = marks[0], p2 = marks[1];
int lenX = (p2.X - p1.X + 1), lenY = (p2.Y - p1.Y + 1), lenZ = (p2.Z - p1.Z + 1);
int horSidesvol = 2 * (lenX * 2 + lenZ * 2); // TODO: slightly overestimated by at most four blocks.
int verSidesVol = Math.Max(0, lenY - 2) * 4;
return horSidesvol + verSidesVol;
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
for (ushort y = y1; y <= y2; y++ ) {
PlaceBlock(p, lvl, x1, y, z1, brush);
PlaceBlock(p, lvl, x2, y, z1, brush);
PlaceBlock(p, lvl, x1, y, z2, brush);
PlaceBlock(p, lvl, x2, y, z2, brush);
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[1];
for (ushort y = p1.Y; y <= p2.Y; y++ ) {
PlaceBlock(p, lvl, p1.X, y, p1.Z, brush);
PlaceBlock(p, lvl, p2.X, y, p1.Z, brush);
PlaceBlock(p, lvl, p1.X, y, p2.Z, brush);
PlaceBlock(p, lvl, p2.X, y, p2.Z, brush);
}
for (ushort z = z1; z <= z2; z++) {
PlaceBlock(p, lvl, x1, y1, z, brush);
PlaceBlock(p, lvl, x2, y1, z, brush);
PlaceBlock(p, lvl, x1, y2, z, brush);
PlaceBlock(p, lvl, x2, y2, z, brush);
for (ushort z = p1.Z; z <= p2.Z; z++) {
PlaceBlock(p, lvl, p1.X, p1.Y, z, brush);
PlaceBlock(p, lvl, p2.X, p1.Y, z, brush);
PlaceBlock(p, lvl, p1.X, p2.Y, z, brush);
PlaceBlock(p, lvl, p2.X, p2.Y, z, brush);
}
for (ushort x = x1; x <= x2; x++) {
PlaceBlock(p, lvl, x, y1, z1, brush);
PlaceBlock(p, lvl, x, y1, z2, brush);
PlaceBlock(p, lvl, x, y2, z1, brush);
PlaceBlock(p, lvl, x, y2, z2, brush);
for (ushort x = p1.X; x <= p2.X; x++) {
PlaceBlock(p, lvl, x, p1.Y, p1.Z, brush);
PlaceBlock(p, lvl, x, p1.Y, p2.Z, brush);
PlaceBlock(p, lvl, x, p2.Y, p1.Z, brush);
PlaceBlock(p, lvl, x, p2.Y, p2.Z, brush);
}
}
}

View File

@ -65,14 +65,12 @@ namespace MCGalaxy.Drawing.Ops {
/// <summary> Estimates the total number of blocks that the drawing commands affects. <br/>
/// Note that this estimate assumes that all possibly affected blocks will be changed by the drawing command. </summary>
public abstract int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2);
public abstract int GetBlocksAffected(Level lvl, Vector3U16[] marks);
public abstract void Perform(ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2,
Player p, Level lvl, Brush brush);
public abstract void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush);
public bool CanDraw(ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2,
Player p, out int affected) {
affected = GetBlocksAffected(p.level, x1, y1, z1, x2, y2, z2);
public bool CanDraw(Vector3U16[] marks, Player p, out int affected) {
affected = GetBlocksAffected(p.level, marks);
if (affected > p.group.maxBlocks) {
Player.SendMessage(p, "You tried to draw " + affected + " blocks.");
Player.SendMessage(p, "You cannot draw more than " + p.group.maxBlocks + ".");
@ -129,19 +127,26 @@ namespace MCGalaxy.Drawing.Ops {
public static bool DoDrawOp(DrawOp op, Brush brush, Player p,
ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
int affected = 0;
op.Origin = new Vector3U16(x1, y1, z1);
op.Min = Vector3U16.Min(x1, y1, z1, x2, y2, z2);
op.Max = Vector3U16.Max(x1, y1, z1, x2, y2, z2);
op.Level = p.level;
if (op.MinMaxCoords) {
ushort xx1 = x1, yy1 = y1, zz1 = z1, xx2 = x2, yy2 = y2, zz2 = z2;
x1 = Math.Min(xx1, xx2); x2 = Math.Max(xx1, xx2);
y1 = Math.Min(yy1, yy2); y2 = Math.Max(yy1, yy2);
z1 = Math.Min(zz1, zz2); z2 = Math.Max(zz1, zz2);
}
Vector3U16[] marks = new [] { new Vector3U16(x1, y1, z1), new Vector3U16(x2, y2, z2) };
return DoDrawOp(op, brush, p, marks);
}
public static bool DoDrawOp(DrawOp op, Brush brush, Player p, Vector3U16[] marks) {
op.Origin = marks[0]; op.Min = marks[0]; op.Max = marks[0];
for (int i = 1; i < marks.Length; i++) {
op.Min = Vector3U16.Min(op.Min, marks[i]);
op.Max = Vector3U16.Max(op.Max, marks[i]);
}
op.Level = p.level;
if (!op.CanDraw(x1, y1, z1, x2, y2, z2, p, out affected))
int affected = 0;
if (!op.CanDraw(marks, p, out affected))
return false;
if (brush != null) {
const string format = "{0}({1}): affecting up to {2} blocks";
@ -152,7 +157,7 @@ namespace MCGalaxy.Drawing.Ops {
}
bool needReveal = op.DetermineDrawOpMethod(p.level, affected);
op.Perform(x1, y1, z1, x2, y2, z2, p, p.level, brush);
op.Perform(marks, p, p.level, brush);
Player[] players = PlayerInfo.Online.Items;
if (needReveal) {
foreach (Player pl in players) {

View File

@ -27,12 +27,11 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Fill"; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
return Positions.Count;
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
ushort x, y, z;
foreach (int pos in Positions) {
lvl.IntToPos(pos, out x, out y, out z);

View File

@ -30,30 +30,31 @@ namespace MCGalaxy.Drawing.Ops {
public override bool MinMaxCoords { get { return false; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
double dx = Math.Abs(x2 - x1) + 0.25, dy = Math.Abs(y2 - y1) + 0.25, dz = Math.Abs(z2 - z1) + 0.25;
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
Vector3U16 p1 = marks[0], p2 = marks[1];
double dx = Math.Abs(p2.X - p1.X) + 0.25, dy = Math.Abs(p2.Y - p1.Y) + 0.25, dz = Math.Abs(p2.Z - p1.Z) + 0.25;
if (WallsMode) {
int baseLen = (int)Math.Ceiling(Math.Sqrt(dx * dx + dz * dz));
return Math.Min(baseLen, MaxLength) * (Math.Abs(y2 - y1) + 1);
return Math.Min(baseLen, MaxLength) * (Math.Abs(p2.Y - p1.Y) + 1);
} else {
int baseLen = (int)Math.Ceiling(Math.Sqrt(dx * dx + dy * dy + dz * dz));
return Math.Min(baseLen, MaxLength);
}
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[1];
List<FillPos> buffer = new List<FillPos>();
DrawLine(x1, y1, z1, MaxLength, x2, y2, z2, buffer);
DrawLine(p1.X, p1.Y, p1.Z, MaxLength, p2.X, p2.Y, p2.Z, buffer);
if (WallsMode) {
ushort yy1 = y1, yy2 = y2;
y1 = Math.Min(yy1, yy2); y2 = Math.Max(yy1, yy2);
ushort yy1 = p1.Y, yy2 = p2.Y;
p1.Y = Math.Min(yy1, yy2); p2.Y = Math.Max(yy1, yy2);
}
for (int i = 0; i < buffer.Count; i++) {
FillPos pos = buffer[i];
if (WallsMode) {
for (ushort yy = y1; yy <= y2; yy++)
for (ushort yy = p1.Y; yy <= p2.Y; yy++)
PlaceBlock(p, lvl, pos.X, yy, pos.Z, brush);
} else {
PlaceBlock(p, lvl, pos.X, pos.Y, pos.Z, brush);

View File

@ -29,16 +29,16 @@ namespace MCGalaxy.Drawing.Ops {
public override bool MinMaxCoords { get { return false; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
return CopyState.Volume;
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0];
CopyState state = CopyState;
bool pasteAir = state.PasteAir;
// Adjust for the fact that paste origin may be outside the map.
short offX = (short)x1, offY = (short)y1, offZ = (short)z1;
short offX = (short)p1.X, offY = (short)p1.Y, offZ = (short)p1.Z;
for (int i = 0; i < state.Blocks.Length; i++ ) {
ushort locX, locY, locZ;
@ -65,17 +65,17 @@ namespace MCGalaxy.Drawing.Ops {
public override bool MinMaxCoords { get { return false; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
return CopyState.Volume;
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0];
CopyState state = CopyState;
bool pasteAir = state.PasteAir;
ExtBlock[] include = Include, exclude = Exclude;
// Adjust for the fact that paste origin may be outside the map.
short offX = (short)x1, offY = (short)y1, offZ = (short)z1;
short offX = (short)p1.X, offY = (short)p1.Y, offZ = (short)p1.Z;
for (int i = 0; i < state.Blocks.Length; i++ ) {
ushort locX, locY, locZ;

View File

@ -33,35 +33,40 @@ namespace MCGalaxy.Drawing.Ops {
return baseOp.DetermineDrawOpMethod(lvl, affected);
}
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
Vector3U16 origP1 = marks[0], origP2 = marks[1];
Vector3U16 p1 = marks[0], p2 = marks[1];
int total = 0;
while (true) {
total += baseOp.GetBlocksAffected(lvl, x1, y1, z2, x2, y1, z2);
if (y1 >= lvl.Height || Math.Abs(x2 - x1) <= 1 || Math.Abs(z2 - z1) <= 1)
total += baseOp.GetBlocksAffected(lvl, marks);
if (p1.Y >= lvl.Height || Math.Abs(p2.X - p1.X) <= 1 || Math.Abs(p2.Z - p1.Z) <= 1)
break;
x1++; x2--;
z1++; z2--;
y1 = (ushort)(y1 + yDir);
p1.X++; p2.X--;
p1.Z++; p2.Z--;
p1.Y = (ushort)(p1.Y + yDir); p2.Y = p1.Y;
marks[0] = p1; marks[1] = p2;
}
marks[0] = origP1; marks[1] = origP2;
return total;
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[1];
while (true) {
baseOp.Perform(x1, y1, z1, x2, y1, z2, p, lvl, brush);
if (y1 >= lvl.Height || Math.Abs(x2 - x1) <= 1 || Math.Abs(z2 - z1) <= 1)
break;
x1++; x2--;
z1++; z2--;
y1 = (ushort)(y1 + yDir);
baseOp.Perform(marks, p, lvl, brush);
if (p1.Y >= lvl.Height || Math.Abs(p2.X - p1.X) <= 1 || Math.Abs(p2.Z - p1.Z) <= 1)
break;
p1.X++; p2.X--;
p1.Z++; p2.Z--;
p1.Y = (ushort)(p1.Y + yDir); p2.Y = p1.Y;
marks[0] = p1; marks[1] = p2;
}
}
}
public class PyramidSolidDrawOp : PyramidDrawOp {
public PyramidSolidDrawOp() : base(new CuboidDrawOp(), 1) {
public PyramidSolidDrawOp() : base(new CuboidDrawOp(), 1) {
}
public override string Name { get { return "Pyramid solid"; } }
@ -69,13 +74,13 @@ namespace MCGalaxy.Drawing.Ops {
public class PyramidHollowDrawOp : PyramidDrawOp {
public PyramidHollowDrawOp() : base(new CuboidWallsDrawOp(), 1) {
public PyramidHollowDrawOp() : base(new CuboidWallsDrawOp(), 1) {
}
public override string Name { get { return "Pyramid hollow"; } }
}
public class PyramidReverseDrawOp : PyramidDrawOp {
public class PyramidReverseDrawOp : PyramidDrawOp {
DrawOp wallOp;
Brush airBrush;
@ -86,16 +91,19 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Pyramid reverse"; } }
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[1];
while (true) {
wallOp.Perform(x1, y1, z1, x2, y1, z2, p, lvl, brush);
if (y1 >= lvl.Height || Math.Abs(x2 - x1) <= 1 || Math.Abs(z2 - z1) <= 1)
break;
x1++; x2--;
z1++; z2--;
baseOp.Perform(x1, y1, z1, x2, y1, z2, p, lvl, airBrush);
y1 = (ushort)(y1 + yDir);
wallOp.Perform(marks, p, lvl, brush);
if (p1.Y >= lvl.Height || Math.Abs(p2.X - p1.X) <= 1 || Math.Abs(p2.Z - p1.Z) <= 1)
break;
p1.X++; p2.X--;
p1.Z++; p2.Z--;
marks[0] = p1; marks[1] = p2;
baseOp.Perform(marks, p, lvl, airBrush);
p1.Y = (ushort)(p1.Y + yDir); p2.Y = p1.Y;
marks[0] = p1; marks[1] = p2;
}
}
}

View File

@ -30,15 +30,16 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Replace"; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
return (x2 - x1 + 1) * (y2 - y1 + 1) * (z2 - z1 + 1);
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
Vector3U16 p1 = marks[0], p2 = marks[1];
return (p2.X - p1.X + 1) * (p2.Y - p1.Y + 1) * (p2.Z - p1.Z + 1);
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
for (ushort y = y1; y <= y2; y++)
for (ushort z = z1; z <= z2; z++)
for (ushort x = x1; x <= x2; x++)
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[1];
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++)
{
byte tile = lvl.GetTile(x, y, z), extTile = 0;
if (tile == Block.custom_block) extTile = lvl.GetExtTile(x, y, z);
@ -59,15 +60,16 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "ReplaceNot"; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
return (x2 - x1 + 1) * (y2 - y1 + 1) * (z2 - z1 + 1);
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
Vector3U16 p1 = marks[0], p2 = marks[1];
return (p2.X - p1.X + 1) * (p2.Y - p1.Y + 1) * (p2.Z - p1.Z + 1);
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
for (ushort y = y1; y <= y2; y++)
for (ushort z = z1; z <= z2; z++)
for (ushort x = x1; x <= x2; x++)
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[1];
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++)
{
byte tile = lvl.GetTile(x, y, z), extTile = 0;
if (tile == Block.custom_block) extTile = lvl.GetExtTile(x, y, z);

View File

@ -24,21 +24,22 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Ellipsoid"; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
double rx = (x2 - x1) / 2.0 + 0.25, ry = (y2 - y1) / 2.0 + 0.25, rz = (z2 - z1) / 2.0 + 0.25;
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
Vector3U16 p1 = marks[0], p2 = marks[1];
double rx = (p2.X - p1.X) / 2.0 + 0.25, ry = (p2.Y - p1.Y) / 2.0 + 0.25, rz = (p2.Z - p1.Z) / 2.0 + 0.25;
return (int)(Math.PI * 4.0/3.0 * rx * ry * rz);
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[1];
/* Courtesy of fCraft's awesome Open-Source'ness :D */
double cx = (x1 + x2) / 2.0, cy = (y1 + y2) / 2.0, cz = (z1 + z2) / 2.0;
double rx = (x2 - x1) / 2.0 + 0.25, ry = (y2 - y1) / 2.0 + 0.25, rz = (z2 - z1) / 2.0 + 0.25;
double cx = (p1.X + p2.X) / 2.0, cy = (p1.Y + p2.Y) / 2.0, cz = (p1.Z + p2.Z) / 2.0;
double rx = (p2.X - p1.X) / 2.0 + 0.25, ry = (p2.Y - p1.Y) / 2.0 + 0.25, rz = (p2.Z - p1.Z) / 2.0 + 0.25;
double rx2 = 1 / (rx * rx), ry2 = 1 / (ry * ry), rz2 = 1 / (rz * rz);
for (ushort yy = y1; yy <= y2; yy++)
for (ushort zz = z1; zz <= z2; zz++)
for (ushort xx = x1; xx <= x2; xx++)
for (ushort yy = p1.Y; yy <= p2.Y; yy++)
for (ushort zz = p1.Z; zz <= p2.Z; zz++)
for (ushort xx = p1.X; xx <= p2.X; xx++)
{
double dx = xx - cx, dy = yy - cy, dz = zz - cz;
if ((dx * dx) * rx2 + (dy * dy) * ry2 + (dz * dz) * rz2 <= 1)
@ -51,31 +52,32 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Ellipsoid Hollow"; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
double rx = (x2 - x1) / 2.0 + 0.25, ry = (y2 - y1) / 2.0 + 0.25, rz = (z2 - z1) / 2.0 + 0.25;
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
Vector3U16 p1 = marks[0], p2 = marks[1];
double rx = (p2.X - p1.X) / 2.0 + 0.25, ry = (p2.Y - p1.Y) / 2.0 + 0.25, rz = (p2.Z - p1.Z) / 2.0 + 0.25;
return (int)(Math.PI * 4.0/3.0 * rx * ry * rz);
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[1];
/* Courtesy of fCraft's awesome Open-Source'ness :D */
double cx = (x1 + x2) / 2.0, cy = (y1 + y2) / 2.0, cz = (z1 + z2) / 2.0;
double rx = (x2 - x1) / 2.0 + 0.25, ry = (y2 - y1) / 2.0 + 0.25, rz = (z2 - z1) / 2.0 + 0.25;
double cx = (p1.X + p2.X) / 2.0, cy = (p1.Y + p2.Y) / 2.0, cz = (p1.Z + p2.Z) / 2.0;
double rx = (p2.X - p1.X) / 2.0 + 0.25, ry = (p2.Y - p1.Y) / 2.0 + 0.25, rz = (p2.Z - p1.Z) / 2.0 + 0.25;
double rx2 = 1 / (rx * rx), ry2 = 1 / (ry * ry), rz2 = 1 / (rz * rz);
double smallrx2 = 1 / ((rx - 1) * (rx - 1));
double smallry2 = 1 / ((ry - 1) * (ry - 1));
double smallrz2 = 1 / ((rz - 1) * (rz - 1));
for (ushort yy = y1; yy <= y2; yy++)
for (ushort zz = z1; zz <= z2; zz++)
for (ushort xx = x1; xx <= x2; xx++)
for (ushort yy = p1.Y; yy <= p2.Y; yy++)
for (ushort zz = p1.Z; zz <= p2.Z; zz++)
for (ushort xx = p1.X; xx <= p2.X; xx++)
{
double dx = xx - cx, dy = yy - cy, dz = zz - cz;
dx *= dx; dy *= dy; dz *= dz;
bool inRange = dx * rx2 + dy * ry2 + dz * rz2 <= 1;
if (inRange && (dx * smallrx2 + dy * smallry2 + dz * smallrz2 > 1))
PlaceBlock(p, lvl, xx, yy, zz, brush);
PlaceBlock(p, lvl, xx, yy, zz, brush);
}
}
}
@ -84,24 +86,25 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Cylinder"; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
double rx = (x2 - x1) / 2.0 + 0.25, rz = (z2 - z1) / 2.0 + 0.25;
int height = (y2 - y1 + 1);
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
Vector3U16 p1 = marks[0], p2 = marks[1];
double rx = (p2.X - p1.X) / 2.0 + 0.25, rz = (p2.Z - p1.Z) / 2.0 + 0.25;
int height = (p2.Y - p1.Y + 1);
return (int)(Math.PI * rx * rz * height);
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[1];
/* Courtesy of fCraft's awesome Open-Source'ness :D */
double cx = (x1 + x2) / 2.0, cz = (z1 + z2) / 2.0;
double rx = (x2 - x1) / 2.0 + 0.25, rz = (z2 - z1) / 2.0 + 0.25;
double rx2 = 1 / (rx * rx), rz2 = 1 / (rz * rz);
double cx = (p1.X + p2.X) / 2.0, cz = (p1.Z + p2.Z) / 2.0;
double rx = (p2.X - p1.X) / 2.0 + 0.25, rz = (p2.Z - p1.Z) / 2.0 + 0.25;
double rx2= 1 / (rx * rx), rz2 = 1 / (rz * rz);
double smallrx2 = 1 / ((rx - 1) * (rx - 1));
double smallrz2 = 1 / ((rz - 1) * (rz - 1));
for (ushort yy = y1; yy <= y2; yy++)
for (ushort zz = z1; zz <= z2; zz++)
for (ushort xx = x1; xx <= x2; xx++)
for (ushort yy = p1.Y; yy <= p2.Y; yy++)
for (ushort zz = p1.Z; zz <= p2.Z; zz++)
for (ushort xx = p1.X; xx <= p2.X; xx++)
{
double dx = xx - cx, dz = zz - cz;
dx *= dx; dz *= dz;

View File

@ -24,23 +24,24 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "Torus"; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
double rx = (x2 - x1) / 2.0 + 0.25, ry = (y2 - y1) / 2.0 + 0.25, rz = (z2 - z1) / 2.0 + 0.25;
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
Vector3U16 p1 = marks[0], p2 = marks[1];
double rx = (p2.X - p1.X) / 2.0 + 0.25, ry = (p2.Y - p1.Y) / 2.0 + 0.25, rz = (p2.Z - p1.Z) / 2.0 + 0.25;
double rTube = ry, rCentre = Math.Min(rx, rz) - rTube;
return (int)(2 * Math.PI * Math.PI * rTube * rTube * rCentre);
}
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
double cx = (x1 + x2) / 2.0, cy = (y1 + y2) / 2.0, cz = (z1 + z2) / 2.0;
double rx = (x2 - x1) / 2.0 + 0.25, ry = (y2 - y1) / 2.0 + 0.25, rz = (z2 - z1) / 2.0 + 0.25;
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[1];
double cx = (p1.X + p2.X) / 2.0, cy = (p1.Y + p2.Y) / 2.0, cz = (p1.Z + p2.Z) / 2.0;
double rx = (p2.X - p1.X) / 2.0 + 0.25, ry = (p2.Y - p1.Y) / 2.0 + 0.25, rz = (p2.Z - p1.Z) / 2.0 + 0.25;
double rTube = ry, rCentre = Math.Min(rx, rz) - rTube;
for (ushort yy = y1; yy <= y2; yy++)
for (ushort zz = z1; zz <= z2; zz++)
for (ushort xx = x1; xx <= x2; xx++)
for (ushort yy = p1.Y; yy <= p2.Y; yy++)
for (ushort zz = p1.Z; zz <= p2.Z; zz++)
for (ushort xx = p1.X; xx <= p2.X; xx++)
{
double dx = xx - cx, dy = yy - cy, dz = zz - cz;
double dx = xx - cx, dy = yy - cy, dz = zz - cz;
dx *= dx; dy *= dy; dz *= dz;
double dInner = rCentre - Math.Sqrt( dx + dz );

View File

@ -30,7 +30,7 @@ namespace MCGalaxy.Drawing.Ops {
public override bool MinMaxCoords { get { return false; } }
public override int GetBlocksAffected(Level lvl, ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {
public override int GetBlocksAffected(Level lvl, Vector3U16[] marks) {
int blocks = 0;
foreach (char c in Text) {
if ((int)c >= 256 || letters[(int)c] == null) {
@ -45,14 +45,14 @@ namespace MCGalaxy.Drawing.Ops {
}
int dirX, dirZ;
public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2,
ushort y2, ushort z2, Player p, Level lvl, Brush brush) {
if (Math.Abs(x2 - x1) > Math.Abs(z2 - z1))
dirX = x2 > x1? 1 : -1;
public override void Perform(Vector3U16[] marks, Player p, Level lvl, Brush brush) {
Vector3U16 p1 = marks[0], p2 = marks[1];
if (Math.Abs(p2.X - p1.X) > Math.Abs(p2.Z - p1.Z))
dirX = p2.X > p1.X? 1 : -1;
else
dirZ = z2 > z1 ? 1 : -1;
dirZ = p2.Z > p1.Z ? 1 : -1;
foreach (char c in Text)
DrawLetter(p, lvl, c, ref x1, y1, ref z1, brush);
DrawLetter(p, lvl, c, ref p1.X, p1.Y, ref p1.Z, brush);
}
void DrawLetter(Player p, Level lvl, char c, ref ushort x, ushort y, ref ushort z, Brush brush) {

View File

@ -78,5 +78,9 @@ namespace MCGalaxy.Drawing {
public static Vector3U16 operator - (Vector3U16 a, Vector3U16 b) {
return new Vector3U16((ushort)(a.X - b.X), (ushort)(a.Y - b.Y), (ushort)(a.Z - b.Z));
}
public override string ToString() {
return X + "," + Y + "," + Z;
}
}
}

View File

@ -219,6 +219,7 @@ namespace MCGalaxy.Games {
internal void UpdateAllPlayerStatus() {
int seconds = (int)(RoundEnd - DateTime.UtcNow).TotalSeconds;
Server.s.Log("UPDATE ALL - " + seconds);
UpdateAllPlayerStatus(GetTimespan(seconds));
}

View File

@ -61,7 +61,6 @@ namespace MCGalaxy.Levels.IO {
writer.WriteLine("Unload = " + level.unload);
writer.WriteLine("WorldChat = " + level.worldChat);
writer.WriteLine();
writer.WriteLine("PerBuild = " + GetName(level.permissionbuild));
writer.WriteLine("PerVisit = " + GetName(level.permissionvisit));
writer.WriteLine("PerBuildMax = " + GetName(level.perbuildmax));
@ -69,7 +68,6 @@ namespace MCGalaxy.Levels.IO {
writer.WriteLine("Buildable = " + level.Buildable);
writer.WriteLine("Deletable = " + level.Deletable);
writer.WriteLine();
writer.WriteLine("Guns = " + level.guns);
writer.WriteLine("LoadOnGoto = " + level.loadOnGoto);
writer.WriteLine("LeafDecay = " + level.leafDecay);
@ -79,7 +77,6 @@ namespace MCGalaxy.Levels.IO {
writer.WriteLine("Texture = " + level.terrainUrl);
writer.WriteLine("TexturePack = " + level.texturePackUrl);
writer.WriteLine();
writer.WriteLine("Likes = " + level.Likes);
writer.WriteLine("Dislikes = " + level.Dislikes);
writer.WriteLine("Authors = " + level.Authors);