From ba62aae7afea907627a02195edb6780f02f2c990 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 11 May 2016 12:26:27 +1000 Subject: [PATCH] Rename NoiseBrush to CloudyBrush and allow brushes to perform configuration/calculation for particular draw ops. --- Drawing/Brushes/Brush.cs | 7 +- .../Brushes/{NoiseBrush.cs => CloudyBrush.cs} | 263 +++++++++--------- Drawing/DrawOps/DrawOp.Performer.cs | 2 + MCGalaxy_.csproj | 2 +- 4 files changed, 142 insertions(+), 132 deletions(-) rename Drawing/Brushes/{NoiseBrush.cs => CloudyBrush.cs} (90%) diff --git a/Drawing/Brushes/Brush.cs b/Drawing/Brushes/Brush.cs index 24ed0e702..b1761b824 100644 --- a/Drawing/Brushes/Brush.cs +++ b/Drawing/Brushes/Brush.cs @@ -30,6 +30,9 @@ namespace MCGalaxy.Drawing.Brushes { /// Description of the brush, in addition to its syntax. public abstract string[] Help { get; } + /// Performs calcuations (if necessary) for the given drawop. + public virtual void Configure(DrawOp op, Player p) { } + public abstract byte NextBlock(DrawOp op); public abstract byte NextExtBlock(DrawOp op); @@ -40,7 +43,7 @@ namespace MCGalaxy.Drawing.Brushes { { "checkered", CheckeredBrush.Process }, { "rainbow", RainbowBrush.Process }, { "bwrainbow", BWRainbowBrush.Process }, { "striped", StripedBrush.Process }, { "replace", ReplaceBrush.Process }, { "replacenot", ReplaceNotBrush.Process }, - { "random", RandomBrush.Process }, { "noise", NoiseBrush.Process }, + { "random", RandomBrush.Process }, { "cloudy", CloudyBrush.Process }, }; public static Dictionary BrushesHelp = new Dictionary { @@ -48,7 +51,7 @@ namespace MCGalaxy.Drawing.Brushes { { "checkered", CheckeredBrush.HelpString }, { "rainbow", RainbowBrush.HelpString }, { "bwrainbow", BWRainbowBrush.HelpString }, { "striped", StripedBrush.HelpString }, { "replace", ReplaceBrush.HelpString }, { "replacenot", ReplaceNotBrush.HelpString }, - { "random", RandomBrush.HelpString }, { "noise", NoiseBrush.HelpString }, + { "random", RandomBrush.HelpString }, { "cloudy", CloudyBrush.HelpString }, }; } diff --git a/Drawing/Brushes/NoiseBrush.cs b/Drawing/Brushes/CloudyBrush.cs similarity index 90% rename from Drawing/Brushes/NoiseBrush.cs rename to Drawing/Brushes/CloudyBrush.cs index ad878b1ed..4779ffbd9 100644 --- a/Drawing/Brushes/NoiseBrush.cs +++ b/Drawing/Brushes/CloudyBrush.cs @@ -1,129 +1,134 @@ -/* - 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 System.Collections.Generic; -using MCGalaxy.Commands; -using MCGalaxy.Drawing.Ops; -using MCGalaxy.Generator; - -namespace MCGalaxy.Drawing.Brushes { - - public sealed class NoiseBrush : FrequencyBrush { - readonly ExtBlock[] blocks; - readonly ImprovedNoise noise; - - public NoiseBrush(ExtBlock[] blocks, NoiseArgs n) { - this.blocks = blocks; - Random r = n.Seed == int.MinValue ? new Random() : new Random(n.Seed); - noise = new ImprovedNoise(r); - - noise.Frequency = n.Frequency; - noise.Amplitude = n.Amplitude; - noise.Octaves = n.Octaves; - noise.Lacunarity = n.Lacunarity; - noise.Persistence = n.Persistence; - } - - public override string Name { get { return "Noise"; } } - - public override string[] Help { get { return HelpString; } } - - public static string[] HelpString = new [] { - "%TArguments: [block1/frequency] [block2] ..", - "%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 arguments format: %T_", - "%H Arguments: amplitude, frequency, lacunarity, octaves, persistence, seed", - }; - - public static Brush Process(BrushArgs args) { - NoiseArgs n = default(NoiseArgs); - n.Amplitude = 1; n.Frequency = 1; n.Octaves = 1; - n.Seed = int.MinValue; n.Persistence = 2; n.Lacunarity = 2; - if (args.Message == "") - return new NoiseBrush(new[] { new ExtBlock(args.Type, args.ExtType), - new ExtBlock(Block.Zero, 0) }, n); - - string[] parts = args.Message.Split(' '); - int[] count = new int[parts.Length]; - ExtBlock[] toAffect = GetBlocks(args.Player, parts, count, - Filter, arg => Handler(arg, args.Player, ref n)); - - if (toAffect == null) return null; - ExtBlock[] blocks = Combine(toAffect, count); - return new NoiseBrush(blocks, n); - } - - // We want to handle non block options. - static bool Filter(string arg) { - if (arg.Length < 2) return true; - return 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; - } - - int next; - public override byte NextBlock(DrawOp op) { - float N = noise.NormalisedNoise(op.Coords.X, op.Coords.Y, op.Coords.Z); - N = (N + 1) * 0.5f; // rescale to [0, 1]; - next = (int)(N * blocks.Length); - - if (next < 0) next = 0; - if (next >= blocks.Length) next = blocks.Length - 1; - return blocks[next].Type; - } - - public override byte NextExtBlock(DrawOp op) { - return blocks[next].ExtType; - } - } - - public struct NoiseArgs { - public byte Octaves; - public int Seed; - public float Frequency, Amplitude, Persistence, Lacunarity; - } -} +/* + 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 System.Collections.Generic; +using MCGalaxy.Commands; +using MCGalaxy.Drawing.Ops; +using MCGalaxy.Generator; + +namespace MCGalaxy.Drawing.Brushes { + + public sealed class CloudyBrush : FrequencyBrush { + readonly ExtBlock[] blocks; + readonly ImprovedNoise noise; + + public CloudyBrush(ExtBlock[] blocks, NoiseArgs n) { + this.blocks = blocks; + Random r = n.Seed == int.MinValue ? new Random() : new Random(n.Seed); + noise = new ImprovedNoise(r); + + noise.Frequency = n.Frequency; + noise.Amplitude = n.Amplitude; + noise.Octaves = n.Octaves; + noise.Lacunarity = n.Lacunarity; + noise.Persistence = n.Persistence; + } + + public override string Name { get { return "Cloudy"; } } + + public override string[] Help { get { return HelpString; } } + + public static string[] HelpString = new [] { + "%TArguments: [block1/frequency] [block2] ..", + "%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 arguments format: %T_", + "%H Arguments: amplitude, frequency, lacunarity, octaves, persistence, seed", + }; + + public static Brush Process(BrushArgs args) { + NoiseArgs n = default(NoiseArgs); + n.Amplitude = 1; n.Frequency = 1; n.Octaves = 1; + n.Seed = int.MinValue; n.Persistence = 2; n.Lacunarity = 2; + if (args.Message == "") + return new CloudyBrush(new[] { new ExtBlock(args.Type, args.ExtType), + new ExtBlock(Block.Zero, 0) }, n); + + string[] parts = args.Message.Split(' '); + int[] count = new int[parts.Length]; + ExtBlock[] toAffect = GetBlocks(args.Player, parts, count, + Filter, arg => Handler(arg, args.Player, ref n)); + + if (toAffect == null) return null; + ExtBlock[] blocks = Combine(toAffect, count); + return new CloudyBrush(blocks, n); + } + + // We want to handle non block options. + static bool Filter(string arg) { + if (arg.Length < 2) return true; + return 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 override void Configure(DrawOp op, Player p) { + Player.Message(p, "Calculating noise distribution..."); + Player.Message(p, "Finished calculating, now drawing."); + } + + int next; + public override byte NextBlock(DrawOp op) { + float N = noise.NormalisedNoise(op.Coords.X, op.Coords.Y, op.Coords.Z); + N = (N + 1) * 0.5f; // rescale to [0, 1]; + next = (int)(N * blocks.Length); + + if (next < 0) next = 0; + if (next >= blocks.Length) next = blocks.Length - 1; + return blocks[next].Type; + } + + public override byte NextExtBlock(DrawOp op) { + return blocks[next].ExtType; + } + } + + public struct NoiseArgs { + public byte Octaves; + public int Seed; + public float Frequency, Amplitude, Persistence, Lacunarity; + } +} diff --git a/Drawing/DrawOps/DrawOp.Performer.cs b/Drawing/DrawOps/DrawOp.Performer.cs index f5cd05316..5261fc32a 100644 --- a/Drawing/DrawOps/DrawOp.Performer.cs +++ b/Drawing/DrawOps/DrawOp.Performer.cs @@ -116,6 +116,8 @@ namespace MCGalaxy.Drawing.Ops { entry.Start = Server.StartTime.AddTicks(timeDelta * TimeSpan.TicksPerSecond); bool needReveal = item.Op.DetermineDrawOpMethod(item.Level, item.Affected); + if (item.Brush != null) + item.Brush.Configure(item.Op, p); item.Op.Perform(item.Marks, p, item.Level, item.Brush); timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds; entry.End = Server.StartTime.AddTicks(timeDelta * TimeSpan.TicksPerSecond); diff --git a/MCGalaxy_.csproj b/MCGalaxy_.csproj index 45f2e31bd..4394f2307 100644 --- a/MCGalaxy_.csproj +++ b/MCGalaxy_.csproj @@ -432,7 +432,7 @@ - +