diff --git a/MCGalaxy/Commands/building/CmdImageprint.cs b/MCGalaxy/Commands/building/CmdImageprint.cs
index 983340972..896bd6c10 100644
--- a/MCGalaxy/Commands/building/CmdImageprint.cs
+++ b/MCGalaxy/Commands/building/CmdImageprint.cs
@@ -122,7 +122,7 @@ namespace MCGalaxy.Commands.Building {
op.Direction = m[1].Z <= m[0].Z ? 3 : 2;
}
- op.Level = p.level;
+ op.SetLevel(p.level);
op.Player = p;
op.Source = bmp;
op.Layer = dArgs.layer;
diff --git a/MCGalaxy/Drawing/DrawOps/DrawOp.cs b/MCGalaxy/Drawing/DrawOps/DrawOp.cs
index 1386602dd..81e44e9d3 100644
--- a/MCGalaxy/Drawing/DrawOps/DrawOp.cs
+++ b/MCGalaxy/Drawing/DrawOps/DrawOp.cs
@@ -58,11 +58,11 @@ namespace MCGalaxy.Drawing.Ops {
/// Note: You should treat this as coordinates, it is a DrawOpBlock struct for performance reasons.
public DrawOpBlock Coords;
- /// Level the draw operation is being performed upon.
- public Level Level;
-
/// Player that is executing the draw operation.
public Player Player;
+
+ /// Level the draw operation is being performed upon.
+ public Level Level;
/// BlockDB change flags for blocks affected by this draw operation.
public ushort Flags = BlockDBFlags.Drawn;
@@ -100,6 +100,12 @@ namespace MCGalaxy.Drawing.Ops {
}
}
+ /// Sets the level associated with this draw operation.
+ public void SetLevel(Level lvl) {
+ Level = lvl;
+ clip = new Vec3S32(lvl.Width - 1, lvl.Height - 1, lvl.Length - 1);
+ }
+
protected DrawOpBlock Place(ushort x, ushort y, ushort z, Brush brush) {
Coords.X = x; Coords.Y = y; Coords.Z = z;
Coords.Block = brush.NextBlock(this);
@@ -115,10 +121,11 @@ namespace MCGalaxy.Drawing.Ops {
return Coords;
}
+ Vec3S32 clip = new Vec3S32(ushort.MaxValue);
protected Vec3U16 Clamp(Vec3S32 pos) {
- pos.X = Math.Max(0, Math.Min(pos.X, Level.Width - 1));
- pos.Y = Math.Max(0, Math.Min(pos.Y, Level.Height - 1));
- pos.Z = Math.Max(0, Math.Min(pos.Z, Level.Length - 1));
+ pos.X = Math.Max(0, Math.Min(pos.X, clip.X));
+ pos.Y = Math.Max(0, Math.Min(pos.Y, clip.Y));
+ pos.Z = Math.Max(0, Math.Min(pos.Z, clip.Z));
return new Vec3U16((ushort)pos.X, (ushort)pos.Y, (ushort)pos.Z);
}
}
diff --git a/MCGalaxy/Drawing/DrawOps/DrawOpPerformer.cs b/MCGalaxy/Drawing/DrawOps/DrawOpPerformer.cs
index a4ac2d7ea..4d12beb0e 100644
--- a/MCGalaxy/Drawing/DrawOps/DrawOpPerformer.cs
+++ b/MCGalaxy/Drawing/DrawOps/DrawOpPerformer.cs
@@ -44,20 +44,21 @@ namespace MCGalaxy.Drawing.Ops {
public static bool Do(DrawOp op, Brush brush, Player p,
Vec3S32[] marks, bool checkLimit = true) {
op.SetMarks(marks);
- op.Level = p == null ? null : p.level;
+ Level lvl = p == null ? null : p.level;
+ op.SetLevel(lvl);
op.Player = p;
- if (op.Level != null && !op.Level.DrawingAllowed) {
+ if (lvl != null && !lvl.DrawingAllowed) {
Player.Message(p, "Drawing commands are turned off on this map.");
return false;
}
- if (op.Level != null && op.Level.BuildAccess.Check(p) == AccessResult.Blacklisted) {
+ if (lvl != null && lvl.BuildAccess.Check(p) == AccessResult.Blacklisted) {
Player.Message(p, "You are blacklisted from building in this map, " +
"hence you cannot draw in this map");
return false;
}
- long affected = op.BlocksAffected(op.Level, marks);
+ long affected = op.BlocksAffected(lvl, marks);
if (p != null && op.AffectedByTransform)
p.Transform.GetBlocksAffected(ref affected);
diff --git a/MCGalaxy/Drawing/DrawOps/PyramidDrawOp.cs b/MCGalaxy/Drawing/DrawOps/PyramidDrawOp.cs
index 7b096b554..c9b139741 100644
--- a/MCGalaxy/Drawing/DrawOps/PyramidDrawOp.cs
+++ b/MCGalaxy/Drawing/DrawOps/PyramidDrawOp.cs
@@ -51,7 +51,7 @@ namespace MCGalaxy.Drawing.Ops {
public override void Perform(Vec3S32[] marks, Brush brush, Action output) {
Vec3S32 p1 = Min, p2 = Max;
- baseOp.Level = Level;
+ baseOp.SetLevel(Level);
baseOp.Player = Player;
while (true) {
@@ -96,7 +96,7 @@ namespace MCGalaxy.Drawing.Ops {
Vec3U16 p1 = Clamp(Min), p2 = Clamp(Max);
wallOp.Min = Min; wallOp.Max = Max;
baseOp.Min = Min; baseOp.Max = Max;
- wallOp.Level = Level; baseOp.Level = Level;
+ wallOp.SetLevel(Level); baseOp.SetLevel(Level);
wallOp.Player = Player; baseOp.Player = Player;
while (true) {
diff --git a/MCGalaxy/Generator/Foilage/AshTree.cs b/MCGalaxy/Generator/Foilage/AshTree.cs
new file mode 100644
index 000000000..dd3275c10
--- /dev/null
+++ b/MCGalaxy/Generator/Foilage/AshTree.cs
@@ -0,0 +1,82 @@
+/*
+ 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.Drawing.Brushes;
+using MCGalaxy.Drawing.Ops;
+
+namespace MCGalaxy.Generator.Foilage {
+ public sealed class AshTree : Tree {
+
+ int halfHeight, branchAmount;
+ const int widthMax = 5, branchHeightMax = 10, clusterSizeMax = 3;
+ List branch = new List();
+
+ public override int DefaultValue(Random rnd) { return rnd.Next(0, 11); }
+
+ public override void SetData(Random rnd, int value) {
+ this.rnd = rnd;
+ height = (byte)rnd.Next(5, 10);
+ halfHeight = height/4;
+ branchAmount = rnd.Next(10, 25);
+ }
+
+ public override void Generate(ushort x, ushort y, ushort z, TreeOutput output) {
+ // Do base trunk
+ Vec3S32 p1 = new Vec3S32(x, y, z);
+ Vec3S32 p2 = new Vec3S32(x, y + height, z);
+ Line(p1, p2, output);
+
+ for (int i = 0; i < branchAmount; i++) {
+ DoBranch(x, y, z, output);
+ }
+ }
+
+
+ void DoBranch(int x, int y, int z, TreeOutput output) {
+ int dx = rnd.Next(-widthMax, widthMax);
+ int dz = rnd.Next(-widthMax, widthMax);
+ int clusterSize = rnd.Next(1, clusterSizeMax);
+ int branchStart = rnd.Next(halfHeight, height);
+ int branchMax = branchStart + rnd.Next(3, branchHeightMax);
+
+ int R = clusterSize;
+ Vec3S32[] marks = new [] {
+ new Vec3S32(x + dx - R, y + branchMax - R, z + dz - R),
+ new Vec3S32(x + dx + R, y + branchMax + R, z + dz + R) };
+
+ DrawOp op = new EllipsoidDrawOp();
+ Brush brush = new RandomBrush(new [] { new ExtBlock(Block.leaf, 0) });
+ op.SetMarks(marks);
+ op.Perform(marks, brush, b => output(b.X, b.Y, b.Z, b.Block));
+
+ Vec3S32 p1 = new Vec3S32(x, branchStart, z);
+ Vec3S32 p2 = new Vec3S32(x + dx, y + branchMax, z + dz);
+ Line(p1, p2, output);
+ }
+
+ void Line(Vec3S32 p1, Vec3S32 p2, TreeOutput output) {
+ LineDrawOp.DrawLine(p1.X, p1.Y, p1.Z, 100, p2.X, p2.Y, p2.Z, branch);
+
+ foreach (Vec3S32 P in branch) {
+ output((ushort)P.X, (ushort)P.Y, (ushort)P.Z, Block.trunk);
+ }
+ branch.Clear();
+ }
+ }
+}
\ No newline at end of file
diff --git a/MCGalaxy/Generator/Foilage/Tree.cs b/MCGalaxy/Generator/Foilage/Tree.cs
index be82adb89..998d9b6c8 100644
--- a/MCGalaxy/Generator/Foilage/Tree.cs
+++ b/MCGalaxy/Generator/Foilage/Tree.cs
@@ -61,7 +61,7 @@ namespace MCGalaxy.Generator.Foilage {
{ "Fern", () => new NormalTree() }, { "Cactus", () => new CactusTree() },
{ "Notch", () => new ClassicTree() }, { "Swamp", () => new SwampTree() },
{ "Bamboo", () => new BambooTree() }, { "Palm", () => new PalmTree() },
- { "Oak", () => new OakTree() },
+ { "Oak", () => new OakTree() }, { "Ash", () => new AshTree() },
};
public static Tree Find(string name) {
diff --git a/MCGalaxy/MCGalaxy_.csproj b/MCGalaxy/MCGalaxy_.csproj
index 5d3972f5d..36fd22a3d 100644
--- a/MCGalaxy/MCGalaxy_.csproj
+++ b/MCGalaxy/MCGalaxy_.csproj
@@ -496,6 +496,7 @@
+
diff --git a/MCGalaxy/util/Math/Vectors.cs b/MCGalaxy/util/Math/Vectors.cs
index b65278935..6e8307edc 100644
--- a/MCGalaxy/util/Math/Vectors.cs
+++ b/MCGalaxy/util/Math/Vectors.cs
@@ -106,6 +106,10 @@ namespace MCGalaxy {
X = x; Y = y; Z = z;
}
+ public Vec3S32(int value) {
+ X = value; Y = value; Z = value;
+ }
+
public override bool Equals(object obj) {
return (obj is Vec3S32) && Equals((Vec3S32)obj);
}