mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-24 05:03:34 -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.Source = bmp;
|
||||||
op.Layer = dArgs.layer;
|
op.Layer = dArgs.layer;
|
||||||
op.Mode = dArgs.popType;
|
op.Mode = dArgs.popType;
|
||||||
|
op.Filename = dArgs.name;
|
||||||
|
|
||||||
if (op.Layer) {
|
if (op.Layer) {
|
||||||
if (op.Mode == 1) op.Mode = 2;
|
if (op.Mode == 1) op.Mode = 2;
|
||||||
if (op.Mode == 3) op.Mode = 4;
|
if (op.Mode == 3) op.Mode = 4;
|
||||||
}
|
}
|
||||||
|
DrawOp.DoDrawOp(op, null, p, m, false);
|
||||||
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]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Help(Player p) {
|
public override void Help(Player p) {
|
||||||
|
@ -73,13 +73,8 @@ 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) {
|
if (p == null) {
|
||||||
BufferedBlockSender buffer = new BufferedBlockSender(op.Level);
|
BufferedBlockSender buffer = new BufferedBlockSender(op.Level);
|
||||||
foreach (var b in op.Perform(marks, p, op.Level, brush)) {
|
op.Perform(marks, p, op.Level, brush,
|
||||||
int index = op.Level.PosToInt(b.X, b.Y, b.Z);
|
b => ConsoleOutputBlock(b, op.Level, buffer));
|
||||||
if (!op.Level.DoPhysicsBlockchange(index, b.Block, false,
|
|
||||||
default(PhysicsArgs), b.ExtBlock)) continue;
|
|
||||||
|
|
||||||
buffer.Add(index, b.Block, b.ExtBlock);
|
|
||||||
}
|
|
||||||
buffer.Send(true);
|
buffer.Send(true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -99,6 +94,13 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
ProcessDrawOps(p);
|
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) {
|
static void ProcessDrawOps(Player p) {
|
||||||
while (true) {
|
while (true) {
|
||||||
PendingDrawOp item;
|
PendingDrawOp item;
|
||||||
@ -138,45 +140,57 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
|
|
||||||
static void DoDrawOp(PendingDrawOp item, Player p) {
|
static void DoDrawOp(PendingDrawOp item, Player p) {
|
||||||
Level lvl = item.Level;
|
Level lvl = item.Level;
|
||||||
IEnumerable<DrawOpBlock> iterator = null;
|
Action<DrawOpBlock, Player, Level> output = 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);
|
|
||||||
|
|
||||||
if (item.Affected > Server.DrawReloadLimit) {
|
if (item.Affected > Server.DrawReloadLimit) {
|
||||||
foreach (var b in iterator) {
|
output = SetTileOutput;
|
||||||
if (b.Block == Block.Zero) continue;
|
} else if (item.Level.bufferblocks) {
|
||||||
byte old = lvl.GetTile(b.X, b.Y, b.Z);
|
output = BufferedOutput;
|
||||||
bool sameBlock = old == b.Block;
|
} else {
|
||||||
if (sameBlock && b.Block == Block.custom_block)
|
output = SlowOutput;
|
||||||
sameBlock = lvl.GetExtTile(b.X, b.Y, b.Z) == b.ExtBlock;
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
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);
|
lvl.SetTile(b.X, b.Y, b.Z, b.Block, p, b.ExtBlock);
|
||||||
p.IncrementBlockStats(b.Block, true);
|
p.IncrementBlockStats(b.Block, true);
|
||||||
}
|
}
|
||||||
} else if (item.Level.bufferblocks) {
|
|
||||||
foreach (var b in iterator) {
|
static void BufferedOutput(DrawOpBlock b, Player p, Level lvl) {
|
||||||
if (b.Block == Block.Zero) continue;
|
if (b.Block == Block.Zero) return;
|
||||||
if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Block, b.ExtBlock, true)) continue;
|
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);
|
int index = lvl.PosToInt(b.X, b.Y, b.Z);
|
||||||
lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
|
lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
|
||||||
BlockQueue.Addblock(p, index, b.Block, b.ExtBlock);
|
BlockQueue.Addblock(p, index, b.Block, b.ExtBlock);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
foreach (var b in iterator) {
|
static void SlowOutput(DrawOpBlock b, Player p, Level lvl) {
|
||||||
if (b.Block == Block.Zero) continue;
|
if (b.Block == Block.Zero) return;
|
||||||
if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Block, b.ExtBlock, true)) continue;
|
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);
|
int index = lvl.PosToInt(b.X, b.Y, b.Z);
|
||||||
lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
|
lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
|
||||||
Player.GlobalBlockchange(lvl, b.X, b.Y, b.Z, b.Block, b.ExtBlock);
|
Player.GlobalBlockchange(lvl, b.X, b.Y, b.Z, b.Block, b.ExtBlock);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DoReload(Player p, Level lvl) {
|
static void DoReload(Player p, Level lvl) {
|
||||||
Player[] players = PlayerInfo.Online.Items;
|
Player[] players = PlayerInfo.Online.Items;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using Draw = System.Drawing;
|
using Draw = System.Drawing;
|
||||||
using MCGalaxy.Drawing.Brushes;
|
using MCGalaxy.Drawing.Brushes;
|
||||||
|
|
||||||
@ -32,6 +33,7 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
internal Draw.Bitmap Source;
|
internal Draw.Bitmap Source;
|
||||||
internal int Mode, Direction;
|
internal int Mode, Direction;
|
||||||
internal bool Layer;
|
internal bool Layer;
|
||||||
|
internal string Filename;
|
||||||
|
|
||||||
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
|
public override void Perform(Vec3S32[] marks, Player p, Level lvl, Brush brush, Action<DrawOpBlock> output) {
|
||||||
Vec3U16 p0 = Clamp(marks[0]);
|
Vec3U16 p0 = Clamp(marks[0]);
|
||||||
@ -69,7 +71,12 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
if (col.A < 20) cur.Block = Block.air;
|
if (col.A < 20) cur.Block = Block.air;
|
||||||
output(Place(X, Y, Z, cur.Block, 0));
|
output(Place(X, Y, Z, cur.Block, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Source.Dispose();
|
||||||
Source = null;
|
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,
|
void CalcMul(bool layer, int dir,
|
||||||
|
@ -26,9 +26,9 @@ namespace MCGalaxy.Drawing.Transforms {
|
|||||||
public override string Name { get { return "None"; } }
|
public override string Name { get { return "None"; } }
|
||||||
public static NoTransform Instance = new NoTransform();
|
public static NoTransform Instance = new NoTransform();
|
||||||
|
|
||||||
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p,
|
public override void Perform(Vec3S32[] marks, Player p, Level lvl,
|
||||||
Level lvl, DrawOp op, Brush brush) {
|
DrawOp op, Brush brush, Action<DrawOpBlock> output) {
|
||||||
return op.Perform(marks, p, lvl, brush);
|
op.Perform(marks, p, lvl, brush, output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,6 +37,9 @@ namespace MCGalaxy.Drawing.Transforms {
|
|||||||
public override string Name { get { return "Scale"; } }
|
public override string Name { get { return "Scale"; } }
|
||||||
public bool CentreOrigin;
|
public bool CentreOrigin;
|
||||||
public int XMul, XDiv, YMul, YDiv, ZMul, ZDiv;
|
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) {
|
public override void GetBlocksAffected(ref long affected) {
|
||||||
// NOTE: We do not the actual size of the drawop on each axis, so we take
|
// 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));
|
affected = Math.Max(x, Math.Max(y, z));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p,
|
public override void Perform(Vec3S32[] marks, Player p, Level lvl,
|
||||||
Level lvl, DrawOp op, Brush brush) {
|
DrawOp op, Brush brush, Action<DrawOpBlock> output) {
|
||||||
Vec3S32 P = (op.Min + op.Max) / 2;
|
P = (op.Min + op.Max) / 2;
|
||||||
int dirX = 1, dirY = 1, dirZ = 1;
|
dirX = 1; dirY = 1; dirZ = 1;
|
||||||
|
width = lvl.Width; height = lvl.Height; length = lvl.Length;
|
||||||
|
|
||||||
if (!CentreOrigin) {
|
if (!CentreOrigin) {
|
||||||
// Guess the direction in which we should be scaling -
|
// Guess the direction in which we should be scaling -
|
||||||
// for simplicity we assume we are scaling in positive direction
|
// for simplicity we assume we are scaling in positive direction
|
||||||
@ -57,20 +62,20 @@ namespace MCGalaxy.Drawing.Transforms {
|
|||||||
dirY = op.Min.Y == op.Max.Y ? 1 : (P.Y == op.Max.Y ? -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);
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
foreach (DrawOpBlock b in op.Perform(marks, p, lvl, brush)) {
|
void OutputBlock(DrawOpBlock b, Action<DrawOpBlock> output) {
|
||||||
int dx = b.X - P.X, dy = b.Y - P.Y, dz = b.Z - P.Z;
|
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
|
// 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 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 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)
|
for (int x = P.X + dx * XMul / XDiv; x != P.X + (dx + dirX) * XMul / XDiv; x += dirX)
|
||||||
{
|
{
|
||||||
if (!lvl.IsValidPos(x, y, z)) continue;
|
if (x < 0 || y < 0 || z < 0 || x >= width || y >= height || z >= length) continue;
|
||||||
cur.X = (ushort)x; cur.Y = (ushort)y; cur.Z = (ushort)z;
|
b.X = (ushort)x; b.Y = (ushort)y; b.Z = (ushort)z;
|
||||||
yield return cur;
|
output(b);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ namespace MCGalaxy.Drawing.Transforms {
|
|||||||
/// <summary> Performs calcuations (if necessary) for the given drawop. </summary>
|
/// <summary> Performs calcuations (if necessary) for the given drawop. </summary>
|
||||||
public virtual void Configure(DrawOp op, Player p) { }
|
public virtual void Configure(DrawOp op, Player p) { }
|
||||||
|
|
||||||
public abstract IEnumerable<DrawOpBlock> Perform(Vec3S32[] marks, Player p,
|
public abstract void Perform(Vec3S32[] marks, Player p, Level lvl,
|
||||||
Level lvl, DrawOp op, Brush brush);
|
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;
|
treeCoords[0].X = x; treeCoords[0].Y = (ushort)(y + 1); treeCoords[0].Z = z;
|
||||||
treeDrawer.SetMarks(treeCoords);
|
treeDrawer.SetMarks(treeCoords);
|
||||||
|
|
||||||
foreach (var block in treeDrawer.Perform(treeCoords, null, Lvl, null))
|
treeDrawer.Perform(treeCoords, null, Lvl, null,
|
||||||
Lvl.SetTile(block.X, block.Y, block.Z, block.Block);
|
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) };
|
Vec3S32[] marks = new [] { new Vec3S32(x, y, z) };
|
||||||
op.SetMarks(marks);
|
op.SetMarks(marks);
|
||||||
|
|
||||||
foreach (var block in op.Perform(marks, null, lvl, null)) {
|
op.Perform(marks, null, lvl, null,
|
||||||
lvl.Blockchange(block.X, block.Y, block.Z, block.Block);
|
b => lvl.Blockchange(b.X, b.Y, b.Z, b.Block));
|
||||||
}
|
|
||||||
C.data.Data = 255;
|
C.data.Data = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user