mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-29 00:26:15 -04:00
Rename NoiseBrush to CloudyBrush and allow brushes to perform configuration/calculation for particular draw ops.
This commit is contained in:
parent
c4af44ecfc
commit
ba62aae7af
@ -30,6 +30,9 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
/// <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) { }
|
||||
|
||||
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<string, string[]> BrushesHelp = new Dictionary<string, string[]> {
|
||||
@ -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 },
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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] <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 arguments format: %T<first letter of arg>_<value>",
|
||||
"%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] <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 arguments format: %T<first letter of arg>_<value>",
|
||||
"%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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -432,7 +432,7 @@
|
||||
<Compile Include="Drawing\Brushes\Brush.cs" />
|
||||
<Compile Include="Drawing\Brushes\CheckeredBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\FrequencyBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\NoiseBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\CloudyBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\PasteBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\RainbowBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\RandomBrush.cs" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user