Refactory all brushes into Brush code and BrushFactory code.

This commit is contained in:
UnknownShadow200 2016-08-04 12:32:01 +10:00
parent b3ae2052d1
commit 3c3e16c1e3
23 changed files with 518 additions and 463 deletions

View File

@ -36,38 +36,26 @@ namespace MCGalaxy.Commands.Building {
Player.Message(p, "Your current brush is: " + p.BrushName); return; Player.Message(p, "Your current brush is: " + p.BrushName); return;
} }
string[] args = message.SplitSpaces(2); string[] args = message.SplitSpaces(2);
string brush = FindBrush(args[0]); BrushFactory brush = BrushFactory.Find(args[0]);
if (args[0].CaselessEq("list")) { if (args[0].CaselessEq("list")) {
Player.Message(p, "%HAvailable brushes: %S" + AvailableBrushes); Player.Message(p, "%HAvailable brushes: %S" + BrushFactory.Available);
} else if (brush == null) { } else if (brush == null) {
Player.Message(p, "No brush found with name \"" + args[0] + "\"."); Player.Message(p, "No brush found with name \"{0}\".", args[0]);
Player.Message(p, "Available brushes: " + AvailableBrushes); Player.Message(p, "Available brushes: " + BrushFactory.Available);
} else { } else {
Player.Message(p, "Set your brush to: " + brush); Player.Message(p, "Set your brush to: " + brush.Name);
p.BrushName = brush; p.BrushName = brush.Name;
p.DefaultBrushArgs = args.Length > 1 ? args[1] : ""; p.DefaultBrushArgs = args.Length > 1 ? args[1] : "";
} }
} }
internal static string FindBrush(string message) {
foreach (var brush in BrushFactory.Brushes) {
if (brush.Key.CaselessEq(message))
return brush.Key;
}
return null;
}
internal static string AvailableBrushes {
get { return BrushFactory.Brushes.Keys.Join(); }
}
public override void Help(Player p) { public override void Help(Player p) {
Player.Message(p, "%T/brush [name] <default brush args>"); Player.Message(p, "%T/brush [name] <default brush args>");
Player.Message(p, "%HSets your current brush to the brush with that name."); Player.Message(p, "%HSets your current brush to the brush with that name.");
Player.Message(p, "%T/help brush [name]"); Player.Message(p, "%T/help brush [name]");
Player.Message(p, "%HOutputs the help for the brush with that name."); Player.Message(p, "%HOutputs the help for the brush with that name.");
Player.Message(p, "%HAvailable brushes: %S" + AvailableBrushes); Player.Message(p, "%HAvailable brushes: %S" + BrushFactory.Available);
Player.Message(p, "%H- The default brush takes one argument specifying the block to draw with. " + Player.Message(p, "%H- The default brush takes one argument specifying the block to draw with. " +
"If no arguments are given, draws with your currently held block."); "If no arguments are given, draws with your currently held block.");
Player.Message(p, "%H- If \"skip\" is used for a block name, " + Player.Message(p, "%H- If \"skip\" is used for a block name, " +
@ -75,12 +63,12 @@ namespace MCGalaxy.Commands.Building {
} }
public override void Help(Player p, string message) { public override void Help(Player p, string message) {
string brush = FindBrush(message); BrushFactory brush = BrushFactory.Find(message);
if (brush == null) { if (brush == null) {
Player.Message(p, "No brush found with name \"{0}\".", message); Player.Message(p, "No brush found with name \"{0}\".", message);
Player.Message(p, "%HAvailable brushes: %S" + AvailableBrushes); Player.Message(p, "%HAvailable brushes: %S" + BrushFactory.Available);
} else { } else {
Player.MessageLines(p, BrushFactory.BrushesHelp[brush]); Player.MessageLines(p, brush.Help);
} }
} }
} }

View File

@ -34,12 +34,12 @@ namespace MCGalaxy.Commands.Building {
DrawArgs cpos = (DrawArgs)state; DrawArgs cpos = (DrawArgs)state;
cpos.block = type; cpos.extBlock = extType; cpos.block = type; cpos.extBlock = extType;
DrawOp op = null; DrawOp op = null;
Func<BrushArgs, Brush> constructor = null; BrushFactory factory = null;
switch (cpos.mode) { switch (cpos.mode) {
case DrawMode.solid: case DrawMode.solid:
op = new CuboidDrawOp(); op = new CuboidDrawOp();
constructor = SolidBrush.Process; break; factory = BrushFactory.Find("normal"); break;
case DrawMode.normal: case DrawMode.normal:
op = new CuboidDrawOp(); break; op = new CuboidDrawOp(); break;
case DrawMode.hollow: case DrawMode.hollow:
@ -48,16 +48,16 @@ namespace MCGalaxy.Commands.Building {
op = new CuboidWallsDrawOp(); break; op = new CuboidWallsDrawOp(); break;
case DrawMode.holes: case DrawMode.holes:
op = new CuboidDrawOp(); op = new CuboidDrawOp();
constructor = CheckeredBrush.Process; break; factory = BrushFactory.Find("checkered"); break;
case DrawMode.wire: case DrawMode.wire:
op = new CuboidWireframeDrawOp(); break; op = new CuboidWireframeDrawOp(); break;
case DrawMode.random: case DrawMode.random:
op = new CuboidDrawOp(); op = new CuboidDrawOp();
constructor = RandomBrush.Process; break; factory = BrushFactory.Find("random"); break;
} }
int brushOffset = cpos.mode == DrawMode.normal ? 0 : 1; int brushOffset = cpos.mode == DrawMode.normal ? 0 : 1;
Brush brush = GetBrush(p, cpos, brushOffset, constructor); Brush brush = GetBrush(p, cpos, brushOffset, factory);
if (brush == null) return false; if (brush == null) return false;
return DrawOp.DoDrawOp(op, brush, p, marks); return DrawOp.DoDrawOp(op, brush, p, marks);
} }

View File

@ -57,10 +57,10 @@ namespace MCGalaxy.Commands.Building {
string[] args = message.Split(' '); string[] args = message.Split(' ');
if (args[0].CaselessEq("not")) { if (args[0].CaselessEq("not")) {
op.Exclude = ReplaceBrush.GetBlocks(p, 1, args.Length, args); op.Exclude = ReplaceBrushFactory.GetBlocks(p, 1, args.Length, args);
if (op.Exclude == null) return false; if (op.Exclude == null) return false;
} else { } else {
op.Include = ReplaceBrush.GetBlocks(p, 0, args.Length, args); op.Include = ReplaceBrushFactory.GetBlocks(p, 0, args.Length, args);
if (op.Include == null) return false; if (op.Include == null) return false;
} }
return DrawOp.DoDrawOp(op, null, p, m); return DrawOp.DoDrawOp(op, null, p, m);

View File

@ -48,16 +48,16 @@ namespace MCGalaxy.Commands.Building {
int block = DrawCmd.GetBlock(p, parts[0], out extBlock); int block = DrawCmd.GetBlock(p, parts[0], out extBlock);
if (block == -1) return false; if (block == -1) return false;
string brushName = CmdBrush.FindBrush(parts[1]); BrushFactory factory = BrushFactory.Find(parts[1]);
if (brushName == null) { if (factory == null) {
Player.Message(p, "No brush found with name \"" + parts[1] + "\"."); Player.Message(p, "No brush found with name \"{0}\".", parts[1]);
Player.Message(p, "Available brushes: " + CmdBrush.AvailableBrushes); Player.Message(p, "Available brushes: " + BrushFactory.Available);
return false; return false;
} }
string brushMessage = parts.Length > 2 ? parts[2].ToLower() : ""; string brushMessage = parts.Length > 2 ? parts[2].ToLower() : "";
BrushArgs args = new BrushArgs(p, brushMessage, type, extType); BrushArgs args = new BrushArgs(p, brushMessage, type, extType);
Brush brush = BrushFactory.Brushes[brushName](args); Brush brush = factory.Construct(args);
if (brush == null) return false; if (brush == null) return false;
DrawOp drawOp = null; DrawOp drawOp = null;

View File

@ -42,11 +42,11 @@ namespace MCGalaxy.Commands.Building {
cpos.block = type; cpos.extBlock = extType; cpos.block = type; cpos.extBlock = extType;
DrawOp op = null; DrawOp op = null;
Func<BrushArgs, Brush> constructor = null; BrushFactory factory = null;
switch (cpos.mode) { switch (cpos.mode) {
case DrawMode.solid: case DrawMode.solid:
op = new AdvSphereDrawOp(); op = new AdvSphereDrawOp();
constructor = SolidBrush.Process; break; factory = BrushFactory.Find("normal"); break;
case DrawMode.hollow: case DrawMode.hollow:
op = new AdvHollowSphereDrawOp(); break; op = new AdvHollowSphereDrawOp(); break;
case DrawMode.circle: case DrawMode.circle:
@ -55,7 +55,7 @@ namespace MCGalaxy.Commands.Building {
op = new AdvSphereDrawOp(); break; op = new AdvSphereDrawOp(); break;
} }
int brushOffset = cpos.mode == DrawMode.normal ? 0 : 1; int brushOffset = cpos.mode == DrawMode.normal ? 0 : 1;
Brush brush = GetBrush(p, cpos, brushOffset, constructor); Brush brush = GetBrush(p, cpos, brushOffset, factory);
if (brush == null) return false; if (brush == null) return false;
Vec3S32 p0 = m[0]; Vec3S32 p0 = m[0];

View File

@ -70,16 +70,16 @@ namespace MCGalaxy.Commands.Building {
static Brush ParseBrush(string raw, Player p, byte block, byte extBlock) { static Brush ParseBrush(string raw, Player p, byte block, byte extBlock) {
string[] parts = raw.SplitSpaces(2); string[] parts = raw.SplitSpaces(2);
string brushName = CmdBrush.FindBrush(parts[0]); BrushFactory brush = BrushFactory.Find(parts[0]);
if (brushName == null) { if (brush == null) {
Player.Message(p, "No brush found with name \"{0}\".", parts[0]); Player.Message(p, "No brush found with name \"{0}\".", parts[0]);
Player.Message(p, "Available brushes: " + CmdBrush.AvailableBrushes); Player.Message(p, "Available brushes: " + BrushFactory.Available);
return null; return null;
} }
string brushArgs = parts.Length >= 2 ? parts[1].ToLower() : ""; string brushArgs = parts.Length >= 2 ? parts[1].ToLower() : "";
BrushArgs args = new BrushArgs(p, brushArgs, block, extBlock); BrushArgs args = new BrushArgs(p, brushArgs, block, extBlock);
return BrushFactory.Brushes[brushName](args); return brush.Construct(args);
} }
struct DrawArgs { public int mode; public string brushMsg; } struct DrawArgs { public int mode; public string brushMsg; }

View File

@ -73,7 +73,7 @@ namespace MCGalaxy.Commands.Building {
} }
protected static Brush GetBrush(Player p, DrawArgs dArgs, protected static Brush GetBrush(Player p, DrawArgs dArgs,
int usedFromEnd, Func<BrushArgs, Brush> constructor = null) { int usedFromEnd, BrushFactory factory = null) {
int end = dArgs.message.Length; int end = dArgs.message.Length;
string brushMsg = ""; string brushMsg = "";
for (int i = 0; i < usedFromEnd; i++) { for (int i = 0; i < usedFromEnd; i++) {
@ -83,9 +83,9 @@ namespace MCGalaxy.Commands.Building {
if (end >= 0) brushMsg = dArgs.message.Substring(0, end); if (end >= 0) brushMsg = dArgs.message.Substring(0, end);
if (brushMsg == "") brushMsg = p.DefaultBrushArgs; if (brushMsg == "") brushMsg = p.DefaultBrushArgs;
if (constructor == null) constructor = BrushFactory.Brushes[p.BrushName]; if (factory == null) factory = BrushFactory.Find(p.BrushName);
BrushArgs args = new BrushArgs(p, brushMsg, dArgs.block, dArgs.extBlock); BrushArgs args = new BrushArgs(p, brushMsg, dArgs.block, dArgs.extBlock);
return constructor(args); return factory.Construct(args);
} }
protected struct DrawArgs { protected struct DrawArgs {

View File

@ -35,7 +35,8 @@ namespace MCGalaxy.Commands.Building {
bool DoReplace(Player p, Vec3S32[] marks, object state, byte type, byte extType) { bool DoReplace(Player p, Vec3S32[] marks, object state, byte type, byte extType) {
BrushArgs args = new BrushArgs(p, (string)state, type, extType); BrushArgs args = new BrushArgs(p, (string)state, type, extType);
Brush brush = ReplaceNot ? ReplaceNotBrush.Process(args) : ReplaceBrush.Process(args); string name = ReplaceNot ? "replacenot" : "replace";
Brush brush = BrushFactory.Find(name).Construct(args);
if (brush == null) return false; if (brush == null) return false;
DrawOp drawOp = new CuboidDrawOp(); DrawOp drawOp = new CuboidDrawOp();
@ -76,7 +77,7 @@ namespace MCGalaxy.Commands.Building {
ushort z2 = (ushort)(p.level.Length - 1); ushort z2 = (ushort)(p.level.Length - 1);
BrushArgs args = new BrushArgs(p, message.ToLower(), 0, 0); BrushArgs args = new BrushArgs(p, message.ToLower(), 0, 0);
Brush brush = ReplaceBrush.Process(args); Brush brush = BrushFactory.Find("replace").Construct(args);
if (brush == null) return; if (brush == null) return;
DrawOp drawOp = new CuboidDrawOp(); DrawOp drawOp = new CuboidDrawOp();

View File

@ -31,24 +31,24 @@ namespace MCGalaxy.Drawing.Brushes {
/// <summary> Creates a brush from the given arguments, /// <summary> Creates a brush from the given arguments,
/// returning null if invalid arguments are specified. </summary> /// returning null if invalid arguments are specified. </summary>
public abstract Brush Process(BrushArgs args); public abstract Brush Construct(BrushArgs args);
public static Dictionary<string, Func<BrushArgs, Brush>> Brushes public static List<BrushFactory> Brushes = new List<BrushFactory>() {
= new Dictionary<string, Func<BrushArgs, Brush>> { new SolidBrushFactory(), new CheckeredBrushFactory(),
{ "normal", SolidBrush.Process }, { "paste", PasteBrush.Process }, new StripedBrushFactory(), new PasteBrushFactory(),
{ "checkered", CheckeredBrush.Process }, { "rainbow", RainbowBrush.Process }, new ReplaceBrushFactory(), new ReplaceNotBrushFactory(),
{ "bwrainbow", BWRainbowBrush.Process }, { "striped", StripedBrush.Process }, new RainbowBrushFactory(), new BWRainbowBrushFactory(),
{ "replace", ReplaceBrush.Process }, { "replacenot", ReplaceNotBrush.Process }, new RandomBrushFactory(), new CloudyBrushFactory(),
{ "random", RandomBrush.Process }, { "cloudy", CloudyBrush.Process },
}; };
public static Dictionary<string, string[]> BrushesHelp = new Dictionary<string, string[]> { public static string Available { get { return Brushes.Join(b => b.Name); } }
{ "normal", SolidBrush.HelpString }, { "paste", PasteBrush.HelpString },
{ "checkered", CheckeredBrush.HelpString }, { "rainbow", RainbowBrush.HelpString }, public static BrushFactory Find(string name) {
{ "bwrainbow", BWRainbowBrush.HelpString }, { "striped", StripedBrush.HelpString }, foreach (BrushFactory brush in Brushes) {
{ "replace", ReplaceBrush.HelpString }, { "replacenot", ReplaceNotBrush.HelpString }, if (brush.Name.CaselessEq(name)) return brush;
{ "random", RandomBrush.HelpString }, { "cloudy", CloudyBrush.HelpString }, }
}; return null;
}
} }
public struct BrushArgs { public struct BrushArgs {

View File

@ -0,0 +1,93 @@
/*
Copyright 2015 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;
namespace MCGalaxy.Drawing.Brushes {
public sealed class CloudyBrushFactory : BrushFactory {
public override string Name { get { return "Cloudy"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: [block1/frequency] [block2] <args>..",
"%HDraws by selecting blocks from the given [blocks] using perlin noise.",
"%Hfrequency is optional (defaults to 1), and specifies the number of times " +
"the block should appear (as a fraction of the total of all the frequencies).",
"%HOptional args format: %T<first letter of argument>_<value>",
"%HArguments: %Ta%Hmplitude, %Tf%Hrequency (scale), %Ts%Heed, " +
"%To%Hctaves, %Tp%Hersistence (turbulence), %Tl%Hacunarity",
};
public override Brush Construct(BrushArgs args) {
NoiseArgs n = default(NoiseArgs);
// Constants borrowed from fCraft to match it
n.Amplitude = 1;
n.Frequency = 0.08f;
n.Octaves = 3;
n.Seed = int.MinValue;
n.Persistence = 0.75f;
n.Lacunarity = 2;
int[] count;
ExtBlock[] toAffect = FrequencyBrush.GetBlocks(args, out count,
Filter, arg => Handler(arg, args.Player, ref n));
if (toAffect == null) return null;
return new CloudyBrush(toAffect, count, n);
}
// Only want to handle non block options.
static bool Filter(string arg) {
return arg.Length < 2 || arg[1] != '_';
}
static bool Handler(string arg, Player p, ref NoiseArgs args) {
char opt = arg[0];
arg = arg.Substring(arg.IndexOf('_') + 1);
if (opt == 'l') {
if (float.TryParse(arg, out args.Lacunarity)) return true;
Player.Message(p, "\"{0}\" was not a valid decimal.", arg);
} else if (opt == 'a') {
if (float.TryParse(arg, out args.Amplitude)) return true;
Player.Message(p, "\"{0}\" was not a valid decimal.", arg);
} else if (opt == 'f') {
if (float.TryParse(arg, out args.Frequency)) return true;
Player.Message(p, "\"{0}\" was not a valid decimal.", arg);
} else if (opt == 'p') {
if (float.TryParse(arg, out args.Persistence)) return true;
Player.Message(p, "\"{0}\" was not a valid decimal.", arg);
} else if (opt == 'o') {
if (byte.TryParse(arg, out args.Octaves)
&& args.Octaves > 0 && args.Octaves <= 16) return true;
Player.Message(p, "\"{0}\" was not an integer between 1 and 16.", arg);
} else if (opt == 's') {
if (int.TryParse(arg, out args.Seed)) return true;
Player.Message(p, "\"{0}\" was not a valid integer.", arg);
} else {
Player.Message(p, "\"{0}\" was not a valid argument name.", opt);
}
return false;
}
}
public struct NoiseArgs {
public byte Octaves;
public int Seed;
public float Frequency, Amplitude, Persistence, Lacunarity;
}
}

View File

@ -1,96 +1,117 @@
/* /*
Copyright 2015 MCGalaxy Copyright 2015 MCGalaxy
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; using System;
using MCGalaxy.Commands.Building; using MCGalaxy.Commands.Building;
namespace MCGalaxy.Drawing.Brushes { namespace MCGalaxy.Drawing.Brushes {
/// <summary> Contains helper methods for brushes that have blocks with /// <summary> Contains helper methods for brushes that have blocks with
/// optional frequency counts (e.g. random and cloudy brushes) </summary> /// optional frequency counts (e.g. random and cloudy brushes) </summary>
public static class FrequencyBrush { public static class FrequencyBrush {
public static ExtBlock[] GetBlocks(BrushArgs args, out int[] count, public static ExtBlock[] GetBlocks(BrushArgs args, out int[] count,
Predicate<string> filter, Predicate<string> handler) { Predicate<string> filter, Predicate<string> handler) {
string[] parts = args.Message.Split(' '); string[] parts = args.Message.Split(' ');
Player p = args.Player; Player p = args.Player;
ExtBlock[] blocks; ExtBlock[] blocks;
GetRaw(parts, filter, args, out blocks, out count); GetRaw(parts, filter, args, out blocks, out count);
for (int i = 0, j = 0; i < parts.Length; i++ ) { for (int i = 0, j = 0; i < parts.Length; i++ ) {
if (parts[i] == "") continue; if (parts[i] == "") continue;
// Brush specific args // Brush specific args
if (!filter(parts[i])) { if (!filter(parts[i])) {
if (!handler(parts[i])) return null; if (!handler(parts[i])) return null;
continue; continue;
} }
byte extType = 0; byte extType = 0;
int sepIndex = parts[i].IndexOf('/'); int sepIndex = parts[i].IndexOf('/');
string block = sepIndex >= 0 ? parts[i].Substring(0, sepIndex) : parts[i]; string block = sepIndex >= 0 ? parts[i].Substring(0, sepIndex) : parts[i];
int type = DrawCmd.GetBlock(p, block, out extType); int type = DrawCmd.GetBlock(p, block, out extType);
if (type == -1) return null; if (type == -1) return null;
blocks[j].Block = (byte)type; blocks[j].Ext = extType; blocks[j].Block = (byte)type; blocks[j].Ext = extType;
if (sepIndex < 0) { j++; continue; } if (sepIndex < 0) { j++; continue; }
int chance; int chance;
if (!int.TryParse(parts[i].Substring(sepIndex + 1), out chance) if (!int.TryParse(parts[i].Substring(sepIndex + 1), out chance)
|| chance <= 0 || chance > 10000) { || chance <= 0 || chance > 10000) {
Player.Message(p, "frequency must be an integer between 1 and 10,000."); return null; Player.Message(p, "frequency must be an integer between 1 and 10,000."); return null;
} }
count[j] = chance; count[j] = chance;
j++; j++;
} }
return blocks; return blocks;
} }
static void GetRaw(string[] parts, Predicate<string> filter, BrushArgs args, static void GetRaw(string[] parts, Predicate<string> filter, BrushArgs args,
out ExtBlock[] blocks, out int[] count) {; out ExtBlock[] blocks, out int[] count) {;
int bCount = 0; int bCount = 0;
for (int i = 0; i < parts.Length; i++) { for (int i = 0; i < parts.Length; i++) {
if (parts[i] == "" || !filter(parts[i])) continue; if (parts[i] == "" || !filter(parts[i])) continue;
bCount++; bCount++;
} }
// For 0 or 1 blocks given, treat second block as 'unchanged'. // For 0 or 1 blocks given, treat second block as 'unchanged'.
blocks = new ExtBlock[Math.Max(2, bCount)]; blocks = new ExtBlock[Math.Max(2, bCount)];
count = new int[blocks.Length]; count = new int[blocks.Length];
for (int i = 0; i < count.Length; i++) { for (int i = 0; i < count.Length; i++) {
count[i] = 1; count[i] = 1;
blocks[i] = new ExtBlock(Block.Zero, 0); blocks[i] = new ExtBlock(Block.Zero, 0);
} }
// No blocks given, assume first is held block // No blocks given, assume first is held block
if (bCount == 0) if (bCount == 0)
blocks[0] = new ExtBlock(args.Block, args.ExtBlock); blocks[0] = new ExtBlock(args.Block, args.ExtBlock);
} }
public static ExtBlock[] Combine(ExtBlock[] toAffect, int[] count) { public static ExtBlock[] Combine(ExtBlock[] toAffect, int[] count) {
int sum = 0; int sum = 0;
for (int i = 0; i < count.Length; i++) sum += count[i]; for (int i = 0; i < count.Length; i++) sum += count[i];
ExtBlock[] blocks = new ExtBlock[sum]; ExtBlock[] blocks = new ExtBlock[sum];
for (int i = 0, index = 0; i < toAffect.Length; i++) { for (int i = 0, index = 0; i < toAffect.Length; i++) {
for (int j = 0; j < count[i]; j++) for (int j = 0; j < count[i]; j++)
blocks[index++] = toAffect[i]; blocks[index++] = toAffect[i];
} }
return blocks; return blocks;
} }
} }
}
public sealed class RandomBrushFactory : BrushFactory {
public override string Name { get { return "Random"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: [block1/frequency] [block2]..",
"%HDraws by randomly selecting blocks from the given [blocks].",
"%Hfrequency is optional (defaults to 1), and specifies the number of times " +
"the block should appear (as a fraction of the total of all the frequencies).",
};
public override Brush Construct(BrushArgs args) {
int[] count;
ExtBlock[] toAffect = FrequencyBrush.GetBlocks(args, out count, P => true, null);
if (toAffect == null) return null;
ExtBlock[] blocks = FrequencyBrush.Combine(toAffect, count);
return new RandomBrush(blocks);
}
}
}

View File

@ -0,0 +1,90 @@
/*
Copyright 2015 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;
using MCGalaxy.Commands.Building;
namespace MCGalaxy.Drawing.Brushes {
public sealed class ReplaceBrushFactory : BrushFactory {
public override string Name { get { return "Replace"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: [block1] [block2].. [new]",
"%HDraws by replacing existing blocks that are in the given [blocks] with [new]",
"%H If only [block] is given, replaces with your held block.",
};
public override Brush Construct(BrushArgs args) { return ProcessReplace(args, false); }
internal static Brush ProcessReplace(BrushArgs args, bool not) {
string[] parts = args.Message.Split(' ');
if (args.Message == "") {
args.Player.SendMessage("You need at least one block to replace."); return null;
}
int count = parts.Length == 1 ? 1 : parts.Length - 1;
ExtBlock[] toAffect = GetBlocks(args.Player, 0, count, parts);
if (toAffect == null) return null;
ExtBlock target;
if (!GetTargetBlock(args, parts, out target)) return null;
if (not) return new ReplaceNotBrush(toAffect, target);
return new ReplaceBrush(toAffect, target);
}
internal static ExtBlock[] GetBlocks(Player p, int start, int max, string[] parts) {
ExtBlock[] blocks = new ExtBlock[max - start];
for (int i = 0; i < blocks.Length; i++)
blocks[i].Block = Block.Zero;
for (int i = 0; start < max; start++, i++ ) {
byte extBlock = 0;
int block = DrawCmd.GetBlock(p, parts[start], out extBlock);
if (block == -1) return null;
blocks[i].Block = (byte)block; blocks[i].Ext = extBlock;
}
return blocks;
}
static bool GetTargetBlock(BrushArgs args, string[] parts, out ExtBlock target) {
if (parts.Length == 1) {
target = new ExtBlock(args.Block, args.ExtBlock);
return true;
}
target = default(ExtBlock);
int block = DrawCmd.GetBlock(args.Player, parts[parts.Length - 1], out target.Ext);
if (block == -1) return false;
target.Block = (byte)block;
return true;
}
}
public sealed class ReplaceNotBrushFactory : BrushFactory {
public override string Name { get { return "ReplaceNot"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: [block1] [block2].. [new]",
"%HDraws by replacing existing blocks that not are in the given [blocks] with [new]",
"%H If only [block] is given, replaces with your held block.",
};
public override Brush Construct(BrushArgs args) { return ReplaceBrushFactory.ProcessReplace(args, true); }
}
}

View File

@ -0,0 +1,147 @@
/*
Copyright 2015 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;
using MCGalaxy.Commands.Building;
namespace MCGalaxy.Drawing.Brushes {
public sealed class SolidBrushFactory : BrushFactory {
public override string Name { get { return "Normal"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: [block]",
"%HDraws using the specified block.",
"%H If block is not given, the currently held block is used.",
};
public override Brush Construct(BrushArgs args) {
if (args.Message == "")
return new SolidBrush(args.Block, args.ExtBlock);
byte extBlock;
int block = DrawCmd.GetBlock(args.Player, args.Message, out extBlock);
if (block == -1) return null;
return new SolidBrush((byte)block, extBlock);
}
}
public sealed class CheckeredBrushFactory : BrushFactory {
public override string Name { get { return "Checkered"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: [block1] [block2]",
"%HDraws an alternating pattern of block1 and block2.",
"%H If block2 is not given, air is used.",
"%H If block1 is not given, the currently held block is used.",
};
public override Brush Construct(BrushArgs args) {
if (args.Message == "")
return new CheckeredBrush(args.Block, args.ExtBlock, 0, 0);
string[] parts = args.Message.Split(' ');
byte extBlock1;
int block1 = DrawCmd.GetBlock(args.Player, parts[0], out extBlock1);
if (block1 == -1) return null;
if (parts.Length == 1)
return new CheckeredBrush((byte)block1, extBlock1, Block.Zero, 0);
byte extBlock2;
int block2 = DrawCmd.GetBlock(args.Player, parts[1], out extBlock2);
if (block2 == -1) return null;
return new CheckeredBrush((byte)block1, extBlock1, (byte)block2, extBlock2);
}
}
public sealed class PasteBrushFactory : BrushFactory {
public override string Name { get { return "Paste"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: none",
"%HDraws using blocks from the current copy state.",
};
public override Brush Construct(BrushArgs args) {
if (args.Player.CopyBuffer == null) {
args.Player.SendMessage("You haven't copied anything yet.");
return null;
}
return new PasteBrush(args.Player.CopyBuffer);
}
}
public sealed class StripedBrushFactory : BrushFactory {
public override string Name { get { return "Striped"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: [block1] [block2]",
"%HDraws a diagonally-alternating pattern of block1 and block2.",
"%H If block2 is not given, air is used.",
"%H If block1 is not given, the currently held block is used.",
};
public override Brush Construct(BrushArgs args) {
if (args.Message == "")
return new StripedBrush(args.Block, args.ExtBlock, 0, 0);
string[] parts = args.Message.Split(' ');
byte extBlock1;
int block1 = DrawCmd.GetBlock(args.Player, parts[0], out extBlock1);
if (block1 == -1) return null;
if (parts.Length == 1)
return new StripedBrush((byte)block1, extBlock1, 0, 0);
byte extBlock2;
int block2 = DrawCmd.GetBlock(args.Player, parts[1], out extBlock2);
if (block2 == -1) return null;
return new StripedBrush((byte)block1, extBlock1, (byte)block2, extBlock2);
}
}
public sealed class RainbowBrushFactory : BrushFactory {
public override string Name { get { return "Rainbow"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: <random>",
"%HIf no arguments are given, draws a diagonally repeating rainbow",
"%HIf \'random\' is given, draws by randomly selecting blocks from the rainbow pattern.",
};
public override Brush Construct(BrushArgs args) {
if (args.Message == "random") return new RandomRainbowBrush();
if (args.Message == "bw") return new BWRainbowBrush();
return new RainbowBrush();
}
}
public sealed class BWRainbowBrushFactory : BrushFactory {
public override string Name { get { return "BWRainbow"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: none",
"%HDraws a diagonally repeating black-white rainbow",
};
public override Brush Construct(BrushArgs args) { return new BWRainbowBrush(); }
}
}

View File

@ -24,9 +24,6 @@ namespace MCGalaxy.Drawing.Brushes {
/// <summary> Human friendly name of this brush. </summary> /// <summary> Human friendly name of this brush. </summary>
public abstract string Name { get; } public abstract string Name { get; }
/// <summary> Description of the brush, in addition to its syntax. </summary>
public abstract string[] Help { get; }
/// <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) { }

View File

@ -20,8 +20,7 @@ using System.Collections.Generic;
using MCGalaxy.Commands.Building; using MCGalaxy.Commands.Building;
using MCGalaxy.Drawing.Ops; using MCGalaxy.Drawing.Ops;
namespace MCGalaxy.Drawing.Brushes { namespace MCGalaxy.Drawing.Brushes {
public sealed class CheckeredBrush : Brush { public sealed class CheckeredBrush : Brush {
readonly byte block1, extBlock1, block2, extBlock2; readonly byte block1, extBlock1, block2, extBlock2;
@ -32,32 +31,6 @@ namespace MCGalaxy.Drawing.Brushes {
public override string Name { get { return "Checkered"; } } public override string Name { get { return "Checkered"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: [block1] [block2]",
"%HDraws an alternating pattern of block1 and block2.",
"%H If block2 is not given, air is used.",
"%H If block1 is not given, the currently held block is used.",
};
public static Brush Process(BrushArgs args) {
if (args.Message == "")
return new CheckeredBrush(args.Block, args.ExtBlock, 0, 0);
string[] parts = args.Message.Split(' ');
byte extBlock1;
int block1 = DrawCmd.GetBlock(args.Player, parts[0], out extBlock1);
if (block1 == -1) return null;
if (parts.Length == 1)
return new CheckeredBrush((byte)block1, extBlock1, Block.Zero, 0);
byte extBlock2;
int block2 = DrawCmd.GetBlock(args.Player, parts[1], out extBlock2);
if (block2 == -1) return null;
return new CheckeredBrush((byte)block1, extBlock1, (byte)block2, extBlock2);
}
public override byte NextBlock(DrawOp op) { public override byte NextBlock(DrawOp op) {
return ((op.Coords.X + op.Coords.Y + op.Coords.Z) & 1) == 0 ? block1 : block2; return ((op.Coords.X + op.Coords.Y + op.Coords.Z) & 1) == 0 ? block1 : block2;
} }

View File

@ -45,70 +45,6 @@ namespace MCGalaxy.Drawing.Brushes {
public override string Name { get { return "Cloudy"; } } public override string Name { get { return "Cloudy"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: [block1/frequency] [block2] <args>..",
"%HDraws by selecting blocks from the given [blocks] using perlin noise.",
"%Hfrequency is optional (defaults to 1), and specifies the number of times " +
"the block should appear (as a fraction of the total of all the frequencies).",
"%HOptional args format: %T<first letter of argument>_<value>",
"%HArguments: %Ta%Hmplitude, %Tf%Hrequency (scale), %Ts%Heed, " +
"%To%Hctaves, %Tp%Hersistence (turbulence), %Tl%Hacunarity",
};
public static Brush Process(BrushArgs args) {
NoiseArgs n = default(NoiseArgs);
// Constants borrowed from fCraft to match it
n.Amplitude = 1;
n.Frequency = 0.08f;
n.Octaves = 3;
n.Seed = int.MinValue;
n.Persistence = 0.75f;
n.Lacunarity = 2;
int[] count;
ExtBlock[] toAffect = FrequencyBrush.GetBlocks(args, out count,
Filter, arg => Handler(arg, args.Player, ref n));
if (toAffect == null) return null;
return new CloudyBrush(toAffect, count, n);
}
// Only want to handle non block options.
static bool Filter(string arg) {
return arg.Length < 2 || arg[1] != '_';
}
static bool Handler(string arg, Player p, ref NoiseArgs args) {
char opt = arg[0];
arg = arg.Substring(arg.IndexOf('_') + 1);
if (opt == 'l') {
if (float.TryParse(arg, out args.Lacunarity)) return true;
Player.Message(p, "\"{0}\" was not a valid decimal.", arg);
} else if (opt == 'a') {
if (float.TryParse(arg, out args.Amplitude)) return true;
Player.Message(p, "\"{0}\" was not a valid decimal.", arg);
} else if (opt == 'f') {
if (float.TryParse(arg, out args.Frequency)) return true;
Player.Message(p, "\"{0}\" was not a valid decimal.", arg);
} else if (opt == 'p') {
if (float.TryParse(arg, out args.Persistence)) return true;
Player.Message(p, "\"{0}\" was not a valid decimal.", arg);
} else if (opt == 'o') {
if (byte.TryParse(arg, out args.Octaves)
&& args.Octaves > 0 && args.Octaves <= 16) return true;
Player.Message(p, "\"{0}\" was not an integer between 1 and 16.", arg);
} else if (opt == 's') {
if (int.TryParse(arg, out args.Seed)) return true;
Player.Message(p, "\"{0}\" was not a valid integer.", arg);
} else {
Player.Message(p, "\"{0}\" was not a valid argument name.", opt);
}
return false;
}
public unsafe override void Configure(DrawOp op, Player p) { public unsafe override void Configure(DrawOp op, Player p) {
Player.Message(p, "Calculating noise distribution..."); Player.Message(p, "Calculating noise distribution...");
// Initalise our noise histogram // Initalise our noise histogram
@ -176,14 +112,6 @@ namespace MCGalaxy.Drawing.Brushes {
return blocks[next].Block; return blocks[next].Block;
} }
public override byte NextExtBlock(DrawOp op) { public override byte NextExtBlock(DrawOp op) { return blocks[next].Ext; }
return blocks[next].Ext;
}
}
public struct NoiseArgs {
public byte Octaves;
public int Seed;
public float Frequency, Amplitude, Persistence, Lacunarity;
} }
} }

View File

@ -20,32 +20,14 @@ using System.Collections.Generic;
using MCGalaxy.Commands; using MCGalaxy.Commands;
using MCGalaxy.Drawing.Ops; using MCGalaxy.Drawing.Ops;
namespace MCGalaxy.Drawing.Brushes { namespace MCGalaxy.Drawing.Brushes {
public sealed class PasteBrush : Brush { public sealed class PasteBrush : Brush {
readonly CopyState state; readonly CopyState state;
public PasteBrush(CopyState state) { public PasteBrush(CopyState state) { this.state = state; }
this.state = state;
}
public override string Name { get { return "Paste"; } } public override string Name { get { return "Paste"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: none",
"%HDraws using blocks from the current copy state.",
};
public static Brush Process(BrushArgs args) {
if (args.Player.CopyBuffer == null) {
args.Player.SendMessage("You haven't copied anything yet.");
return null;
}
return new PasteBrush(args.Player.CopyBuffer);
}
public override byte NextBlock(DrawOp op) { public override byte NextBlock(DrawOp op) {
Vec3U16 p = LocalCoords(op); Vec3U16 p = LocalCoords(op);
return state.Blocks[state.GetIndex(p.X, p.Y, p.Z)]; return state.Blocks[state.GetIndex(p.X, p.Y, p.Z)];

View File

@ -26,14 +26,6 @@ namespace MCGalaxy.Drawing.Brushes {
public override string Name { get { return "Rainbow"; } } public override string Name { get { return "Rainbow"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: <random>",
"%HIf no arguments are given, draws a diagonally repeating rainbow",
"%HIf \'random\' is given, draws by randomly selecting blocks from the rainbow pattern.",
};
public override byte NextBlock(DrawOp op) { public override byte NextBlock(DrawOp op) {
int offset = (op.Coords.X + op.Coords.Y + op.Coords.Z) % 13; int offset = (op.Coords.X + op.Coords.Y + op.Coords.Z) % 13;
if (offset < 0) offset += 13; if (offset < 0) offset += 13;
@ -41,14 +33,6 @@ namespace MCGalaxy.Drawing.Brushes {
} }
public override byte NextExtBlock(DrawOp op) { return 0; } public override byte NextExtBlock(DrawOp op) { return 0; }
public static Brush Process(BrushArgs args) {
if (args.Message == "random")
return new RandomRainbowBrush();
if (args.Message == "bw")
return new BWRainbowBrush();
return new RainbowBrush();
}
} }
public sealed class BWRainbowBrush : Brush { public sealed class BWRainbowBrush : Brush {
@ -63,18 +47,7 @@ namespace MCGalaxy.Drawing.Brushes {
return blocks[offset]; return blocks[offset];
} }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: none",
"%HDraws a diagonally repeating black-white rainbow",
};
public override byte NextExtBlock(DrawOp op) { return 0; } public override byte NextExtBlock(DrawOp op) { return 0; }
public static Brush Process(BrushArgs args) {
return new BWRainbowBrush();
}
} }
internal sealed class RandomRainbowBrush : Brush { internal sealed class RandomRainbowBrush : Brush {
@ -82,15 +55,9 @@ namespace MCGalaxy.Drawing.Brushes {
public override string Name { get { return "RandomRainbow"; } } public override string Name { get { return "RandomRainbow"; } }
public override string[] Help { get { return new string[0]; } } public RandomRainbowBrush() { rnd = new Random(); }
public RandomRainbowBrush() { public RandomRainbowBrush(int seed) { rnd = new Random(seed); }
rnd = new Random();
}
public RandomRainbowBrush(int seed) {
rnd = new Random(seed);
}
public override byte NextBlock(DrawOp op) { public override byte NextBlock(DrawOp op) {
return (byte)rnd.Next(Block.red, Block.darkgrey); return (byte)rnd.Next(Block.red, Block.darkgrey);

View File

@ -33,24 +33,6 @@ namespace MCGalaxy.Drawing.Brushes {
public override string Name { get { return "Random"; } } public override string Name { get { return "Random"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: [block1/frequency] [block2]..",
"%HDraws by randomly selecting blocks from the given [blocks].",
"%Hfrequency is optional (defaults to 1), and specifies the number of times " +
"the block should appear (as a fraction of the total of all the frequencies).",
};
public static Brush Process(BrushArgs args) {
int[] count;
ExtBlock[] toAffect = FrequencyBrush.GetBlocks(args, out count, P => true, null);
if (toAffect == null) return null;
ExtBlock[] blocks = FrequencyBrush.Combine(toAffect, count);
return new RandomBrush(blocks);
}
int next; int next;
const int mask = 0x7fffffff; const int mask = 0x7fffffff;
public override byte NextBlock(DrawOp op) { public override byte NextBlock(DrawOp op) {

View File

@ -20,8 +20,7 @@ using System.Collections.Generic;
using MCGalaxy.Commands.Building; using MCGalaxy.Commands.Building;
using MCGalaxy.Drawing.Ops; using MCGalaxy.Drawing.Ops;
namespace MCGalaxy.Drawing.Brushes { namespace MCGalaxy.Drawing.Brushes {
public sealed class ReplaceBrush : Brush { public sealed class ReplaceBrush : Brush {
readonly ExtBlock[] include; readonly ExtBlock[] include;
readonly ExtBlock target; readonly ExtBlock target;
@ -32,61 +31,6 @@ namespace MCGalaxy.Drawing.Brushes {
public override string Name { get { return "Replace"; } } public override string Name { get { return "Replace"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: [block1] [block2].. [new]",
"%HDraws by replacing existing blocks that are in the given [blocks] with [new]",
"%H If only [block] is given, replaces with your held block.",
};
public static Brush Process(BrushArgs args) {
return ProcessReplace(args, false);
}
internal static Brush ProcessReplace(BrushArgs args, bool not) {
string[] parts = args.Message.Split(' ');
if (args.Message == "") {
args.Player.SendMessage("You need at least one block to replace."); return null;
}
int count = parts.Length == 1 ? 1 : parts.Length - 1;
ExtBlock[] toAffect = GetBlocks(args.Player, 0, count, parts);
if (toAffect == null) return null;
ExtBlock target;
if (!GetTargetBlock(args, parts, out target)) return null;
if (not) return new ReplaceNotBrush(toAffect, target);
return new ReplaceBrush(toAffect, target);
}
internal static ExtBlock[] GetBlocks(Player p, int start, int max, string[] parts) {
ExtBlock[] blocks = new ExtBlock[max - start];
for (int i = 0; i < blocks.Length; i++)
blocks[i].Block = Block.Zero;
for (int i = 0; start < max; start++, i++ ) {
byte extBlock = 0;
int block = DrawCmd.GetBlock(p, parts[start], out extBlock);
if (block == -1) return null;
blocks[i].Block = (byte)block; blocks[i].Ext = extBlock;
}
return blocks;
}
static bool GetTargetBlock(BrushArgs args, string[] parts, out ExtBlock target) {
if (parts.Length == 1) {
target = new ExtBlock(args.Block, args.ExtBlock);
return true;
}
target = default(ExtBlock);
int block = DrawCmd.GetBlock(args.Player, parts[parts.Length - 1], out target.Ext);
if (block == -1) return false;
target.Block = (byte)block;
return true;
}
public override byte NextBlock(DrawOp op) { public override byte NextBlock(DrawOp op) {
ushort x = op.Coords.X, y = op.Coords.Y, z = op.Coords.Z; ushort x = op.Coords.X, y = op.Coords.Y, z = op.Coords.Z;
byte tile = op.Level.GetTile(x, y, z), extTile = 0; byte tile = op.Level.GetTile(x, y, z), extTile = 0;
@ -100,9 +44,7 @@ namespace MCGalaxy.Drawing.Brushes {
return Block.Zero; return Block.Zero;
} }
public override byte NextExtBlock(DrawOp op) { public override byte NextExtBlock(DrawOp op) { return target.Ext; }
return target.Ext;
}
} }
public sealed class ReplaceNotBrush : Brush { public sealed class ReplaceNotBrush : Brush {
@ -115,18 +57,6 @@ namespace MCGalaxy.Drawing.Brushes {
public override string Name { get { return "ReplaceNot"; } } public override string Name { get { return "ReplaceNot"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: [block1] [block2].. [new]",
"%HDraws by replacing existing blocks that not are in the given [blocks] with [new]",
"%H If only [block] is given, replaces with your held block.",
};
public static Brush Process(BrushArgs args) {
return ReplaceBrush.ProcessReplace(args, true);
}
public override byte NextBlock(DrawOp op) { public override byte NextBlock(DrawOp op) {
ushort x = op.Coords.X, y = op.Coords.Y, z = op.Coords.Z; ushort x = op.Coords.X, y = op.Coords.Y, z = op.Coords.Z;
byte tile = op.Level.GetTile(x, y, z), extTile = 0; byte tile = op.Level.GetTile(x, y, z), extTile = 0;
@ -140,8 +70,6 @@ namespace MCGalaxy.Drawing.Brushes {
return target.Block; return target.Block;
} }
public override byte NextExtBlock(DrawOp op) { public override byte NextExtBlock(DrawOp op) { return target.Ext; }
return target.Ext;
}
} }
} }

View File

@ -19,37 +19,19 @@ using System;
using MCGalaxy.Commands.Building; using MCGalaxy.Commands.Building;
using MCGalaxy.Drawing.Ops; using MCGalaxy.Drawing.Ops;
namespace MCGalaxy.Drawing.Brushes { namespace MCGalaxy.Drawing.Brushes {
public sealed class SolidBrush : Brush { public sealed class SolidBrush : Brush {
readonly byte type, extType; readonly byte block, extBlock;
public SolidBrush(byte type, byte extType) { public SolidBrush(byte type, byte extType) {
this.type = type; this.block = type;
this.extType = extType; this.extBlock = extType;
} }
public override string Name { get { return "Normal"; } } public override string Name { get { return "Normal"; } }
public override string[] Help { get { return HelpString; } } public override byte NextBlock(DrawOp op) { return block; }
public static string[] HelpString = new [] { public override byte NextExtBlock(DrawOp op) { return extBlock; }
"%TArguments: [block]",
"%HDraws using the specified block.",
"%H If block is not given, the currently held block is used.",
};
public static Brush Process(BrushArgs args) {
if (args.Message == "")
return new SolidBrush(args.Block, args.ExtBlock);
byte extBlock;
int block = DrawCmd.GetBlock(args.Player, args.Message, out extBlock);
if (block == -1) return null;
return new SolidBrush((byte)block, extBlock);
}
public override byte NextBlock(DrawOp op) { return type; }
public override byte NextExtBlock(DrawOp op) { return extType; }
} }
} }

View File

@ -20,8 +20,7 @@ using System.Collections.Generic;
using MCGalaxy.Commands.Building; using MCGalaxy.Commands.Building;
using MCGalaxy.Drawing.Ops; using MCGalaxy.Drawing.Ops;
namespace MCGalaxy.Drawing.Brushes { namespace MCGalaxy.Drawing.Brushes {
public sealed class StripedBrush : Brush { public sealed class StripedBrush : Brush {
readonly byte block1, extBlock1, block2, extBlock2; readonly byte block1, extBlock1, block2, extBlock2;
@ -32,32 +31,6 @@ namespace MCGalaxy.Drawing.Brushes {
public override string Name { get { return "Striped"; } } public override string Name { get { return "Striped"; } }
public override string[] Help { get { return HelpString; } }
public static string[] HelpString = new [] {
"%TArguments: [block1] [block2]",
"%HDraws a diagonally-alternating pattern of block1 and block2.",
"%H If block2 is not given, air is used.",
"%H If block1 is not given, the currently held block is used.",
};
public static Brush Process(BrushArgs args) {
if (args.Message == "")
return new StripedBrush(args.Block, args.ExtBlock, 0, 0);
string[] parts = args.Message.Split(' ');
byte extBlock1;
int block1 = DrawCmd.GetBlock(args.Player, parts[0], out extBlock1);
if (block1 == -1) return null;
if (parts.Length == 1)
return new StripedBrush((byte)block1, extBlock1, 0, 0);
byte extBlock2;
int block2 = DrawCmd.GetBlock(args.Player, parts[1], out extBlock2);
if (block2 == -1) return null;
return new StripedBrush((byte)block1, extBlock1, (byte)block2, extBlock2);
}
public override byte NextBlock(DrawOp op) { public override byte NextBlock(DrawOp op) {
return ((op.Coords.X + op.Coords.Y + op.Coords.Z) & 3) <= 1 ? block1 : block2; return ((op.Coords.X + op.Coords.Y + op.Coords.Z) & 3) <= 1 ? block1 : block2;
} }

View File

@ -415,7 +415,6 @@
<Compile Include="Database\SQLite\SQLiteParameterisedQuery.cs" /> <Compile Include="Database\SQLite\SQLiteParameterisedQuery.cs" />
<Compile Include="Drawing\Brushes\Brush.cs" /> <Compile Include="Drawing\Brushes\Brush.cs" />
<Compile Include="Drawing\Brushes\CheckeredBrush.cs" /> <Compile Include="Drawing\Brushes\CheckeredBrush.cs" />
<Compile Include="Drawing\Brushes\FrequencyBrush.cs" />
<Compile Include="Drawing\Brushes\CloudyBrush.cs" /> <Compile Include="Drawing\Brushes\CloudyBrush.cs" />
<Compile Include="Drawing\Brushes\PasteBrush.cs" /> <Compile Include="Drawing\Brushes\PasteBrush.cs" />
<Compile Include="Drawing\Brushes\RainbowBrush.cs" /> <Compile Include="Drawing\Brushes\RainbowBrush.cs" />
@ -424,6 +423,10 @@
<Compile Include="Drawing\Brushes\SolidBrush.cs" /> <Compile Include="Drawing\Brushes\SolidBrush.cs" />
<Compile Include="Drawing\Brushes\StripedBrush.cs" /> <Compile Include="Drawing\Brushes\StripedBrush.cs" />
<Compile Include="Drawing\BrushFactories\BrushFactory.cs" /> <Compile Include="Drawing\BrushFactories\BrushFactory.cs" />
<Compile Include="Drawing\BrushFactories\CloudyBrush.cs" />
<Compile Include="Drawing\BrushFactories\FrequencyBrushes.cs" />
<Compile Include="Drawing\BrushFactories\ReplaceBrushes.cs" />
<Compile Include="Drawing\BrushFactories\SimpleBrushes.cs" />
<Compile Include="Drawing\CopyState.cs" /> <Compile Include="Drawing\CopyState.cs" />
<Compile Include="Drawing\DrawOps\AdvConeDrawOps.cs" /> <Compile Include="Drawing\DrawOps\AdvConeDrawOps.cs" />
<Compile Include="Drawing\DrawOps\AdvDrawOps.cs" /> <Compile Include="Drawing\DrawOps\AdvDrawOps.cs" />