mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-23 04:32:50 -04:00
Rewrite /imageprint to be a drawop. This means the output can now be affected by /transform.
This commit is contained in:
parent
4e271d1ede
commit
e29a3d31c6
@ -121,25 +121,13 @@ namespace MCGalaxy.Commands.Building {
|
||||
op.Source = bmp;
|
||||
op.Layer = dArgs.layer;
|
||||
op.Mode = dArgs.popType;
|
||||
op.Filename = dArgs.name;
|
||||
|
||||
if (op.Layer) {
|
||||
if (op.Mode == 1) op.Mode = 2;
|
||||
if (op.Mode == 3) op.Mode = 4;
|
||||
}
|
||||
|
||||
BufferedBlockSender buffer = new BufferedBlockSender(op.Level);
|
||||
foreach (var b in op.Perform(m, p, p.level, null)) {
|
||||
if (b.Block == Block.Zero) continue;
|
||||
if (!op.Level.DoBlockchange(p, b.X, b.Y, b.Z, b.Block, b.ExtBlock, true)) continue;
|
||||
|
||||
int index = op.Level.PosToInt(b.X, b.Y, b.Z);
|
||||
op.Level.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
|
||||
buffer.Add(index, b.Block, b.ExtBlock);
|
||||
}
|
||||
buffer.Send(true);
|
||||
|
||||
if (dArgs.name == "tempImage_" + p.name)
|
||||
File.Delete("extra/images/tempImage_" + p.name + ".bmp");
|
||||
Player.Message(p, "Finished printing image using " + ImagePalette.Names[op.Mode]);
|
||||
DrawOp.DoDrawOp(op, null, p, m, false);
|
||||
}
|
||||
|
||||
public override void Help(Player p) {
|
||||
|
@ -53,7 +53,7 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
}
|
||||
|
||||
long affected = op.BlocksAffected(op.Level, marks);
|
||||
if (p != null && op.AffectedByTransform)
|
||||
if (p != null && op.AffectedByTransform)
|
||||
p.Transform.GetBlocksAffected(ref affected);
|
||||
|
||||
if (checkLimit && !op.CanDraw(marks, p, affected))
|
||||
@ -73,13 +73,8 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
static void AppendDrawOp(Player p, DrawOp op, Brush brush, Vec3S32[] marks, long affected) {
|
||||
if (p == null) {
|
||||
BufferedBlockSender buffer = new BufferedBlockSender(op.Level);
|
||||
foreach (var b in op.Perform(marks, p, op.Level, brush)) {
|
||||
int index = op.Level.PosToInt(b.X, b.Y, b.Z);
|
||||
if (!op.Level.DoPhysicsBlockchange(index, b.Block, false,
|
||||
default(PhysicsArgs), b.ExtBlock)) continue;
|
||||
|
||||
buffer.Add(index, b.Block, b.ExtBlock);
|
||||
}
|
||||
op.Perform(marks, p, op.Level, brush,
|
||||
b => ConsoleOutputBlock(b, op.Level, buffer));
|
||||
buffer.Send(true);
|
||||
return;
|
||||
}
|
||||
@ -99,6 +94,13 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
ProcessDrawOps(p);
|
||||
}
|
||||
|
||||
static void ConsoleOutputBlock(DrawOpBlock b, Level lvl, BufferedBlockSender buffer) {
|
||||
int index = lvl.PosToInt(b.X, b.Y, b.Z);
|
||||
if (!lvl.DoPhysicsBlockchange(index, b.Block, false,
|
||||
default(PhysicsArgs), b.ExtBlock)) return;
|
||||
buffer.Add(index, b.Block, b.ExtBlock);
|
||||
}
|
||||
|
||||
static void ProcessDrawOps(Player p) {
|
||||
while (true) {
|
||||
PendingDrawOp item;
|
||||
@ -138,44 +140,56 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
|
||||
static void DoDrawOp(PendingDrawOp item, Player p) {
|
||||
Level lvl = item.Level;
|
||||
IEnumerable<DrawOpBlock> iterator = null;
|
||||
if (item.Op.AffectedByTransform)
|
||||
iterator = p.Transform.Perform(item.Marks, p, lvl, item.Op, item.Brush);
|
||||
else
|
||||
iterator = item.Op.Perform(item.Marks, p, lvl, item.Brush);
|
||||
Action<DrawOpBlock, Player, Level> output = null;
|
||||
|
||||
if (item.Affected > Server.DrawReloadLimit) {
|
||||
foreach (var b in iterator) {
|
||||
if (b.Block == Block.Zero) continue;
|
||||
byte old = lvl.GetTile(b.X, b.Y, b.Z);
|
||||
bool sameBlock = old == b.Block;
|
||||
if (sameBlock && b.Block == Block.custom_block)
|
||||
sameBlock = lvl.GetExtTile(b.X, b.Y, b.Z) == b.ExtBlock;
|
||||
|
||||
if (sameBlock || old == Block.Zero || !lvl.CheckAffectPermissions(p, b.X, b.Y, b.Z, old, b.Block, b.ExtBlock))
|
||||
continue;
|
||||
lvl.SetTile(b.X, b.Y, b.Z, b.Block, p, b.ExtBlock);
|
||||
p.IncrementBlockStats(b.Block, true);
|
||||
}
|
||||
output = SetTileOutput;
|
||||
} else if (item.Level.bufferblocks) {
|
||||
foreach (var b in iterator) {
|
||||
if (b.Block == Block.Zero) continue;
|
||||
if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Block, b.ExtBlock, true)) continue;
|
||||
|
||||
int index = lvl.PosToInt(b.X, b.Y, b.Z);
|
||||
lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
|
||||
BlockQueue.Addblock(p, index, b.Block, b.ExtBlock);
|
||||
}
|
||||
output = BufferedOutput;
|
||||
} else {
|
||||
foreach (var b in iterator) {
|
||||
if (b.Block == Block.Zero) continue;
|
||||
if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Block, b.ExtBlock, true)) continue;
|
||||
|
||||
int index = lvl.PosToInt(b.X, b.Y, b.Z);
|
||||
lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
|
||||
Player.GlobalBlockchange(lvl, b.X, b.Y, b.Z, b.Block, b.ExtBlock);
|
||||
}
|
||||
output = SlowOutput;
|
||||
}
|
||||
|
||||
if (item.Op.AffectedByTransform) {
|
||||
p.Transform.Perform(item.Marks, p, lvl, item.Op, item.Brush,
|
||||
b => output(b, p, lvl));
|
||||
} else {
|
||||
item.Op.Perform(item.Marks, p, lvl, item.Brush,
|
||||
b => output(b, p, lvl));
|
||||
}
|
||||
}
|
||||
|
||||
static void SetTileOutput(DrawOpBlock b, Player p, Level lvl) {
|
||||
if (b.Block == Block.Zero) return;
|
||||
byte old = lvl.GetTile(b.X, b.Y, b.Z);
|
||||
if (old == Block.Zero) return;
|
||||
|
||||
bool same = old == b.Block;
|
||||
if (same && b.Block == Block.custom_block)
|
||||
same = lvl.GetExtTile(b.X, b.Y, b.Z) == b.ExtBlock;
|
||||
if (same || !lvl.CheckAffectPermissions(p, b.X, b.Y, b.Z, old, b.Block, b.ExtBlock))
|
||||
return;
|
||||
|
||||
lvl.SetTile(b.X, b.Y, b.Z, b.Block, p, b.ExtBlock);
|
||||
p.IncrementBlockStats(b.Block, true);
|
||||
}
|
||||
|
||||
static void BufferedOutput(DrawOpBlock b, Player p, Level lvl) {
|
||||
if (b.Block == Block.Zero) return;
|
||||
if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Block, b.ExtBlock, true)) return;
|
||||
|
||||
int index = lvl.PosToInt(b.X, b.Y, b.Z);
|
||||
lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
|
||||
BlockQueue.Addblock(p, index, b.Block, b.ExtBlock);
|
||||
}
|
||||
|
||||
static void SlowOutput(DrawOpBlock b, Player p, Level lvl) {
|
||||
if (b.Block == Block.Zero) return;
|
||||
if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Block, b.ExtBlock, true)) return;
|
||||
|
||||
int index = lvl.PosToInt(b.X, b.Y, b.Z);
|
||||
lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
|
||||
Player.GlobalBlockchange(lvl, b.X, b.Y, b.Z, b.Block, b.ExtBlock);
|
||||
}
|
||||
|
||||
static void DoReload(Player p, Level lvl) {
|
||||
@ -186,6 +200,6 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
}
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Draw = System.Drawing;
|
||||
using MCGalaxy.Drawing.Brushes;
|
||||
|
||||
@ -32,6 +33,7 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
internal Draw.Bitmap Source;
|
||||
internal int Mode, Direction;
|
||||
internal bool Layer;
|
||||
internal string Filename;
|
||||
|
||||
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
|
||||
Vec3U16 p0 = Clamp(marks[0]);
|
||||
@ -69,7 +71,12 @@ namespace MCGalaxy.Drawing.Ops {
|
||||
if (col.A < 20) cur.Block = Block.air;
|
||||
output(Place(X, Y, Z, cur.Block, 0));
|
||||
}
|
||||
|
||||
Source.Dispose();
|
||||
Source = null;
|
||||
if (Filename == "tempImage_" + p.name)
|
||||
File.Delete("extra/images/tempImage_" + p.name + ".bmp");
|
||||
Player.Message(p, "Finished printing image using " + ImagePalette.Names[Mode]);
|
||||
}
|
||||
|
||||
void CalcMul(bool layer, int dir,
|
||||
|
@ -26,9 +26,9 @@ namespace MCGalaxy.Drawing.Transforms {
|
||||
public override string Name { get { return "None"; } }
|
||||
public static NoTransform Instance = new NoTransform();
|
||||
|
||||
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p,
|
||||
Level lvl, DrawOp op, Brush brush) {
|
||||
return op.Perform(marks, p, lvl, brush);
|
||||
public override void Perform(Vec3S32[] marks, Player p, Level lvl,
|
||||
DrawOp op, Brush brush, Action<DrawOpBlock> output) {
|
||||
op.Perform(marks, p, lvl, brush, output);
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,6 +37,9 @@ namespace MCGalaxy.Drawing.Transforms {
|
||||
public override string Name { get { return "Scale"; } }
|
||||
public bool CentreOrigin;
|
||||
public int XMul, XDiv, YMul, YDiv, ZMul, ZDiv;
|
||||
int dirX, dirY, dirZ;
|
||||
int width, height, length;
|
||||
Vec3S32 P;
|
||||
|
||||
public override void GetBlocksAffected(ref long affected) {
|
||||
// NOTE: We do not the actual size of the drawop on each axis, so we take
|
||||
@ -45,10 +48,12 @@ namespace MCGalaxy.Drawing.Transforms {
|
||||
affected = Math.Max(x, Math.Max(y, z));
|
||||
}
|
||||
|
||||
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p,
|
||||
Level lvl, DrawOp op, Brush brush) {
|
||||
Vec3S32 P = (op.Min + op.Max) / 2;
|
||||
int dirX = 1, dirY = 1, dirZ = 1;
|
||||
public override void Perform(Vec3S32[] marks, Player p, Level lvl,
|
||||
DrawOp op, Brush brush, Action<DrawOpBlock> output) {
|
||||
P = (op.Min + op.Max) / 2;
|
||||
dirX = 1; dirY = 1; dirZ = 1;
|
||||
width = lvl.Width; height = lvl.Height; length = lvl.Length;
|
||||
|
||||
if (!CentreOrigin) {
|
||||
// Guess the direction in which we should be scaling -
|
||||
// for simplicity we assume we are scaling in positive direction
|
||||
@ -56,21 +61,21 @@ namespace MCGalaxy.Drawing.Transforms {
|
||||
dirX = op.Min.X == op.Max.X ? 1 : (P.X == op.Max.X ? -1 : 1);
|
||||
dirY = op.Min.Y == op.Max.Y ? 1 : (P.Y == op.Max.Y ? -1 : 1);
|
||||
dirZ = op.Min.Z == op.Max.Z ? 1 : (P.Z == op.Max.Z ? -1 : 1);
|
||||
}
|
||||
}
|
||||
op.Perform(marks, p, lvl, brush, b => OutputBlock(b, output));
|
||||
}
|
||||
|
||||
void OutputBlock(DrawOpBlock b, Action<DrawOpBlock> output) {
|
||||
int dx = b.X - P.X, dy = b.Y - P.Y, dz = b.Z - P.Z;
|
||||
|
||||
foreach (DrawOpBlock b in op.Perform(marks, p, lvl, brush)) {
|
||||
int dx = b.X - P.X, dy = b.Y - P.Y, dz = b.Z - P.Z;
|
||||
DrawOpBlock cur = b;
|
||||
|
||||
// Scale out until we hit the next block
|
||||
for (int y = P.Y + dy * YMul / YDiv; y != P.Y + (dy + dirY) * YMul / YDiv; y += dirY)
|
||||
for (int z = P.Z + dz * ZMul / ZDiv; z != P.Z + (dz + dirZ) * ZMul / ZDiv; z += dirZ)
|
||||
for (int x = P.X + dx * XMul / XDiv; x != P.X + (dx + dirX) * XMul / XDiv; x += dirX)
|
||||
{
|
||||
if (!lvl.IsValidPos(x, y, z)) continue;
|
||||
cur.X = (ushort)x; cur.Y = (ushort)y; cur.Z = (ushort)z;
|
||||
yield return cur;
|
||||
}
|
||||
// Scale out until we hit the next block
|
||||
for (int y = P.Y + dy * YMul / YDiv; y != P.Y + (dy + dirY) * YMul / YDiv; y += dirY)
|
||||
for (int z = P.Z + dz * ZMul / ZDiv; z != P.Z + (dz + dirZ) * ZMul / ZDiv; z += dirZ)
|
||||
for (int x = P.X + dx * XMul / XDiv; x != P.X + (dx + dirX) * XMul / XDiv; x += dirX)
|
||||
{
|
||||
if (x < 0 || y < 0 || z < 0 || x >= width || y >= height || z >= length) continue;
|
||||
b.X = (ushort)x; b.Y = (ushort)y; b.Z = (ushort)z;
|
||||
output(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ namespace MCGalaxy.Drawing.Transforms {
|
||||
/// <summary> Performs calcuations (if necessary) for the given drawop. </summary>
|
||||
public virtual void Configure(DrawOp op, Player p) { }
|
||||
|
||||
public abstract IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p,
|
||||
Level lvl, DrawOp op, Brush brush);
|
||||
public abstract void Perform(Vec3S32[] marks, Player p, Level lvl,
|
||||
DrawOp op, Brush brush, Action<DrawOpBlock> output);
|
||||
}
|
||||
}
|
||||
|
@ -147,8 +147,8 @@ namespace MCGalaxy.Generator {
|
||||
treeCoords[0].X = x; treeCoords[0].Y = (ushort)(y + 1); treeCoords[0].Z = z;
|
||||
treeDrawer.SetMarks(treeCoords);
|
||||
|
||||
foreach (var block in treeDrawer.Perform(treeCoords, null, Lvl, null))
|
||||
Lvl.SetTile(block.X, block.Y, block.Z, block.Block);
|
||||
treeDrawer.Perform(treeCoords, null, Lvl, null,
|
||||
b => Lvl.SetTile(b.X, b.Y, b.Z, b.Block));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,9 +126,8 @@ namespace MCGalaxy.BlockPhysics {
|
||||
Vec3S32[] marks = new [] { new Vec3S32(x, y, z) };
|
||||
op.SetMarks(marks);
|
||||
|
||||
foreach (var block in op.Perform(marks, null, lvl, null)) {
|
||||
lvl.Blockchange(block.X, block.Y, block.Z, block.Block);
|
||||
}
|
||||
op.Perform(marks, null, lvl, null,
|
||||
b => lvl.Blockchange(b.X, b.Y, b.Z, b.Block));
|
||||
C.data.Data = 255;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user