mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-22 03:55:18 -04:00
Refactory all brushes into Brush code and BrushFactory code.
This commit is contained in:
parent
b3ae2052d1
commit
3c3e16c1e3
@ -36,38 +36,26 @@ namespace MCGalaxy.Commands.Building {
|
||||
Player.Message(p, "Your current brush is: " + p.BrushName); return;
|
||||
}
|
||||
string[] args = message.SplitSpaces(2);
|
||||
string brush = FindBrush(args[0]);
|
||||
BrushFactory brush = BrushFactory.Find(args[0]);
|
||||
|
||||
if (args[0].CaselessEq("list")) {
|
||||
Player.Message(p, "%HAvailable brushes: %S" + AvailableBrushes);
|
||||
Player.Message(p, "%HAvailable brushes: %S" + BrushFactory.Available);
|
||||
} else if (brush == null) {
|
||||
Player.Message(p, "No brush found with name \"" + args[0] + "\".");
|
||||
Player.Message(p, "Available brushes: " + AvailableBrushes);
|
||||
Player.Message(p, "No brush found with name \"{0}\".", args[0]);
|
||||
Player.Message(p, "Available brushes: " + BrushFactory.Available);
|
||||
} else {
|
||||
Player.Message(p, "Set your brush to: " + brush);
|
||||
p.BrushName = brush;
|
||||
Player.Message(p, "Set your brush to: " + brush.Name);
|
||||
p.BrushName = brush.Name;
|
||||
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) {
|
||||
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, "%T/help brush [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. " +
|
||||
"If no arguments are given, draws with your currently held block.");
|
||||
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) {
|
||||
string brush = FindBrush(message);
|
||||
BrushFactory brush = BrushFactory.Find(message);
|
||||
if (brush == null) {
|
||||
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 {
|
||||
Player.MessageLines(p, BrushFactory.BrushesHelp[brush]);
|
||||
Player.MessageLines(p, brush.Help);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,12 +34,12 @@ namespace MCGalaxy.Commands.Building {
|
||||
DrawArgs cpos = (DrawArgs)state;
|
||||
cpos.block = type; cpos.extBlock = extType;
|
||||
DrawOp op = null;
|
||||
Func<BrushArgs, Brush> constructor = null;
|
||||
BrushFactory factory = null;
|
||||
|
||||
switch (cpos.mode) {
|
||||
case DrawMode.solid:
|
||||
op = new CuboidDrawOp();
|
||||
constructor = SolidBrush.Process; break;
|
||||
factory = BrushFactory.Find("normal"); break;
|
||||
case DrawMode.normal:
|
||||
op = new CuboidDrawOp(); break;
|
||||
case DrawMode.hollow:
|
||||
@ -48,16 +48,16 @@ namespace MCGalaxy.Commands.Building {
|
||||
op = new CuboidWallsDrawOp(); break;
|
||||
case DrawMode.holes:
|
||||
op = new CuboidDrawOp();
|
||||
constructor = CheckeredBrush.Process; break;
|
||||
factory = BrushFactory.Find("checkered"); break;
|
||||
case DrawMode.wire:
|
||||
op = new CuboidWireframeDrawOp(); break;
|
||||
case DrawMode.random:
|
||||
op = new CuboidDrawOp();
|
||||
constructor = RandomBrush.Process; break;
|
||||
factory = BrushFactory.Find("random"); break;
|
||||
}
|
||||
|
||||
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;
|
||||
return DrawOp.DoDrawOp(op, brush, p, marks);
|
||||
}
|
||||
|
@ -57,10 +57,10 @@ namespace MCGalaxy.Commands.Building {
|
||||
string[] args = message.Split(' ');
|
||||
|
||||
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;
|
||||
} 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;
|
||||
}
|
||||
return DrawOp.DoDrawOp(op, null, p, m);
|
||||
|
@ -48,16 +48,16 @@ namespace MCGalaxy.Commands.Building {
|
||||
int block = DrawCmd.GetBlock(p, parts[0], out extBlock);
|
||||
if (block == -1) return false;
|
||||
|
||||
string brushName = CmdBrush.FindBrush(parts[1]);
|
||||
if (brushName == null) {
|
||||
Player.Message(p, "No brush found with name \"" + parts[1] + "\".");
|
||||
Player.Message(p, "Available brushes: " + CmdBrush.AvailableBrushes);
|
||||
BrushFactory factory = BrushFactory.Find(parts[1]);
|
||||
if (factory == null) {
|
||||
Player.Message(p, "No brush found with name \"{0}\".", parts[1]);
|
||||
Player.Message(p, "Available brushes: " + BrushFactory.Available);
|
||||
return false;
|
||||
}
|
||||
|
||||
string brushMessage = parts.Length > 2 ? parts[2].ToLower() : "";
|
||||
BrushArgs args = new BrushArgs(p, brushMessage, type, extType);
|
||||
Brush brush = BrushFactory.Brushes[brushName](args);
|
||||
Brush brush = factory.Construct(args);
|
||||
if (brush == null) return false;
|
||||
|
||||
DrawOp drawOp = null;
|
||||
|
@ -42,11 +42,11 @@ namespace MCGalaxy.Commands.Building {
|
||||
cpos.block = type; cpos.extBlock = extType;
|
||||
|
||||
DrawOp op = null;
|
||||
Func<BrushArgs, Brush> constructor = null;
|
||||
BrushFactory factory = null;
|
||||
switch (cpos.mode) {
|
||||
case DrawMode.solid:
|
||||
op = new AdvSphereDrawOp();
|
||||
constructor = SolidBrush.Process; break;
|
||||
factory = BrushFactory.Find("normal"); break;
|
||||
case DrawMode.hollow:
|
||||
op = new AdvHollowSphereDrawOp(); break;
|
||||
case DrawMode.circle:
|
||||
@ -55,7 +55,7 @@ namespace MCGalaxy.Commands.Building {
|
||||
op = new AdvSphereDrawOp(); break;
|
||||
}
|
||||
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;
|
||||
|
||||
Vec3S32 p0 = m[0];
|
||||
|
@ -70,16 +70,16 @@ namespace MCGalaxy.Commands.Building {
|
||||
|
||||
static Brush ParseBrush(string raw, Player p, byte block, byte extBlock) {
|
||||
string[] parts = raw.SplitSpaces(2);
|
||||
string brushName = CmdBrush.FindBrush(parts[0]);
|
||||
if (brushName == null) {
|
||||
BrushFactory brush = BrushFactory.Find(parts[0]);
|
||||
if (brush == null) {
|
||||
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;
|
||||
}
|
||||
|
||||
string brushArgs = parts.Length >= 2 ? parts[1].ToLower() : "";
|
||||
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; }
|
||||
|
@ -73,7 +73,7 @@ namespace MCGalaxy.Commands.Building {
|
||||
}
|
||||
|
||||
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;
|
||||
string brushMsg = "";
|
||||
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 (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);
|
||||
return constructor(args);
|
||||
return factory.Construct(args);
|
||||
}
|
||||
|
||||
protected struct DrawArgs {
|
||||
|
@ -35,7 +35,8 @@ namespace MCGalaxy.Commands.Building {
|
||||
|
||||
bool DoReplace(Player p, Vec3S32[] marks, object state, byte type, byte 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;
|
||||
|
||||
DrawOp drawOp = new CuboidDrawOp();
|
||||
@ -76,7 +77,7 @@ namespace MCGalaxy.Commands.Building {
|
||||
ushort z2 = (ushort)(p.level.Length - 1);
|
||||
|
||||
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;
|
||||
|
||||
DrawOp drawOp = new CuboidDrawOp();
|
||||
|
@ -31,24 +31,24 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
/// <summary> Creates a brush from the given arguments,
|
||||
/// 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
|
||||
= new Dictionary<string, Func<BrushArgs, Brush>> {
|
||||
{ "normal", SolidBrush.Process }, { "paste", PasteBrush.Process },
|
||||
{ "checkered", CheckeredBrush.Process }, { "rainbow", RainbowBrush.Process },
|
||||
{ "bwrainbow", BWRainbowBrush.Process }, { "striped", StripedBrush.Process },
|
||||
{ "replace", ReplaceBrush.Process }, { "replacenot", ReplaceNotBrush.Process },
|
||||
{ "random", RandomBrush.Process }, { "cloudy", CloudyBrush.Process },
|
||||
public static List<BrushFactory> Brushes = new List<BrushFactory>() {
|
||||
new SolidBrushFactory(), new CheckeredBrushFactory(),
|
||||
new StripedBrushFactory(), new PasteBrushFactory(),
|
||||
new ReplaceBrushFactory(), new ReplaceNotBrushFactory(),
|
||||
new RainbowBrushFactory(), new BWRainbowBrushFactory(),
|
||||
new RandomBrushFactory(), new CloudyBrushFactory(),
|
||||
};
|
||||
|
||||
public static Dictionary<string, string[]> BrushesHelp = new Dictionary<string, string[]> {
|
||||
{ "normal", SolidBrush.HelpString }, { "paste", PasteBrush.HelpString },
|
||||
{ "checkered", CheckeredBrush.HelpString }, { "rainbow", RainbowBrush.HelpString },
|
||||
{ "bwrainbow", BWRainbowBrush.HelpString }, { "striped", StripedBrush.HelpString },
|
||||
{ "replace", ReplaceBrush.HelpString }, { "replacenot", ReplaceNotBrush.HelpString },
|
||||
{ "random", RandomBrush.HelpString }, { "cloudy", CloudyBrush.HelpString },
|
||||
};
|
||||
public static string Available { get { return Brushes.Join(b => b.Name); } }
|
||||
|
||||
public static BrushFactory Find(string name) {
|
||||
foreach (BrushFactory brush in Brushes) {
|
||||
if (brush.Name.CaselessEq(name)) return brush;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public struct BrushArgs {
|
||||
|
93
Drawing/BrushFactories/CloudyBrush.cs
Normal file
93
Drawing/BrushFactories/CloudyBrush.cs
Normal 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;
|
||||
}
|
||||
}
|
@ -1,96 +1,117 @@
|
||||
/*
|
||||
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 {
|
||||
|
||||
/// <summary> Contains helper methods for brushes that have blocks with
|
||||
/// optional frequency counts (e.g. random and cloudy brushes) </summary>
|
||||
public static class FrequencyBrush {
|
||||
|
||||
public static ExtBlock[] GetBlocks(BrushArgs args, out int[] count,
|
||||
Predicate<string> filter, Predicate<string> handler) {
|
||||
string[] parts = args.Message.Split(' ');
|
||||
Player p = args.Player;
|
||||
ExtBlock[] blocks;
|
||||
GetRaw(parts, filter, args, out blocks, out count);
|
||||
|
||||
for (int i = 0, j = 0; i < parts.Length; i++ ) {
|
||||
if (parts[i] == "") continue;
|
||||
|
||||
// Brush specific args
|
||||
if (!filter(parts[i])) {
|
||||
if (!handler(parts[i])) return null;
|
||||
continue;
|
||||
}
|
||||
|
||||
byte extType = 0;
|
||||
int sepIndex = parts[i].IndexOf('/');
|
||||
string block = sepIndex >= 0 ? parts[i].Substring(0, sepIndex) : parts[i];
|
||||
int type = DrawCmd.GetBlock(p, block, out extType);
|
||||
if (type == -1) return null;
|
||||
|
||||
blocks[j].Block = (byte)type; blocks[j].Ext = extType;
|
||||
if (sepIndex < 0) { j++; continue; }
|
||||
|
||||
int chance;
|
||||
if (!int.TryParse(parts[i].Substring(sepIndex + 1), out chance)
|
||||
|| chance <= 0 || chance > 10000) {
|
||||
Player.Message(p, "frequency must be an integer between 1 and 10,000."); return null;
|
||||
}
|
||||
count[j] = chance;
|
||||
j++;
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
static void GetRaw(string[] parts, Predicate<string> filter, BrushArgs args,
|
||||
out ExtBlock[] blocks, out int[] count) {;
|
||||
int bCount = 0;
|
||||
for (int i = 0; i < parts.Length; i++) {
|
||||
if (parts[i] == "" || !filter(parts[i])) continue;
|
||||
bCount++;
|
||||
}
|
||||
|
||||
// For 0 or 1 blocks given, treat second block as 'unchanged'.
|
||||
blocks = new ExtBlock[Math.Max(2, bCount)];
|
||||
count = new int[blocks.Length];
|
||||
for (int i = 0; i < count.Length; i++) {
|
||||
count[i] = 1;
|
||||
blocks[i] = new ExtBlock(Block.Zero, 0);
|
||||
}
|
||||
|
||||
// No blocks given, assume first is held block
|
||||
if (bCount == 0)
|
||||
blocks[0] = new ExtBlock(args.Block, args.ExtBlock);
|
||||
}
|
||||
|
||||
public static ExtBlock[] Combine(ExtBlock[] toAffect, int[] count) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < count.Length; i++) sum += count[i];
|
||||
|
||||
ExtBlock[] blocks = new ExtBlock[sum];
|
||||
for (int i = 0, index = 0; i < toAffect.Length; i++) {
|
||||
for (int j = 0; j < count[i]; j++)
|
||||
blocks[index++] = toAffect[i];
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
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 {
|
||||
|
||||
/// <summary> Contains helper methods for brushes that have blocks with
|
||||
/// optional frequency counts (e.g. random and cloudy brushes) </summary>
|
||||
public static class FrequencyBrush {
|
||||
|
||||
public static ExtBlock[] GetBlocks(BrushArgs args, out int[] count,
|
||||
Predicate<string> filter, Predicate<string> handler) {
|
||||
string[] parts = args.Message.Split(' ');
|
||||
Player p = args.Player;
|
||||
ExtBlock[] blocks;
|
||||
GetRaw(parts, filter, args, out blocks, out count);
|
||||
|
||||
for (int i = 0, j = 0; i < parts.Length; i++ ) {
|
||||
if (parts[i] == "") continue;
|
||||
|
||||
// Brush specific args
|
||||
if (!filter(parts[i])) {
|
||||
if (!handler(parts[i])) return null;
|
||||
continue;
|
||||
}
|
||||
|
||||
byte extType = 0;
|
||||
int sepIndex = parts[i].IndexOf('/');
|
||||
string block = sepIndex >= 0 ? parts[i].Substring(0, sepIndex) : parts[i];
|
||||
int type = DrawCmd.GetBlock(p, block, out extType);
|
||||
if (type == -1) return null;
|
||||
|
||||
blocks[j].Block = (byte)type; blocks[j].Ext = extType;
|
||||
if (sepIndex < 0) { j++; continue; }
|
||||
|
||||
int chance;
|
||||
if (!int.TryParse(parts[i].Substring(sepIndex + 1), out chance)
|
||||
|| chance <= 0 || chance > 10000) {
|
||||
Player.Message(p, "frequency must be an integer between 1 and 10,000."); return null;
|
||||
}
|
||||
count[j] = chance;
|
||||
j++;
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
static void GetRaw(string[] parts, Predicate<string> filter, BrushArgs args,
|
||||
out ExtBlock[] blocks, out int[] count) {;
|
||||
int bCount = 0;
|
||||
for (int i = 0; i < parts.Length; i++) {
|
||||
if (parts[i] == "" || !filter(parts[i])) continue;
|
||||
bCount++;
|
||||
}
|
||||
|
||||
// For 0 or 1 blocks given, treat second block as 'unchanged'.
|
||||
blocks = new ExtBlock[Math.Max(2, bCount)];
|
||||
count = new int[blocks.Length];
|
||||
for (int i = 0; i < count.Length; i++) {
|
||||
count[i] = 1;
|
||||
blocks[i] = new ExtBlock(Block.Zero, 0);
|
||||
}
|
||||
|
||||
// No blocks given, assume first is held block
|
||||
if (bCount == 0)
|
||||
blocks[0] = new ExtBlock(args.Block, args.ExtBlock);
|
||||
}
|
||||
|
||||
public static ExtBlock[] Combine(ExtBlock[] toAffect, int[] count) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < count.Length; i++) sum += count[i];
|
||||
|
||||
ExtBlock[] blocks = new ExtBlock[sum];
|
||||
for (int i = 0, index = 0; i < toAffect.Length; i++) {
|
||||
for (int j = 0; j < count[i]; j++)
|
||||
blocks[index++] = toAffect[i];
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
90
Drawing/BrushFactories/ReplaceBrushes.cs
Normal file
90
Drawing/BrushFactories/ReplaceBrushes.cs
Normal 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); }
|
||||
}
|
||||
}
|
147
Drawing/BrushFactories/SimpleBrushes.cs
Normal file
147
Drawing/BrushFactories/SimpleBrushes.cs
Normal 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(); }
|
||||
}
|
||||
}
|
@ -24,9 +24,6 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
/// <summary> Human friendly name of this brush. </summary>
|
||||
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>
|
||||
public virtual void Configure(DrawOp op, Player p) { }
|
||||
|
||||
|
@ -20,8 +20,7 @@ using System.Collections.Generic;
|
||||
using MCGalaxy.Commands.Building;
|
||||
using MCGalaxy.Drawing.Ops;
|
||||
|
||||
namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
namespace MCGalaxy.Drawing.Brushes {
|
||||
public sealed class CheckeredBrush : Brush {
|
||||
readonly byte block1, extBlock1, block2, extBlock2;
|
||||
|
||||
@ -32,32 +31,6 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
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) {
|
||||
return ((op.Coords.X + op.Coords.Y + op.Coords.Z) & 1) == 0 ? block1 : block2;
|
||||
}
|
||||
|
@ -45,70 +45,6 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
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) {
|
||||
Player.Message(p, "Calculating noise distribution...");
|
||||
// Initalise our noise histogram
|
||||
@ -176,14 +112,6 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
return blocks[next].Block;
|
||||
}
|
||||
|
||||
public override byte NextExtBlock(DrawOp op) {
|
||||
return blocks[next].Ext;
|
||||
}
|
||||
}
|
||||
|
||||
public struct NoiseArgs {
|
||||
public byte Octaves;
|
||||
public int Seed;
|
||||
public float Frequency, Amplitude, Persistence, Lacunarity;
|
||||
public override byte NextExtBlock(DrawOp op) { return blocks[next].Ext; }
|
||||
}
|
||||
}
|
||||
|
@ -20,32 +20,14 @@ using System.Collections.Generic;
|
||||
using MCGalaxy.Commands;
|
||||
using MCGalaxy.Drawing.Ops;
|
||||
|
||||
namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
namespace MCGalaxy.Drawing.Brushes {
|
||||
public sealed class PasteBrush : Brush {
|
||||
readonly CopyState state;
|
||||
|
||||
public PasteBrush(CopyState state) {
|
||||
this.state = state;
|
||||
}
|
||||
public PasteBrush(CopyState state) { this.state = state; }
|
||||
|
||||
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) {
|
||||
Vec3U16 p = LocalCoords(op);
|
||||
return state.Blocks[state.GetIndex(p.X, p.Y, p.Z)];
|
||||
|
@ -26,14 +26,6 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
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) {
|
||||
int offset = (op.Coords.X + op.Coords.Y + op.Coords.Z) % 13;
|
||||
if (offset < 0) offset += 13;
|
||||
@ -41,14 +33,6 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
}
|
||||
|
||||
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 {
|
||||
@ -63,18 +47,7 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
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 static Brush Process(BrushArgs args) {
|
||||
return new BWRainbowBrush();
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class RandomRainbowBrush : Brush {
|
||||
@ -82,15 +55,9 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
public override string Name { get { return "RandomRainbow"; } }
|
||||
|
||||
public override string[] Help { get { return new string[0]; } }
|
||||
public RandomRainbowBrush() { rnd = new Random(); }
|
||||
|
||||
public RandomRainbowBrush() {
|
||||
rnd = new Random();
|
||||
}
|
||||
|
||||
public RandomRainbowBrush(int seed) {
|
||||
rnd = new Random(seed);
|
||||
}
|
||||
public RandomRainbowBrush(int seed) { rnd = new Random(seed); }
|
||||
|
||||
public override byte NextBlock(DrawOp op) {
|
||||
return (byte)rnd.Next(Block.red, Block.darkgrey);
|
||||
|
@ -33,24 +33,6 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
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;
|
||||
const int mask = 0x7fffffff;
|
||||
public override byte NextBlock(DrawOp op) {
|
||||
|
@ -20,8 +20,7 @@ using System.Collections.Generic;
|
||||
using MCGalaxy.Commands.Building;
|
||||
using MCGalaxy.Drawing.Ops;
|
||||
|
||||
namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
namespace MCGalaxy.Drawing.Brushes {
|
||||
public sealed class ReplaceBrush : Brush {
|
||||
readonly ExtBlock[] include;
|
||||
readonly ExtBlock target;
|
||||
@ -32,61 +31,6 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
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) {
|
||||
ushort x = op.Coords.X, y = op.Coords.Y, z = op.Coords.Z;
|
||||
byte tile = op.Level.GetTile(x, y, z), extTile = 0;
|
||||
@ -100,9 +44,7 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
return Block.Zero;
|
||||
}
|
||||
|
||||
public override byte NextExtBlock(DrawOp op) {
|
||||
return target.Ext;
|
||||
}
|
||||
public override byte NextExtBlock(DrawOp op) { return target.Ext; }
|
||||
}
|
||||
|
||||
public sealed class ReplaceNotBrush : Brush {
|
||||
@ -115,18 +57,6 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
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) {
|
||||
ushort x = op.Coords.X, y = op.Coords.Y, z = op.Coords.Z;
|
||||
byte tile = op.Level.GetTile(x, y, z), extTile = 0;
|
||||
@ -140,8 +70,6 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
return target.Block;
|
||||
}
|
||||
|
||||
public override byte NextExtBlock(DrawOp op) {
|
||||
return target.Ext;
|
||||
}
|
||||
public override byte NextExtBlock(DrawOp op) { return target.Ext; }
|
||||
}
|
||||
}
|
||||
|
@ -19,37 +19,19 @@ using System;
|
||||
using MCGalaxy.Commands.Building;
|
||||
using MCGalaxy.Drawing.Ops;
|
||||
|
||||
namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
namespace MCGalaxy.Drawing.Brushes {
|
||||
public sealed class SolidBrush : Brush {
|
||||
readonly byte type, extType;
|
||||
readonly byte block, extBlock;
|
||||
|
||||
public SolidBrush(byte type, byte extType) {
|
||||
this.type = type;
|
||||
this.extType = extType;
|
||||
this.block = type;
|
||||
this.extBlock = extType;
|
||||
}
|
||||
|
||||
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 [] {
|
||||
"%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; }
|
||||
public override byte NextExtBlock(DrawOp op) { return extBlock; }
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,7 @@ using System.Collections.Generic;
|
||||
using MCGalaxy.Commands.Building;
|
||||
using MCGalaxy.Drawing.Ops;
|
||||
|
||||
namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
namespace MCGalaxy.Drawing.Brushes {
|
||||
public sealed class StripedBrush : Brush {
|
||||
readonly byte block1, extBlock1, block2, extBlock2;
|
||||
|
||||
@ -32,32 +31,6 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
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) {
|
||||
return ((op.Coords.X + op.Coords.Y + op.Coords.Z) & 3) <= 1 ? block1 : block2;
|
||||
}
|
||||
|
@ -415,7 +415,6 @@
|
||||
<Compile Include="Database\SQLite\SQLiteParameterisedQuery.cs" />
|
||||
<Compile Include="Drawing\Brushes\Brush.cs" />
|
||||
<Compile Include="Drawing\Brushes\CheckeredBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\FrequencyBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\CloudyBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\PasteBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\RainbowBrush.cs" />
|
||||
@ -424,6 +423,10 @@
|
||||
<Compile Include="Drawing\Brushes\SolidBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\StripedBrush.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\DrawOps\AdvConeDrawOps.cs" />
|
||||
<Compile Include="Drawing\DrawOps\AdvDrawOps.cs" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user