Add /wrt that allows specifying text scale and spacing between letters.

This commit is contained in:
UnknownShadow200 2016-02-27 19:23:55 +11:00
parent 7dc6fd4cfc
commit 98dad500fc
6 changed files with 211 additions and 133 deletions

View File

@ -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());

View File

@ -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");

View File

@ -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.");
}
}
}

152
Drawing/BlockWriter.cs Normal file
View File

@ -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 };
}
}
}

View File

@ -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<ColorBlock> 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 };
}
}
}

View File

@ -388,6 +388,7 @@
<Compile Include="Commands\World\CmdUnflood.cs" />
<Compile Include="Commands\World\CmdUnload.cs" />
<Compile Include="Commands\World\CmdUnlock.cs" />
<Compile Include="Drawing\BlockWriter.cs" />
<Compile Include="Drawing\Brush.cs" />
<Compile Include="Drawing\CopyState.cs" />
<Compile Include="Drawing\DrawOps\CuboidDrawOp.cs" />