diff --git a/Commands/building/CmdWrite.cs b/Commands/building/CmdWrite.cs index 6e2154b26..67f6d58c9 100644 --- a/Commands/building/CmdWrite.cs +++ b/Commands/building/CmdWrite.cs @@ -17,6 +17,8 @@ */ using System; using MCGalaxy.Drawing; +using MCGalaxy.Drawing.Brushes; +using MCGalaxy.Drawing.Ops; namespace MCGalaxy.Commands { @@ -53,35 +55,27 @@ namespace MCGalaxy.Commands { p.Blockchange += new Player.BlockchangeEventHandler(Blockchange1); } - public void Blockchange1(Player p, ushort x, ushort y, ushort z, byte type, byte extType) { + void Blockchange1(Player p, ushort x, ushort y, ushort z, byte type, byte extType) { RevertAndClearState(p, x, y, z); CatchPos bp = (CatchPos)p.blockchangeObject; bp.x = x; bp.y = y; bp.z = z; p.blockchangeObject = bp; p.Blockchange += new Player.BlockchangeEventHandler(Blockchange2); } - public void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) { + void Blockchange2(Player p, ushort x, ushort y, ushort z, byte type, byte extType) { type = type < 128 ? p.bindings[type] : type; RevertAndClearState(p, x, y, z); CatchPos cpos = (CatchPos)p.blockchangeObject; Level lvl = p.level; - if (x == cpos.x && z == cpos.z) { Player.SendMessage(p, "No direction was selected"); return; } + + WriteDrawOp op = new WriteDrawOp(); + op.Text = cpos.givenMessage; + op.Scale = cpos.scale; op.Spacing = cpos.spacing; + Brush brush = new SolidBrush(type, extType); + if (!DrawOp.DoDrawOp(op, brush, p, cpos.x, cpos.y, cpos.z, x, y, z)) + return; - int dir = 0; - if (Math.Abs(cpos.x - x) > Math.Abs(cpos.z - z)) - dir = x > cpos.x ? 0 : 1; - else - dir = z > cpos.z ? 2 : 3; - - int count = BlockWriter.CountBlocks(cpos.givenMessage, cpos.scale); - if (count > p.group.maxBlocks) { - Player.SendMessage(p, "You cannot affect more than " + p.group.maxBlocks + " blocks."); return; - } - - foreach (char c in cpos.givenMessage) - BlockWriter.DrawLetter(lvl, p, c, ref cpos.x, cpos.y, ref cpos.z, - type, extType, dir, cpos.scale, cpos.spacing); if (p.staticCommands) p.Blockchange += new Player.BlockchangeEventHandler(Blockchange1); } diff --git a/Drawing/BlockWriter.cs b/Drawing/DrawOps/WriteDrawOp.cs similarity index 76% rename from Drawing/BlockWriter.cs rename to Drawing/DrawOps/WriteDrawOp.cs index a1b1f43c0..367e8c84b 100644 --- a/Drawing/BlockWriter.cs +++ b/Drawing/DrawOps/WriteDrawOp.cs @@ -1,152 +1,170 @@ -/* - Copyright 2011 MCForge - - Dual-licensed under the Educational Community License, Version 2.0 and - the GNU General Public License, Version 3 (the "Licenses"); you may - not use this file except in compliance with the Licenses. You may - obtain a copy of the Licenses at - - http://www.opensource.org/licenses/ecl2.php - http://www.gnu.org/licenses/gpl-3.0.html - - Unless required by applicable law or agreed to in writing, - software distributed under the Licenses are distributed on an "AS IS" - BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express - or implied. See the Licenses for the specific language governing - permissions and limitations under the Licenses. - */ -using System.Collections.Generic; - -namespace MCGalaxy.Drawing { - - internal static class BlockWriter { - - public static int CountBlocks(string s, byte scale) { - int blocks = 0; - foreach (char c in s) { - if ((int)c >= 256 || letters[(int)c] == null) { - blocks += (4 * scale) * (4 * scale); - } else { - byte[] flags = letters[(int)c]; - for (int i = 0; i < flags.Length; i++) - blocks += scale * scale * HighestBit(flags[i]); - } - } - return blocks; - } - - public static void DrawLetter(Level l, Player p, char c, ref ushort x, ushort y, ref ushort z, - byte type, byte extType, int dir, byte scale, byte spacing) { - int dirX = dir == 0 ? 1 : dir == 1 ? -1 : 0; - int dirZ = dir == 2 ? 1 : dir == 3 ? -1 : 0; - if ((int)c >= 256 || letters[(int)c] == null) { - Player.SendMessage(p, "\"" + c + "\" is not currently supported, replacing with space."); - x = (ushort)(x + dirX * 4 * scale); - z = (ushort)(z + dirZ * 4 * scale); - } else { - byte[] flags = letters[(int)c]; - for (int i = 0; i < flags.Length; i++) { - byte yUsed = flags[i]; - for (int j = 0; j < 8; j++) { - if ((yUsed & (1 << j)) == 0) continue; - - for (int ver = 0; ver < scale; ver++) - for (int hor = 0; hor < scale; hor++) { - int xx = x + dirX * hor, yy = y + j * scale + ver, zz = z + dirZ * hor; - l.UpdateBlock(p, (ushort)xx, (ushort)yy, (ushort)zz, type, extType); - } - } - x = (ushort)(x + dirX * scale); - z = (ushort)(z + dirZ * scale); - } - } - x = (ushort)(x + dirX * spacing); - z = (ushort)(z + dirZ * spacing); - } - - static int HighestBit(int value) { - int bits = 0; - while (value > 0) { - value >>= 1; bits++; - } - return bits; - } - - static byte[][] letters; - static BlockWriter() { - letters = new byte[256][]; - // each set bit indicates to place a block with a y offset equal to the bit index. - // e.g. for 0x3, indicates to place a block at 'y = 0' and 'y = 1' - letters['A'] = new byte[] { 0x0F, 0x14, 0x0F }; - letters['B'] = new byte[] { 0x1F, 0x15, 0x0A }; - letters['C'] = new byte[] { 0x0E, 0x11, 0x11 }; - letters['D'] = new byte[] { 0x1F, 0x11, 0x0E }; - letters['E'] = new byte[] { 0x1F, 0x15, 0x15 }; - letters['F'] = new byte[] { 0x1F, 0x14, 0x14 }; - letters['G'] = new byte[] { 0x0E, 0x11, 0x17 }; - letters['H'] = new byte[] { 0x1F, 0x04, 0x1F }; - letters['I'] = new byte[] { 0x11, 0x1F, 0x11 }; - letters['J'] = new byte[] { 0x11, 0x11, 0x1E }; - letters['K'] = new byte[] { 0x1F, 0x04, 0x1B }; - letters['L'] = new byte[] { 0x1F, 0x01, 0x01 }; - letters['M'] = new byte[] { 0x1F, 0x08, 0x04, 0x08, 0x1F }; - letters['N'] = new byte[] { 0x1F, 0x08, 0x04, 0x02, 0x1F }; - letters['O'] = new byte[] { 0x0E, 0x11, 0x0E }; - letters['P'] = new byte[] { 0x1F, 0x14, 0x08 }; - letters['Q'] = new byte[] { 0x0E, 0x11, 0x13, 0x0F }; - letters['R'] = new byte[] { 0x1F, 0x14, 0x0B }; - letters['S'] = new byte[] { 0x09, 0x15, 0x12 }; - letters['T'] = new byte[] { 0x10, 0x1F, 0x10 }; - letters['U'] = new byte[] { 0x1E, 0x01, 0x1E }; - letters['V'] = new byte[] { 0x18, 0x06, 0x01, 0x06, 0x18 }; - letters['W'] = new byte[] { 0x1F, 0x02, 0x04, 0x02, 0x1F }; - letters['X'] = new byte[] { 0x1B, 0x04, 0x1B }; - letters['Y'] = new byte[] { 0x10, 0x08, 0x07, 0x08, 0x10 }; - letters['Z'] = new byte[] { 0x11, 0x13, 0x15, 0x19, 0x11 }; - letters['0'] = new byte[] { 0x0E, 0x13, 0x15, 0x19, 0x0E }; - letters['1'] = new byte[] { 0x09, 0x1F, 0x01 }; - letters['2'] = new byte[] { 0x17, 0x15, 0x1D }; - letters['3'] = new byte[] { 0x15, 0x15, 0x1F }; - letters['4'] = new byte[] { 0x1E, 0x02, 0x07, 0x02 }; - letters['5'] = new byte[] { 0x1D, 0x15, 0x17 }; - letters['6'] = new byte[] { 0x1F, 0x15, 0x17 }; - letters['7'] = new byte[] { 0x10, 0x10, 0x1F }; - letters['8'] = new byte[] { 0x1F, 0x15, 0x1F }; - letters['9'] = new byte[] { 0x1D, 0x15, 0x1F }; - - letters[' '] = new byte[] { 0x00 }; - letters['!'] = new byte[] { 0x1D }; - letters['"'] = new byte[] { 0x18, 0x00, 0x18 }; - // # is missing - // $ is missing - // % is missing - // & is missing - letters['\''] = new byte[] { 0x18 }; - letters['('] = new byte[] { 0x0E, 0x11 }; - letters[')'] = new byte[] { 0x11, 0x0E }; - // * is missing - letters['+'] = new byte[] { 0x04, 0x0E, 0x04 }; - letters[','] = new byte[] { 0x01, 0x03 }; - letters['-'] = new byte[] { 0x04, 0x04, 0x04 }; - letters['.'] = new byte[] { 0x01 }; - letters['/'] = new byte[] { 0x01, 0x02, 0x04, 0x08, 0x10 }; - letters[':'] = new byte[] { 0x0A }; - letters[';'] = new byte[] { 0x10, 0x0A }; - letters['\\'] = new byte[] { 0x10, 0x08, 0x04, 0x02, 0x01 }; - letters['<'] = new byte[] { 0x04, 0x0A, 0x11 }; - letters['='] = new byte[] { 0x0A, 0x0A, 0x0A }; - letters['>'] = new byte[] { 0x11, 0x0A, 0x04 }; - // '?' is missing - // '@' is missing - letters['['] = new byte[] { 0x1F, 0x11 }; - letters['\''] = new byte[] { 0x18 }; - letters[']'] = new byte[] { 0x11, 0x1F }; - letters['_'] = new byte[] { 0x01, 0x01, 0x01, 0x01 }; - letters['`'] = new byte[] { 0x10, 0x08 }; - letters['{'] = new byte[] { 0x04, 0x1B, 0x11 }; - letters['|'] = new byte[] { 0x1F }; - letters['}'] = new byte[] { 0x11, 0x1B, 0x04 }; - letters['~'] = new byte[] { 0x04, 0x08, 0x04, 0x08 }; - } - } -} +/* + Copyright 2011 MCForge + + Dual-licensed under the Educational Community License, Version 2.0 and + the GNU General Public License, Version 3 (the "Licenses"); you may + not use this file except in compliance with the Licenses. You may + obtain a copy of the Licenses at + + http://www.opensource.org/licenses/ecl2.php + http://www.gnu.org/licenses/gpl-3.0.html + + Unless required by applicable law or agreed to in writing, + software distributed under the Licenses are distributed on an "AS IS" + BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the Licenses for the specific language governing + permissions and limitations under the Licenses. + */ +using System; +using System.Collections.Generic; +using MCGalaxy.Drawing.Brushes; + +namespace MCGalaxy.Drawing.Ops { + + public class WriteDrawOp : DrawOp { + + public string Text; + public byte Scale, Spacing; + + public override string Name { get { return "Write"; } } + + 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) { + int blocks = 0; + foreach (char c in Text) { + if ((int)c >= 256 || letters[(int)c] == null) { + blocks += (4 * Scale) * (4 * Scale); + } else { + byte[] flags = letters[(int)c]; + for (int i = 0; i < flags.Length; i++) + blocks += Scale * Scale * HighestBit(flags[i]); + } + } + return blocks; + } + + 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; + else + dirZ = z2 > z1 ? 1 : -1; + foreach (char c in Text) + DrawLetter(p, lvl, c, ref x1, y1, ref z1, brush); + } + + void DrawLetter(Player p, Level lvl, char c, ref ushort x, ushort y, ref ushort z, Brush brush) { + if ((int)c >= 256 || letters[(int)c] == null) { + Player.SendMessage(p, "\"" + c + "\" is not currently supported, replacing with space."); + x = (ushort)(x + dirX * 4 * Scale); + z = (ushort)(z + dirZ * 4 * Scale); + } else { + byte[] flags = letters[(int)c]; + for (int i = 0; i < flags.Length; i++) { + byte yUsed = flags[i]; + for (int j = 0; j < 8; j++) { + if ((yUsed & (1 << j)) == 0) continue; + + for (int ver = 0; ver < Scale; ver++) + for (int hor = 0; hor < Scale; hor++) + { + int xx = x + dirX * hor, yy = y + j * Scale + ver, zz = z + dirZ * hor; + PlaceBlock(p, lvl, (ushort)xx, (ushort)yy, (ushort)zz, brush); + } + } + x = (ushort)(x + dirX * Scale); + z = (ushort)(z + dirZ * Scale); + } + } + x = (ushort)(x + dirX * Spacing); + z = (ushort)(z + dirZ * Spacing); + } + + static int HighestBit(int value) { + int bits = 0; + while (value > 0) { + value >>= 1; bits++; + } + return bits; + } + + static byte[][] letters; + static WriteDrawOp() { + letters = new byte[256][]; + // each set bit indicates to place a block with a y offset equal to the bit index. + // e.g. for 0x3, indicates to place a block at 'y = 0' and 'y = 1' + letters['A'] = new byte[] { 0x0F, 0x14, 0x0F }; + letters['B'] = new byte[] { 0x1F, 0x15, 0x0A }; + letters['C'] = new byte[] { 0x0E, 0x11, 0x11 }; + letters['D'] = new byte[] { 0x1F, 0x11, 0x0E }; + letters['E'] = new byte[] { 0x1F, 0x15, 0x15 }; + letters['F'] = new byte[] { 0x1F, 0x14, 0x14 }; + letters['G'] = new byte[] { 0x0E, 0x11, 0x17 }; + letters['H'] = new byte[] { 0x1F, 0x04, 0x1F }; + letters['I'] = new byte[] { 0x11, 0x1F, 0x11 }; + letters['J'] = new byte[] { 0x11, 0x11, 0x1E }; + letters['K'] = new byte[] { 0x1F, 0x04, 0x1B }; + letters['L'] = new byte[] { 0x1F, 0x01, 0x01 }; + letters['M'] = new byte[] { 0x1F, 0x08, 0x04, 0x08, 0x1F }; + letters['N'] = new byte[] { 0x1F, 0x08, 0x04, 0x02, 0x1F }; + letters['O'] = new byte[] { 0x0E, 0x11, 0x0E }; + letters['P'] = new byte[] { 0x1F, 0x14, 0x08 }; + letters['Q'] = new byte[] { 0x0E, 0x11, 0x13, 0x0F }; + letters['R'] = new byte[] { 0x1F, 0x14, 0x0B }; + letters['S'] = new byte[] { 0x09, 0x15, 0x12 }; + letters['T'] = new byte[] { 0x10, 0x1F, 0x10 }; + letters['U'] = new byte[] { 0x1E, 0x01, 0x1E }; + letters['V'] = new byte[] { 0x18, 0x06, 0x01, 0x06, 0x18 }; + letters['W'] = new byte[] { 0x1F, 0x02, 0x04, 0x02, 0x1F }; + letters['X'] = new byte[] { 0x1B, 0x04, 0x1B }; + letters['Y'] = new byte[] { 0x10, 0x08, 0x07, 0x08, 0x10 }; + letters['Z'] = new byte[] { 0x11, 0x13, 0x15, 0x19, 0x11 }; + letters['0'] = new byte[] { 0x0E, 0x13, 0x15, 0x19, 0x0E }; + letters['1'] = new byte[] { 0x09, 0x1F, 0x01 }; + letters['2'] = new byte[] { 0x17, 0x15, 0x1D }; + letters['3'] = new byte[] { 0x15, 0x15, 0x1F }; + letters['4'] = new byte[] { 0x1E, 0x02, 0x07, 0x02 }; + letters['5'] = new byte[] { 0x1D, 0x15, 0x17 }; + letters['6'] = new byte[] { 0x1F, 0x15, 0x17 }; + letters['7'] = new byte[] { 0x10, 0x10, 0x1F }; + letters['8'] = new byte[] { 0x1F, 0x15, 0x1F }; + letters['9'] = new byte[] { 0x1D, 0x15, 0x1F }; + + letters[' '] = new byte[] { 0x00 }; + letters['!'] = new byte[] { 0x1D }; + letters['"'] = new byte[] { 0x18, 0x00, 0x18 }; + // # is missing + // $ is missing + // % is missing + // & is missing + letters['\''] = new byte[] { 0x18 }; + letters['('] = new byte[] { 0x0E, 0x11 }; + letters[')'] = new byte[] { 0x11, 0x0E }; + // * is missing + letters['+'] = new byte[] { 0x04, 0x0E, 0x04 }; + letters[','] = new byte[] { 0x01, 0x03 }; + letters['-'] = new byte[] { 0x04, 0x04, 0x04 }; + letters['.'] = new byte[] { 0x01 }; + letters['/'] = new byte[] { 0x01, 0x02, 0x04, 0x08, 0x10 }; + letters[':'] = new byte[] { 0x0A }; + letters[';'] = new byte[] { 0x10, 0x0A }; + letters['\\'] = new byte[] { 0x10, 0x08, 0x04, 0x02, 0x01 }; + letters['<'] = new byte[] { 0x04, 0x0A, 0x11 }; + letters['='] = new byte[] { 0x0A, 0x0A, 0x0A }; + letters['>'] = new byte[] { 0x11, 0x0A, 0x04 }; + // '?' is missing + // '@' is missing + letters['['] = new byte[] { 0x1F, 0x11 }; + letters['\''] = new byte[] { 0x18 }; + letters[']'] = new byte[] { 0x11, 0x1F }; + letters['_'] = new byte[] { 0x01, 0x01, 0x01, 0x01 }; + letters['`'] = new byte[] { 0x10, 0x08 }; + letters['{'] = new byte[] { 0x04, 0x1B, 0x11 }; + letters['|'] = new byte[] { 0x1F }; + letters['}'] = new byte[] { 0x11, 0x1B, 0x04 }; + letters['~'] = new byte[] { 0x04, 0x08, 0x04, 0x08 }; + } + } +} diff --git a/MCGalaxy_.csproj b/MCGalaxy_.csproj index 3b4cb2292..bb2f1db08 100644 --- a/MCGalaxy_.csproj +++ b/MCGalaxy_.csproj @@ -391,7 +391,6 @@ - @@ -410,6 +409,7 @@ +