Start work on separate brush factory code (So we can validate arguments at the time the player first does /z, instead of by the time they have placed their second block.

This commit is contained in:
UnknownShadow200 2016-08-04 11:42:58 +10:00
parent fdb00cadc1
commit b3ae2052d1
8 changed files with 132 additions and 83 deletions

View File

@ -51,7 +51,7 @@ namespace MCGalaxy.Commands.Building {
}
internal static string FindBrush(string message) {
foreach (var brush in Brush.Brushes) {
foreach (var brush in BrushFactory.Brushes) {
if (brush.Key.CaselessEq(message))
return brush.Key;
}
@ -59,7 +59,7 @@ namespace MCGalaxy.Commands.Building {
}
internal static string AvailableBrushes {
get { return Brush.Brushes.Keys.Join(); }
get { return BrushFactory.Brushes.Keys.Join(); }
}
public override void Help(Player p) {
@ -80,7 +80,7 @@ namespace MCGalaxy.Commands.Building {
Player.Message(p, "No brush found with name \"{0}\".", message);
Player.Message(p, "%HAvailable brushes: %S" + AvailableBrushes);
} else {
Player.MessageLines(p, Brush.BrushesHelp[brush]);
Player.MessageLines(p, BrushFactory.BrushesHelp[brush]);
}
}
}

View File

@ -57,7 +57,7 @@ namespace MCGalaxy.Commands.Building {
string brushMessage = parts.Length > 2 ? parts[2].ToLower() : "";
BrushArgs args = new BrushArgs(p, brushMessage, type, extType);
Brush brush = Brush.Brushes[brushName](args);
Brush brush = BrushFactory.Brushes[brushName](args);
if (brush == null) return false;
DrawOp drawOp = null;

View File

@ -79,7 +79,7 @@ namespace MCGalaxy.Commands.Building {
string brushArgs = parts.Length >= 2 ? parts[1].ToLower() : "";
BrushArgs args = new BrushArgs(p, brushArgs, block, extBlock);
return Brush.Brushes[brushName](args);
return BrushFactory.Brushes[brushName](args);
}
struct DrawArgs { public int mode; public string brushMsg; }

View File

@ -83,7 +83,7 @@ namespace MCGalaxy.Commands.Building {
if (end >= 0) brushMsg = dArgs.message.Substring(0, end);
if (brushMsg == "") brushMsg = p.DefaultBrushArgs;
if (constructor == null) constructor = Brush.Brushes[p.BrushName];
if (constructor == null) constructor = BrushFactory.Brushes[p.BrushName];
BrushArgs args = new BrushArgs(p, brushMsg, dArgs.block, dArgs.extBlock);
return constructor(args);
}

View File

@ -0,0 +1,73 @@
/*
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;
namespace MCGalaxy.Drawing.Brushes {
public abstract class BrushFactory {
/// <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> Creates a brush from the given arguments,
/// returning null if invalid arguments are specified. </summary>
public abstract Brush Process(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 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 struct BrushArgs {
/// <summary> Player that is providing arguments for this brush. </summary>
public Player Player;
/// <summary> Raw message provided for arguments to the brush, including spaces. </summary>
public string Message;
/// <summary> Raw block the player is currently holding. </summary>
/// <remarks> If the player is holding a custom block,
/// this value is Block.custom_block and ExtBlock is the actual block.</remarks>
public byte Block;
/// <summary> Custom block the player is currently holding. </summary>
public byte ExtBlock;
public BrushArgs(Player p, string message, byte block, byte extBlock) {
Player = p; Message = message; Block = block; ExtBlock = extBlock;
}
}
}

View File

@ -16,12 +16,9 @@
permissions and limitations under the Licenses.
*/
using System;
using System.Collections.Generic;
using MCGalaxy.Commands;
using MCGalaxy.Drawing.Ops;
namespace MCGalaxy.Drawing.Brushes {
public abstract class Brush {
/// <summary> Human friendly name of this brush. </summary>
@ -33,35 +30,12 @@ namespace MCGalaxy.Drawing.Brushes {
/// <summary> Performs calcuations (if necessary) for the given drawop. </summary>
public virtual void Configure(DrawOp op, Player p) { }
/// <summary> Returns the next block that should be placed in the world,
/// based on the draw operation's current state. </summary>
public abstract byte NextBlock(DrawOp op);
/// <summary> Returns the next custom block that should be placed in the world,
/// based on the draw operation's current state. </summary>
public abstract byte NextExtBlock(DrawOp op);
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 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 struct BrushArgs {
public Player Player;
public string Message;
public byte Block, ExtBlock; // currently holding
public BrushArgs(Player p, string message, byte block, byte extBlock) {
Player = p; Message = message; Block = block; ExtBlock = extBlock;
}
}
}

View File

@ -423,6 +423,7 @@
<Compile Include="Drawing\Brushes\ReplaceBrush.cs" />
<Compile Include="Drawing\Brushes\SolidBrush.cs" />
<Compile Include="Drawing\Brushes\StripedBrush.cs" />
<Compile Include="Drawing\BrushFactories\BrushFactory.cs" />
<Compile Include="Drawing\CopyState.cs" />
<Compile Include="Drawing\DrawOps\AdvConeDrawOps.cs" />
<Compile Include="Drawing\DrawOps\AdvDrawOps.cs" />
@ -691,6 +692,7 @@
<Folder Include="Drawing\DrawOps" />
<Folder Include="Drawing\Brushes" />
<Folder Include="Drawing\Image" />
<Folder Include="Drawing\BrushFactories" />
<Folder Include="Games\Countdown" />
<Folder Include="Games\LavaSurvival" />
<Folder Include="Games\TntWars" />

View File

@ -18,61 +18,61 @@
using System;
namespace MCGalaxy {
/// <summary>Utility methods for reading/writing big endian integers, and fixed length strings. </summary>
public static class NetUtils {
public static void Write(string str, byte[] array, int offset, bool hasCP437) {
if (hasCP437) WriteCP437(str, array, offset);
else WriteAscii(str, array, offset);
public static short ReadI16(byte[] array, int offset) {
return (short)(array[offset] << 8 | array[offset + 1]);
}
public static void WriteAscii(string str, byte[] array, int offset) {
for (int i = 0; i < 64; i++)
array[offset + i] = (byte)' ';
for (int i = 0; i < Math.Min(str.Length, 64); i++) {
char raw = str[i];
array[offset + i] = raw >= '\u0080' ? (byte)'?' : (byte)raw;
}
}
public static void WriteCP437(string str, byte[] array, int offset) {
for (int i = 0; i < 64; i++)
array[offset + i] = (byte)' ';
for (int i = 0; i < Math.Min(str.Length, 64); i++) {
array[offset + i] = (byte)str[i];
}
}
public static short ReadI16(byte[] array, int offset) {
return (short)(array[offset] << 8 | array[offset + 1]);
}
public static ushort ReadU16(byte[] array, int offset) {
return (ushort)(array[offset] << 8 | array[offset + 1]);
}
return (ushort)(array[offset] << 8 | array[offset + 1]);
}
public static int ReadI32(byte[] array, int offset) {
return array[offset] << 24 | array[offset + 1] << 16
| array[offset + 2] << 8 | array[offset + 3];
}
return array[offset] << 24 | array[offset + 1] << 16
| array[offset + 2] << 8 | array[offset + 3];
}
public static void WriteI16(short value, byte[] array, int index) {
array[index++] = (byte)(value >> 8);
array[index++] = (byte)(value);
}
array[index++] = (byte)(value >> 8);
array[index++] = (byte)(value);
}
public static void WriteU16(ushort value, byte[] array, int index) {
array[index++] = (byte)(value >> 8);
array[index++] = (byte)(value);
}
public static void WriteI32(int value, byte[] array, int index) {
array[index++] = (byte)(value >> 24);
array[index++] = (byte)(value >> 16);
array[index++] = (byte)(value >> 8);
array[index++] = (byte)(value);
}
array[index++] = (byte)(value >> 8);
array[index++] = (byte)(value);
}
public static void WriteI32(int value, byte[] array, int index) {
array[index++] = (byte)(value >> 24);
array[index++] = (byte)(value >> 16);
array[index++] = (byte)(value >> 8);
array[index++] = (byte)(value);
}
public static void Write(string str, byte[] array, int offset, bool hasCP437) {
if (hasCP437) WriteCP437(str, array, offset);
else WriteAscii(str, array, offset);
}
public static void WriteAscii(string str, byte[] array, int offset) {
int count = Math.Min(str.Length, 64);
for (int i = 0; i < count; i++) {
char raw = str[i];
array[offset + i] = raw >= '\u0080' ? (byte)'?' : (byte)raw;
}
for (int i = count; i < 64; i++)
array[offset + i] = (byte)' ';
}
public static void WriteCP437(string str, byte[] array, int offset) {
int count = Math.Min(str.Length, 64);
for (int i = 0; i < count; i++)
array[offset + i] = (byte)str[i];
for (int i = count; i < 64; i++)
array[offset + i] = (byte)' ';
}
}
}