From 98dad500fc8daf3f7572030c3e2c2113737129f4 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 27 Feb 2016 19:23:55 +1100 Subject: [PATCH] Add /wrt that allows specifying text scale and spacing between letters. --- Commands/Command.All.cs | 1 + Commands/CommandKeywords.cs | 1 + Commands/building/CmdWrite.cs | 77 ++++++++++++----- Drawing/BlockWriter.cs | 152 ++++++++++++++++++++++++++++++++++ Drawing/FindReference.cs | 112 +------------------------ MCGalaxy_.csproj | 1 + 6 files changed, 211 insertions(+), 133 deletions(-) create mode 100644 Drawing/BlockWriter.cs diff --git a/Commands/Command.All.cs b/Commands/Command.All.cs index e4425b923..3ba7fbe60 100644 --- a/Commands/Command.All.cs +++ b/Commands/Command.All.cs @@ -300,6 +300,7 @@ namespace MCGalaxy all.Add(new CmdWhoNick()); all.Add(new CmdWhowas()); all.Add(new CmdWrite()); + all.Add(new CmdWriteText()); all.Add(new CmdXban()); all.Add(new CmdXColor()); all.Add(new CmdXhide()); diff --git a/Commands/CommandKeywords.cs b/Commands/CommandKeywords.cs index 9bf085005..9714d2930 100644 --- a/Commands/CommandKeywords.cs +++ b/Commands/CommandKeywords.cs @@ -261,6 +261,7 @@ namespace MCGalaxy.Commands new CommandKeywords((new CmdWhois()), "who player info"); new CommandKeywords((new CmdWhowas()), "who player info"); new CommandKeywords((new CmdWrite()), "block text"); + new CommandKeywords((new CmdWriteText()), "block text"); new CommandKeywords((new CmdXban()), "ban undo admin"); new CommandKeywords((new CmdXhide()), "hide all extra"); new CommandKeywords((new CmdXJail()), "extra jail undo"); diff --git a/Commands/building/CmdWrite.cs b/Commands/building/CmdWrite.cs index 140e7693c..701720169 100644 --- a/Commands/building/CmdWrite.cs +++ b/Commands/building/CmdWrite.cs @@ -14,25 +14,37 @@ 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; namespace MCGalaxy.Commands { - public sealed class CmdWrite : Command { + public sealed class CmdWriteText : Command { - public override string name { get { return "write"; } } - public override string shortcut { get { return ""; } } + public override string name { get { return "writetext"; } } + public override string shortcut { get { return "wrt"; } } public override string type { get { return CommandTypes.Building; } } public override bool museumUsable { get { return false; } } - public override LevelPermission defaultRank { get { return LevelPermission.Operator; } } - public CmdWrite() { } - + public override LevelPermission defaultRank { get { return LevelPermission.Builder; } } + static char[] trimChars = { ' ' }; + public override void Use(Player p, string message) { + if (p == null) { MessageInGameOnly(p); return; } + if (!p.group.CanExecute(Command.all.Find("write"))) { + Player.SendMessage(p, "You must be able to use /write to use /writetext."); return; + } + if (message == "") { Help(p); return; } + string[] args = message.Split(trimChars, 3); + if (args.Length < 3) { Help(p); return; } + + byte scale = 1, spacing = 1; + if (!byte.TryParse(args[0], out scale)) scale = 1; + if (!byte.TryParse(args[1], out spacing)) spacing = 1; CatchPos cpos = default(CatchPos); - cpos.givenMessage = message.ToUpper(); + cpos.scale = scale; cpos.spacing = spacing; + cpos.givenMessage = args[2].ToUpper(); p.blockchangeObject = cpos; Player.SendMessage(p, "Place two blocks to determine direction."); @@ -53,29 +65,50 @@ namespace MCGalaxy.Commands { CatchPos cpos = (CatchPos)p.blockchangeObject; Level lvl = p.level; - ushort cur; if (x == cpos.x && z == cpos.z) { Player.SendMessage(p, "No direction was selected"); return; } - if (Math.Abs(cpos.x - x) > Math.Abs(cpos.z - z)) { - cur = cpos.x; - int dir = x > cpos.x ? 0 : 1; - foreach (char c in cpos.givenMessage) - cur = FindReference.WriteLetter(lvl, p, c, cur, cpos.y, cpos.z, type, extType, dir); - } else { - cur = cpos.z; - int dir = z > cpos.z ? 2 : 3; - foreach (char c in cpos.givenMessage) - cur = FindReference.WriteLetter(lvl, p, c, cpos.x, cpos.y, cur, type, extType, dir); + 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; } - - if (p.staticCommands) + + 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); } - struct CatchPos { public ushort x, y, z; public string givenMessage; } + struct CatchPos { public byte scale, spacing; public ushort x, y, z; public string givenMessage; } + + public override void Help(Player p) { + Player.SendMessage(p, "%T/wrt [scale] [spacing] [message]"); + Player.SendMessage(p, "%TWrites the given message in blocks."); + Player.SendMessage(p, "%Tspacing specifies the number of blocks between each letter."); + } + } + + public sealed class CmdWrite : Command { + + public override string name { get { return "write"; } } + public override string shortcut { get { return ""; } } + public override string type { get { return CommandTypes.Building; } } + public override bool museumUsable { get { return false; } } + public override LevelPermission defaultRank { get { return LevelPermission.Operator; } } + + public override void Use(Player p, string message) { + Command.all.Find("writetext").Use(p, "1 1 " + message); + } public override void Help(Player p) { Player.SendMessage(p, "/write [message] - Writes [message] in blocks"); + Player.SendMessage(p, "Note that this command has been deprecated by /writetext."); } } } diff --git a/Drawing/BlockWriter.cs b/Drawing/BlockWriter.cs new file mode 100644 index 000000000..4b6604b2f --- /dev/null +++ b/Drawing/BlockWriter.cs @@ -0,0 +1,152 @@ +/* + Copyright 2011 MCGalaxy + + 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 { + + 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.Blockchange(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 }; + } + } +} diff --git a/Drawing/FindReference.cs b/Drawing/FindReference.cs index 1ea7f4698..017f98010 100644 --- a/Drawing/FindReference.cs +++ b/Drawing/FindReference.cs @@ -20,38 +20,6 @@ using System.Collections.Generic; namespace MCGalaxy { internal static class FindReference { - - public static ushort WriteLetter(Level l, Player p, char c, ushort x, ushort y, ushort z, byte type, byte extType, int dir) { - if( (int)c >= 256 || letters[(int)c] == null ) { - Player.SendMessage(p, "\"" + c + "\" is not currently supported, replacing with space."); - if (dir == 0) x += 4; - else if (dir == 1) x -= 4; - else if (dir == 2) z += 4; - else if (dir == 3) z -= 4; - } 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; - - PlaceBlock(l, p, x, (ushort)(y + j), z, type, extType); - } - - if (dir == 0) x++; - else if (dir == 1) x--; - else if (dir == 2) z++; - else if (dir == 3) z--; - } - } - - if (dir == 0) return (ushort)(x + 1); - else if (dir == 1) return (ushort)(x - 1); - else if (dir == 2) return (ushort)(z + 1); - else if (dir == 3) return (ushort)(z - 1); - return 0; - } - public static List popRefCol(byte popType) { ColorBlock tempref = new ColorBlock(); @@ -491,86 +459,8 @@ namespace MCGalaxy { l.Blockchange(p, x, y, z, type, extType); } - public struct ColorBlock - { + public struct ColorBlock { public ushort x, y, z; public byte type, r, g, b, a; } - - static byte[][] letters; - static FindReference() { - 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 3eb3299c3..70479347a 100644 --- a/MCGalaxy_.csproj +++ b/MCGalaxy_.csproj @@ -388,6 +388,7 @@ +