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); }