Refactor /img to be more modular

This commit is contained in:
UnknownShadow200 2017-02-16 15:14:03 +11:00
parent e3500790f1
commit bddec7cca6
6 changed files with 260 additions and 275 deletions

View File

@ -41,44 +41,36 @@ namespace MCGalaxy.Commands.Building {
public override void Use(Player p, string message) { public override void Use(Player p, string message) {
if (!Directory.Exists("extra/images/")) if (!Directory.Exists("extra/images/"))
Directory.CreateDirectory("extra/images/"); Directory.CreateDirectory("extra/images/");
bool layer = false;
byte popType = 1;
string bitmapLoc = null;
if (message == "") { Help(p); return; } if (message == "") { Help(p); return; }
string[] parts = message.SplitSpaces(3);
if (message.IndexOf(' ') != -1) {
string[] args = message.Split(' ');
for (int i = 0; i < args.Length; i++)
{
if (args[i] == "layer" || args[i] == "l") layer = true;
else if (args[i] == "1" || args[i] == "2color") popType = 1;
else if (args[i] == "2" || args[i] == "1color") popType = 2;
else if (args[i] == "3" || args[i] == "2gray") popType = 3;
else if (args[i] == "4" || args[i] == "1gray") popType = 4;
else if (args[i] == "5" || args[i] == "bw") popType = 5;
else if (args[i] == "6" || args[i] == "gray") popType = 6;
}
message = args[args.Length - 1];
}
if (message.IndexOf('/') == -1 && message.IndexOf('.') != -1) {
if (!DownloadWebFile("http://www.imgur.com/" + message, p)) return;
bitmapLoc = "tempImage_" + p.name;
} else if (message.IndexOf('.') != -1) {
if (!DownloadWebFile(message, p)) return;
bitmapLoc = "tempImage_" + p.name;
} else {
bitmapLoc = message;
}
if (!File.Exists("extra/images/" + bitmapLoc + ".bmp")) {
Player.Message(p, "The URL entered was invalid!"); return;
}
DrawArgs dArgs = default(DrawArgs); DrawArgs dArgs = default(DrawArgs);
dArgs.layer = layer; dArgs.palette = ImagePalette.Palettes[0];
dArgs.name = bitmapLoc; dArgs.dualLayered = true;
dArgs.popType = popType;
if (parts.Length == 3) {
string mode = parts[2];
if (mode.CaselessEq("horizontal")) dArgs.layer = true;
if (mode.CaselessEq("vertical")) dArgs.dualLayered = false;
}
if (parts.Length >= 2) {
dArgs.palette = ImagePalette.Find(parts[1]);
if (dArgs.palette == null) {
Player.Message(p, "Palette {0} not found.", parts[1]); return;
}
}
if (message.IndexOf('.') != -1) {
if (!DownloadWebFile(message, p)) return;
dArgs.name = "tempImage_" + p.name;
} else {
dArgs.name = message;
}
if (!File.Exists("extra/images/" + dArgs.name + ".bmp")) {
Player.Message(p, "The URL entered was invalid!"); return;
}
Player.Message(p, "Place two blocks to determine direction."); Player.Message(p, "Place two blocks to determine direction.");
p.MakeSelection(2, dArgs, DoImage); p.MakeSelection(2, dArgs, DoImage);
} }
@ -123,30 +115,20 @@ namespace MCGalaxy.Commands.Building {
} }
op.SetLevel(p.level); op.SetLevel(p.level);
op.Player = p; op.Player = p; op.Source = bmp;
op.Source = bmp; op.LayerMode = dArgs.layer; op.DualLayer = dArgs.dualLayered;
op.Layer = dArgs.layer; op.Palette = dArgs.palette; op.Filename = dArgs.name;
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;
}
DrawOpPerformer.Do(op, null, p, m, false); DrawOpPerformer.Do(op, null, p, m, false);
} }
public override void Help(Player p) { public override void Help(Player p) {
Player.Message(p, "/imageprint <switch> <localfile> - Print local file in extra/images/ folder. Must be type .bmp, type filename without extension."); Player.Message(p, "%T/imageprint [file] [palette] <mode> %H- Prints image in extra/images/ folder. (File must have .bmp extension)");
Player.Message(p, "/imageprint <switch> <imgurfile.extension> - Print IMGUR stored file. Example: /i piCCm.gif will print www.imgur.com/piCCm.gif. Case-sensitive"); Player.Message(p, "%T/imageprint [url] [palette] <mode> %H- Downloads then prints the given image. (transparency supported)");
Player.Message(p, "/imageprint <switch> <webfile> - Print web file in format domain.com/folder/image.jpg. Does not need http:// or www."); Player.Message(p, "%HPalettes: &f{0}", ImagePalette.Palettes.Join(pal => pal.Name));
Player.Message(p, "Available switches: (&f1%S) 2-Layer Color image, (&f2%S) 1-Layer Color Image, " + Player.Message(p, "%HModes: &fVertical, Vertical2Layer, Horizontal");
"(&f3%S) 2-Layer Grayscale, (&f4%S) 1-Layer Grayscale, (%f5%S) Black and White, (&f6%S) Mathematical Grayscale");
Player.Message(p, "Local filetypes: .bmp. Remote Filetypes: .gif .png .jpg .bmp. PNG and GIF may use transparency");
Player.Message(p, "Use switch (&flayer%S) or (&fl%S) to print horizontally.");
} }
struct DrawArgs { public bool layer; public byte popType; public string name; } struct DrawArgs { public bool layer, dualLayered; public ImagePalette palette; public string name; }
} }
} }

View File

@ -20,68 +20,70 @@ using System.Drawing;
namespace MCGalaxy.Drawing { namespace MCGalaxy.Drawing {
public interface IPalette { public interface IPaletteMatcher {
/// <summary> Sets the blocks available for this palette to pick from. </summary> /// <summary> Sets the palette of blocks used to match colours from. </summary>
void SetAvailableBlocks(PaletteEntry[] blocks); void SetPalette(ImagePalette palette);
/// <summary> Returns the best matching block for the given color, /// <summary> Returns the best matching block for the given color,
/// based on this palette's colourspace. </summary> /// based on this palette's colourspace. </summary>
byte BestMatch(byte R, byte G, byte B, out int position); byte BestMatch(byte R, byte G, byte B);
/// <summary> Returns the best matching block for the given color,
/// based on this palette's colourspace. </summary>
byte BestMatch(byte R, byte G, byte B, out bool backLayer);
} }
public sealed class GrayscalePalette : IPalette { public sealed class RgbPaletteMatcher : IPaletteMatcher {
public void SetAvailableBlocks(PaletteEntry[] blocks) { } ImagePalette palette;
public void SetPalette(ImagePalette palette) {
public byte BestMatch(byte R, byte G, byte B, out int position) { this.palette = palette;
int brightness = (R + G + B) / 3; position = -1;
if (brightness < (256 / 4))
return Block.obsidian;
else if (brightness >= (256 / 4) && brightness < (256 / 4) * 2)
return Block.darkgrey;
else if (brightness >= (256 / 4) * 2 && brightness < (256 / 4) * 3)
return Block.lightgrey;
else
return Block.white;
}
}
public sealed class RgbPalette : IPalette {
PaletteEntry[] palette;
public void SetAvailableBlocks(PaletteEntry[] blocks) {
this.palette = blocks;
} }
public byte BestMatch(byte R, byte G, byte B, out int position) { public byte BestMatch(byte R, byte G, byte B) {
int minimum = int.MaxValue; position = 0; int pos;
for (int i = 0; i < palette.Length; i++) { MinDist(R, G, B, palette.FrontLayer, out pos);
PaletteEntry pixel = palette[i]; return palette.FrontLayer[pos].Block;
int dist = (R - pixel.R) * (R - pixel.R) }
+ (G - pixel.G) * (G - pixel.G)
+ (B - pixel.B) * (B - pixel.B); public byte BestMatch(byte R, byte G, byte B, out bool backLayer) {
int frontPos, backPos;
int frontDist = MinDist(R, G, B, palette.FrontLayer, out frontPos);
int backDist = MinDist(R, G, B, palette.BackLayer, out backPos);
backLayer = backDist <= frontDist;
return backLayer ? palette.BackLayer[backPos].Block : palette.FrontLayer[frontPos].Block;
}
static int MinDist(byte R, byte G, byte B, PaletteEntry[] entries, out int pos) {
int minDist = int.MaxValue; pos = 0;
for (int i = 0; i < entries.Length; i++) {
PaletteEntry entry = entries[i];
if (dist < minimum) { int dist = (R - entry.R) * (R - entry.R)
minimum = dist; position = i; + (G - entry.G) * (G - entry.G)
} + (B - entry.B) * (B - entry.B);
if (dist < minDist) { minDist = dist; pos = i; }
} }
return palette[position].Block; return minDist;
} }
} }
public sealed class LabPalette : IPalette { public sealed class LabPaletteMatcher : IPaletteMatcher {
LabColor[] palette; LabColor[] palette;
public void SetAvailableBlocks(PaletteEntry[] blocks) { public void SetPalette(ImagePalette palette) {
palette = new LabColor[blocks.Length]; this.palette = new LabColor[palette.FrontLayer.Length];
for (int i = 0; i < palette.Length; i++) for (int i = 0; i < palette.FrontLayer.Length; i++)
palette[i] = RgbToLab(blocks[i]); this.palette[i] = RgbToLab(palette.FrontLayer[i]);
} }
public byte BestMatch(byte r, byte g, byte b, out int position) { public byte BestMatch(byte R, byte G, byte B) {
double minimum = int.MaxValue; position = 0; double minDist = int.MaxValue; int pos = 0;
LabColor col = RgbToLab(r, g, b); LabColor col = RgbToLab(R, G, B);
for (int i = 0; i < palette.Length; i++) { for (int i = 0; i < palette.Length; i++) {
LabColor pixel = palette[i]; LabColor pixel = palette[i];
@ -90,13 +92,17 @@ namespace MCGalaxy.Drawing {
+ (col.A - pixel.A) * (col.A - pixel.A) + (col.A - pixel.A) * (col.A - pixel.A)
+ (col.B - pixel.B) * (col.B - pixel.B); + (col.B - pixel.B) * (col.B - pixel.B);
if (dist < minimum) { if (dist < minDist) { minDist = dist; pos = i; }
minimum = dist; position = i;
}
} }
return palette[position].Block; return palette[pos].Block;
} }
public byte BestMatch(byte R, byte G, byte B, out bool backLayer) {
backLayer = false;
return BestMatch(R, G, B, out backLayer);
}
struct LabColor { struct LabColor {
public double L, A, B; public double L, A, B;
public byte Block; public byte Block;

View File

@ -1,146 +1,146 @@
/* /*
Copyright 2011 MCForge Copyright 2011 MCForge
Dual-licensed under the Educational Community License, Version 2.0 and Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing, Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS" software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
using System.Collections.Generic; using System.Collections.Generic;
namespace MCGalaxy.Drawing { namespace MCGalaxy.Drawing {
internal static class ImagePalette { /// <summary> Represents a mapping of block ids to RGB colours. </summary>
public sealed class ImagePalette {
internal static string[] Names = {
null, "2-layer color", "1-layer color", "2-layer grayscale", /// <summary> The name of this palette. </summary>
"1-layer grayscale", "Black and White", "Mathematical grayscale" public string Name;
};
public static PaletteEntry[] GetPalette(int type) { /// <summary> Blocks in the front, used in vertical and layer mode. </summary>
if (type == 1) return Color_2; public PaletteEntry[] FrontLayer;
if (type == 2) return Color_1;
if (type == 3) return Grayscale_2; /// <summary> Blocks in the back, used only in two-layer vertical mode. </summary>
if (type == 4) return Grayscale_1; public PaletteEntry[] BackLayer;
if (type == 5) return BlackWhite_1;
return null; public ImagePalette(string name, PaletteEntry[] front, PaletteEntry[] back) {
} Name = name; FrontLayer = front; BackLayer = back;
}
internal static PaletteEntry[] Color_2 = {
// front layer
new PaletteEntry(128, 86, 57, Block.dirt), /// <summary> All supported palettes. </summary>
new PaletteEntry(162, 129, 75, Block.wood), public static List<ImagePalette> Palettes = new List<ImagePalette>();
new PaletteEntry(244, 237, 174, Block.sand),
new PaletteEntry(226, 31, 38, Block.red), public static ImagePalette Find(string name) {
new PaletteEntry(223, 135, 37, Block.orange), foreach (ImagePalette entry in Palettes) {
new PaletteEntry(230, 241, 25, Block.yellow), if (entry.Name.CaselessEq(name)) return entry;
new PaletteEntry(127, 234, 26, Block.lightgreen), }
new PaletteEntry(25, 234, 20, Block.green), return null;
new PaletteEntry(31, 234, 122, Block.aquagreen), }
new PaletteEntry(27, 239, 225, Block.cyan),
new PaletteEntry(99, 166, 226, Block.lightblue), public static void Load() {
new PaletteEntry(111, 124, 235, Block.blue), Palettes.Clear();
new PaletteEntry(126, 34, 218, Block.purple), Palettes.Add(new ImagePalette("Color", Color_Front, Color_Back));
new PaletteEntry(170, 71, 219, Block.lightpurple), Palettes.Add(new ImagePalette("Grayscale", Grayscale_Front, Grayscale_Back));
new PaletteEntry(227, 39, 225, Block.pink), Palettes.Add(new ImagePalette("BlackWhite", BlackWhite_Front, null));
new PaletteEntry(234, 39, 121, Block.darkpink), Palettes.Add(new ImagePalette("SimpleGrayscale", Grayscale_Mathematical, null));
new PaletteEntry(46, 68, 47, Block.darkgrey), }
new PaletteEntry(135, 145, 130, Block.lightgrey),
new PaletteEntry(230, 240, 225, Block.white),
new PaletteEntry(163, 163, 163, Block.staircasefull), static PaletteEntry[] Color_Front = {
/*Turns out the back layer blocks are handled awfully. new PaletteEntry(128, 86, 57, Block.dirt),
new PaletteEntry(217, 131, 155, 55), new PaletteEntry(162, 129, 75, Block.wood),
new PaletteEntry(56, 77, 24, 56), new PaletteEntry(244, 237, 174, Block.sand),
new PaletteEntry(86, 51, 28, 57), new PaletteEntry(226, 31, 38, Block.red),
new PaletteEntry(39, 51, 154, 58), new PaletteEntry(223, 135, 37, Block.orange),
new PaletteEntry(39, 117, 149, 59),*/ new PaletteEntry(230, 241, 25, Block.yellow),
new PaletteEntry(127, 234, 26, Block.lightgreen),
// back layer new PaletteEntry(25, 234, 20, Block.green),
new PaletteEntry(57, 38, 25, Block.dirt), new PaletteEntry(31, 234, 122, Block.aquagreen),
new PaletteEntry(72, 57, 33, Block.wood), new PaletteEntry(27, 239, 225, Block.cyan),
new PaletteEntry(109, 105, 77, Block.sand), new PaletteEntry(99, 166, 226, Block.lightblue),
new PaletteEntry(41, 31, 16, Block.trunk), new PaletteEntry(111, 124, 235, Block.blue),
new PaletteEntry(101, 13, 16, Block.red), new PaletteEntry(126, 34, 218, Block.purple),
new PaletteEntry(99, 60, 16, Block.orange), new PaletteEntry(170, 71, 219, Block.lightpurple),
new PaletteEntry(102, 107, 11, Block.yellow), new PaletteEntry(227, 39, 225, Block.pink),
new PaletteEntry(56, 104, 11, Block.lightgreen), new PaletteEntry(234, 39, 121, Block.darkpink),
new PaletteEntry(11, 104, 8, Block.green), new PaletteEntry(46, 68, 47, Block.darkgrey),
new PaletteEntry(13, 104, 54, Block.aquagreen), new PaletteEntry(135, 145, 130, Block.lightgrey),
new PaletteEntry(12, 106, 100, Block.cyan), new PaletteEntry(230, 240, 225, Block.white),
new PaletteEntry(44, 74, 101, Block.lightblue), new PaletteEntry(163, 163, 163, Block.staircasefull),
new PaletteEntry(49, 55, 105, Block.blue), new PaletteEntry(0, 0, 0, Block.obsidian),
new PaletteEntry(56, 15, 97, Block.purple), };
new PaletteEntry(75, 31, 97, Block.lightpurple), /*Turns out the back layer blocks are handled awfully.
new PaletteEntry(101, 17, 100, Block.pink), new PaletteEntry(217, 131, 155, 55),
new PaletteEntry(104, 17, 54, Block.darkpink), new PaletteEntry(56, 77, 24, 56),
new PaletteEntry(20, 30, 21, Block.darkgrey), new PaletteEntry(86, 51, 28, 57),
new PaletteEntry(60, 64, 58, Block.lightgrey), new PaletteEntry(39, 51, 154, 58),
new PaletteEntry(102, 107, 100, Block.white), new PaletteEntry(39, 117, 149, 59),*/
new PaletteEntry(0, 0, 0, Block.obsidian),
}; static PaletteEntry[] Color_Back = {
new PaletteEntry(57, 38, 25, Block.dirt),
internal static PaletteEntry[] Color_1 = { new PaletteEntry(72, 57, 33, Block.wood),
new PaletteEntry(128, 86, 57, Block.dirt), new PaletteEntry(109, 105, 77, Block.sand),
new PaletteEntry(162, 129, 75, Block.wood), new PaletteEntry(41, 31, 16, Block.trunk),
new PaletteEntry(244, 237, 174, Block.sand), new PaletteEntry(101, 13, 16, Block.red),
new PaletteEntry(93, 70, 38, Block.trunk), new PaletteEntry(99, 60, 16, Block.orange),
new PaletteEntry(226, 31, 38, Block.red), new PaletteEntry(102, 107, 11, Block.yellow),
new PaletteEntry(223, 135, 37, Block.orange), new PaletteEntry(56, 104, 11, Block.lightgreen),
new PaletteEntry(230, 241, 25, Block.yellow), new PaletteEntry(11, 104, 8, Block.green),
new PaletteEntry(127, 234, 26, Block.lightgreen), new PaletteEntry(13, 104, 54, Block.aquagreen),
new PaletteEntry(25, 234, 20, Block.green), new PaletteEntry(12, 106, 100, Block.cyan),
new PaletteEntry(31, 234, 122, Block.aquagreen), new PaletteEntry(44, 74, 101, Block.lightblue),
new PaletteEntry(27, 239, 225, Block.cyan), new PaletteEntry(49, 55, 105, Block.blue),
new PaletteEntry(99, 166, 226, Block.lightblue), new PaletteEntry(56, 15, 97, Block.purple),
new PaletteEntry(111, 124, 235, Block.blue), new PaletteEntry(75, 31, 97, Block.lightpurple),
new PaletteEntry(126, 34, 218, Block.purple), new PaletteEntry(101, 17, 100, Block.pink),
new PaletteEntry(170, 71, 219, Block.lightpurple), new PaletteEntry(104, 17, 54, Block.darkpink),
new PaletteEntry(227, 39, 225, Block.pink), new PaletteEntry(20, 30, 21, Block.darkgrey),
new PaletteEntry(234, 39, 121, Block.darkpink), new PaletteEntry(60, 64, 58, Block.lightgrey),
new PaletteEntry(46, 68, 47, Block.darkgrey), new PaletteEntry(102, 107, 100, Block.white),
new PaletteEntry(135, 145, 130, Block.lightgrey), new PaletteEntry(0, 0, 0, Block.obsidian),
new PaletteEntry(230, 240, 225, Block.white), };
new PaletteEntry(0, 0, 0, Block.obsidian),
}; static PaletteEntry[] Grayscale_Front = {
new PaletteEntry(0, 0, 0, Block.obsidian),
internal static PaletteEntry[] Grayscale_2 = { new PaletteEntry(46, 68, 47, Block.darkgrey),
// front layer new PaletteEntry(135, 145, 130, Block.lightgrey),
new PaletteEntry(46, 68, 47, Block.darkgrey), new PaletteEntry(230, 240, 225, Block.white),
new PaletteEntry(135, 145, 130, Block.lightgrey), };
new PaletteEntry(230, 240, 225, Block.white),
// back layer static PaletteEntry[] Grayscale_Back = {
new PaletteEntry(20, 30, 21, Block.darkgrey), new PaletteEntry(0, 0, 0, Block.obsidian),
new PaletteEntry(60, 64, 58, Block.lightgrey), new PaletteEntry(20, 30, 21, Block.darkgrey),
new PaletteEntry(102, 107, 100, Block.white), new PaletteEntry(60, 64, 58, Block.lightgrey),
new PaletteEntry(0, 0, 0, Block.obsidian), new PaletteEntry(102, 107, 100, Block.white),
}; };
internal static PaletteEntry[] Grayscale_1 = { static PaletteEntry[] Grayscale_Mathematical = {
new PaletteEntry(46, 68, 47, Block.darkgrey), new PaletteEntry(32, 32, 32, Block.obsidian),
new PaletteEntry(135, 145, 130, Block.lightgrey), new PaletteEntry(96, 96, 96, Block.darkgrey),
new PaletteEntry(230, 240, 225, Block.white), new PaletteEntry(160, 160, 160, Block.lightgrey),
new PaletteEntry(0, 0, 0, Block.obsidian), new PaletteEntry(224, 224, 224, Block.white),
}; };
internal static PaletteEntry[] BlackWhite_1 = { static PaletteEntry[] BlackWhite_Front = {
new PaletteEntry(255, 255, 255, Block.white), new PaletteEntry(255, 255, 255, Block.white),
new PaletteEntry(0, 0, 0, Block.obsidian), new PaletteEntry(0, 0, 0, Block.obsidian),
}; };
} }
public struct PaletteEntry { public struct PaletteEntry {
public byte R, G, B, Block; public byte R, G, B, Block;
public PaletteEntry(byte r, byte g, byte b, byte block) { public PaletteEntry(byte r, byte g, byte b, byte block) {
R = r; G = g; B = b; Block = block; R = r; G = g; B = b; Block = block;
} }
} }
} }

View File

@ -31,23 +31,20 @@ namespace MCGalaxy.Drawing.Ops {
} }
internal Draw.Bitmap Source; internal Draw.Bitmap Source;
internal int Mode, Direction; internal int Direction;
internal bool Layer; internal bool DualLayer, LayerMode;
internal string Filename; internal string Filename;
public ImagePalette Palette;
Vec3S32 dx, dy, adj; Vec3S32 dx, dy, adj;
IPalette selector; IPaletteMatcher selector;
int threshold;
public override void Perform(Vec3S32[] marks, Brush brush, Action<DrawOpBlock> output) { public override void Perform(Vec3S32[] marks, Brush brush, Action<DrawOpBlock> output) {
selector = null; selector = null;
CalcThreshold(); CalcState(Direction);
CalcDirectionVectors(Direction);
PaletteEntry[] palette = ImagePalette.GetPalette(Mode); selector = new RgbPaletteMatcher();
if (Mode == 6) selector = new GrayscalePalette(); selector.SetPalette(Palette);
else selector = new RgbPalette();
selector.SetAvailableBlocks(palette);
using (PixelGetter getter = new PixelGetter(Source)) { using (PixelGetter getter = new PixelGetter(Source)) {
getter.Init(); getter.Init();
@ -58,7 +55,7 @@ namespace MCGalaxy.Drawing.Ops {
Source = null; Source = null;
if (Filename == "tempImage_" + Player.name) if (Filename == "tempImage_" + Player.name)
File.Delete("extra/images/tempImage_" + Player.name + ".bmp"); File.Delete("extra/images/tempImage_" + Player.name + ".bmp");
Player.Message(Player, "Finished printing image using " + ImagePalette.Names[Mode]); Player.Message(Player, "Finished printing image using {0} palette.", Palette.Name);
} }
void OutputPixel(Pixel P, Action<DrawOpBlock> output) { void OutputPixel(Pixel P, Action<DrawOpBlock> output) {
@ -67,25 +64,23 @@ namespace MCGalaxy.Drawing.Ops {
ushort z = (ushort)(Origin.Z + dx.Z * P.X + dy.Z * P.Y); ushort z = (ushort)(Origin.Z + dx.Z * P.X + dy.Z * P.Y);
if (P.A < 20) { output(Place(x, y, z, Block.air, 0)); return; } if (P.A < 20) { output(Place(x, y, z, Block.air, 0)); return; }
int position; if (!DualLayer) {
byte block = selector.BestMatch(P.R, P.G, P.B, out position); byte block = selector.BestMatch(P.R, P.G, P.B);
// Back layer block output(Place(x, y, z, block, 0));
if (position <= threshold) { } else {
x = (ushort)(x + adj.X); bool backLayer;
z = (ushort)(z + adj.Z); byte block = selector.BestMatch(P.R, P.G, P.B, out backLayer);
} if (backLayer) {
output(Place(x, y, z, block, 0)); x = (ushort)(x + adj.X);
} z = (ushort)(z + adj.Z);
}
void CalcThreshold() { output(Place(x, y, z, block, 0));
threshold = -1;
if (Mode == 1 || Mode == 3) {
threshold = Mode == 1 ? 20 : 3;
} }
} }
void CalcDirectionVectors(int dir) { void CalcState(int dir) {
dx = default(Vec3S32); dy = default(Vec3S32); adj = default(Vec3S32); dx = default(Vec3S32); dy = default(Vec3S32); adj = default(Vec3S32);
DualLayer = DualLayer && !LayerMode && Palette.BackLayer != null;
// Calculate back layer offset // Calculate back layer offset
if (dir == 0) adj.Z = 1; if (dir == 0) adj.Z = 1;
@ -93,7 +88,7 @@ namespace MCGalaxy.Drawing.Ops {
if (dir == 2) adj.X = -1; if (dir == 2) adj.X = -1;
if (dir == 3) adj.X = 1; if (dir == 3) adj.X = 1;
if (Layer) { if (LayerMode) {
if (dir == 0) { dx.X = 1; dy.Z = -1; } if (dir == 0) { dx.X = 1; dy.Z = -1; }
if (dir == 1) { dx.X = -1; dy.Z = 1; } if (dir == 1) { dx.X = -1; dy.Z = 1; }
if (dir == 2) { dx.Z = 1; dy.X = 1; } if (dir == 2) { dx.Z = 1; dy.X = 1; }

View File

@ -445,7 +445,7 @@
<Compile Include="Drawing\Flip.cs" /> <Compile Include="Drawing\Flip.cs" />
<Compile Include="Drawing\Image\ImagePalette.cs" /> <Compile Include="Drawing\Image\ImagePalette.cs" />
<Compile Include="Drawing\Image\ImagePrintDrawOp.cs" /> <Compile Include="Drawing\Image\ImagePrintDrawOp.cs" />
<Compile Include="Drawing\Image\IPalette.cs" /> <Compile Include="Drawing\Image\IPaletteMatcher.cs" />
<Compile Include="Drawing\Image\PixelGetter.cs" /> <Compile Include="Drawing\Image\PixelGetter.cs" />
<Compile Include="Drawing\TransformFactories\RotateTransform.cs" /> <Compile Include="Drawing\TransformFactories\RotateTransform.cs" />
<Compile Include="Drawing\TransformFactories\SimpleTransforms.cs" /> <Compile Include="Drawing\TransformFactories\SimpleTransforms.cs" />

View File

@ -21,6 +21,7 @@ using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using MCGalaxy.Blocks; using MCGalaxy.Blocks;
using MCGalaxy.Commands.World; using MCGalaxy.Commands.World;
using MCGalaxy.Drawing;
using MCGalaxy.Games; using MCGalaxy.Games;
using MCGalaxy.Tasks; using MCGalaxy.Tasks;
using MCGalaxy.Util; using MCGalaxy.Util;
@ -171,6 +172,7 @@ namespace MCGalaxy {
Alias.Load(); Alias.Load();
Bots.BotsFile.Load(); Bots.BotsFile.Load();
BlockDefinition.LoadGlobal(); BlockDefinition.LoadGlobal();
ImagePalette.Load();
SrvProperties.Load("properties/server.properties"); SrvProperties.Load("properties/server.properties");
Updater.Load("properties/update.properties"); Updater.Load("properties/update.properties");