Make Tree code more generic

This commit is contained in:
UnknownShadow200 2017-02-02 17:33:11 +11:00
parent 559b531002
commit 4b6a3abec3
7 changed files with 71 additions and 37 deletions

View File

@ -124,8 +124,8 @@ namespace MCGalaxy.Blocks.Physics {
Tree tree = Tree.Find(lvl.TreeType);
if (tree == null) tree = new NormalTree();
tree.SetData(rand);
tree.Output(x, y, z, (xT, yT, zT, bT) =>
tree.SetData(rand, tree.DefaultValue(rand));
tree.Generate(x, y, z, (xT, yT, zT, bT) =>
{
if (bT == Block.leaf && lvl.GetTile(xT, yT, zT) != Block.air) return;
lvl.Blockchange(xT, yT, zT, bT);

View File

@ -42,6 +42,16 @@ namespace MCGalaxy.Commands.Building {
DrawArgs dArgs = default(DrawArgs);
dArgs.tree = tree;
dArgs.brushMsg = brushMsg;
if (brushMsg != "") {
if (!p.group.CanExecute("brush")) {
Player.Message(p, "You cannot use %T/brush%S, so therefore cannot use %T/tree%S with a brush."); return;
}
Brush brush = ParseBrush(dArgs.brushMsg, p, 0, 0);
if (brush == null) return;
}
Player.Message(p, "Select where you wish your tree to grow");
p.MakeSelection(1, dArgs, DoTree);
}
@ -50,18 +60,14 @@ namespace MCGalaxy.Commands.Building {
DrawArgs dArgs = (DrawArgs)state;
TreeDrawOp op = new TreeDrawOp();
op.Tree = dArgs.tree;
Brush brush = null;
op.Value = dArgs.value;
if (dArgs.brushMsg != "") {
if (!p.group.CanExecute("brush")) {
Player.Message(p, "You cannot use /brush, so therefore cannot use /tree with a brush."); return false;
}
brush = ParseBrush(dArgs.brushMsg, p, type, extType);
if (brush == null) return false;
}
Brush brush = null;
if (dArgs.brushMsg != "") brush = ParseBrush(dArgs.brushMsg, p, type, extType);
return DrawOpPerformer.Do(op, brush, p, marks);
}
static Brush ParseBrush(string raw, Player p, byte block, byte extBlock) {
string[] parts = raw.SplitSpaces(2);
BrushFactory brush = BrushFactory.Find(parts[0]);
@ -76,7 +82,7 @@ namespace MCGalaxy.Commands.Building {
return brush.Construct(args);
}
struct DrawArgs { public Tree tree; public string brushMsg; }
struct DrawArgs { public Tree tree; public string brushMsg; public int value; }
public override void Help(Player p) {
Player.Message(p, "%T/tree [type] %H- Draws a tree.");

View File

@ -37,6 +37,8 @@ namespace MCGalaxy.Drawing.Ops {
public Tree Tree;
static Brush defBrush = new SolidBrush(Block.leaf, 0);
public int Value = -1;
public override long BlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
public override void Perform(Vec3S32[] marks, Brush brush, Action<DrawOpBlock> output) {
@ -44,7 +46,7 @@ namespace MCGalaxy.Drawing.Ops {
Vec3U16 P = Clamp(marks[0]);
Level lvl = Level;
Tree.Output(P.X, P.Y, P.Z, (xT, yT, zT, bT) =>
Tree.Generate(P.X, P.Y, P.Z, (xT, yT, zT, bT) =>
{
if (bT == Block.leaf && lvl.GetTile(xT, yT, zT) != Block.air) return;
@ -58,7 +60,9 @@ namespace MCGalaxy.Drawing.Ops {
public override void SetMarks(Vec3S32[] marks) {
base.SetMarks(marks);
Tree.SetData(random);
int value = Value != -1 ? Value : Tree.DefaultValue(random);
Tree.SetData(random, value);
Max.Y += Tree.height;
Min.X -= Tree.size; Min.Z -= Tree.size;
Max.X += Tree.size; Max.Z += Tree.size;

View File

@ -25,13 +25,15 @@ namespace MCGalaxy.Generator.Foilage {
public sealed class BambooTree : Tree {
public override void SetData(Random rnd) {
height = (byte)rnd.Next(4, 8);
public override int DefaultValue(Random rnd) { return rnd.Next(4, 8); }
public override void SetData(Random rnd, int value) {
height = (byte)value;
size = 1;
this.rnd = rnd;
}
}
public override void Output(ushort x, ushort y, ushort z, TreeOutput output) {
public override void Generate(ushort x, ushort y, ushort z, TreeOutput output) {
for (int dy = 0; dy <= height; dy++) {
ushort yy = (ushort)(y + dy);
if (dy < height) output(x, yy, z, Block.trunk);
@ -47,13 +49,15 @@ namespace MCGalaxy.Generator.Foilage {
public sealed class PalmTree : Tree {
public override void SetData(Random rnd) {
height = (byte)rnd.Next(4, 8);
public override int DefaultValue(Random rnd) { return rnd.Next(4, 8); }
public override void SetData(Random rnd, int value) {
height = (byte)value;
size = 2;
this.rnd = rnd;
}
}
public override void Output(ushort x, ushort y, ushort z, TreeOutput output) {
public override void Generate(ushort x, ushort y, ushort z, TreeOutput output) {
for (int dy = 0; dy <= height; dy++)
if (dy < height) output(x, (ushort)(y + dy), z, Block.trunk);

View File

@ -29,13 +29,15 @@ using System;
namespace MCGalaxy.Generator.Foilage {
public sealed class CactusTree : Tree {
public override void SetData(Random rnd) {
height = (byte)rnd.Next(3, 6);
public override int DefaultValue(Random rnd) { return rnd.Next(3, 6); }
public override void SetData(Random rnd, int value) {
height = (byte)value;
size = 1;
this.rnd = rnd;
}
public override void Output(ushort x, ushort y, ushort z, TreeOutput output) {
public override void Generate(ushort x, ushort y, ushort z, TreeOutput output) {
for (ushort dy = 0; dy <= height; dy++) {
output(x, (ushort)(y + dy), z, Block.green);
}
@ -54,15 +56,17 @@ namespace MCGalaxy.Generator.Foilage {
}
public sealed class NormalTree : Tree {
public override int DefaultValue(Random rnd) { return rnd.Next(5, 8); }
public override void SetData(Random rnd) {
height = (byte)rnd.Next(5, 8);
public override void SetData(Random rnd, int value) {
height = (byte)value;
top = (byte)(height - rnd.Next(2, 4));
size = top;
this.rnd = rnd;
}
public override void Output(ushort x, ushort y, ushort z, TreeOutput output) {
public override void Generate(ushort x, ushort y, ushort z, TreeOutput output) {
for (ushort dy = 0; dy < top + height - 1; dy++)
output(x, (ushort)(y + dy), z, Block.trunk);
@ -83,14 +87,16 @@ namespace MCGalaxy.Generator.Foilage {
public sealed class ClassicTree : Tree {
public override void SetData(Random rnd) {
height = (byte)rnd.Next(3, 7);
public override int DefaultValue(Random rnd) { return rnd.Next(3, 7); }
public override void SetData(Random rnd, int value) {
height = (byte)value;
top = (byte)(height - 2);
size = 2;
this.rnd = rnd;
}
public override void Output(ushort x, ushort y, ushort z, TreeOutput output) {
public override void Generate(ushort x, ushort y, ushort z, TreeOutput output) {
for (int dy = 0; dy <= height; dy++)
output(x, (ushort)(y + dy), z, Block.trunk);
@ -115,14 +121,16 @@ namespace MCGalaxy.Generator.Foilage {
public sealed class SwampTree : Tree {
public override void SetData(Random rnd) {
height = (byte)rnd.Next(4, 8);
public override int DefaultValue(Random rnd) { return rnd.Next(4, 8); }
public override void SetData(Random rnd, int value) {
height = (byte)value;
top = (byte)(height - 2);
size = 3;
this.rnd = rnd;
}
public override void Output(ushort x, ushort y, ushort z, TreeOutput output) {
public override void Generate(ushort x, ushort y, ushort z, TreeOutput output) {
for (int dy = 0; dy <= height; dy++)
output(x, (ushort)(y + dy), z, Block.trunk);

View File

@ -27,9 +27,21 @@ namespace MCGalaxy.Generator.Foilage {
protected internal byte height, top, size;
protected Random rnd;
public abstract void SetData(Random rnd);
/// <summary> Calculates a random default value (usually used for height) for this tree. </summary>
public abstract int DefaultValue(Random rnd);
/// <summary> Minimum allowed value (usually used for height) for this tree. </summary>
public virtual int MinValue { get { return 3; } }
/// <summary> Maximum allowed value (usually used for height) for this tree. </summary>
public virtual int MaxValue { get { return 100; } }
/// <summary> Initalises data (e.g. height and size) for this tree using the input value. </summary>
public abstract void SetData(Random rnd, int value);
/// <summary> Outputs the blocks generated by this tree at the given coordinates. </summary>
public abstract void Generate(ushort x, ushort y, ushort z, TreeOutput output);
public abstract void Output(ushort x, ushort y, ushort z, TreeOutput output);
/// <summary> Returns true if any green or trunk blocks are in the cube centred at (x, y, z) of extent 'size'. </summary>
public static bool TreeCheck(Level lvl, ushort x, ushort y, ushort z, short size) { //return true if tree is near

View File

@ -140,8 +140,8 @@ namespace MCGalaxy.Generator {
if (genParams.UseCactus) tree = new CactusTree();
else tree = new NormalTree();
tree.SetData(rand);
tree.Output(x, (ushort)(y + 1), z, (xT, yT, zT, bT) =>
tree.SetData(rand, tree.DefaultValue(rand));
tree.Generate(x, (ushort)(y + 1), z, (xT, yT, zT, bT) =>
{
if (Lvl.GetTile(xT, yT, zT) == Block.air)
Lvl.SetTile(xT, yT, zT, bT);