Make trees a drawop.

This commit is contained in:
UnknownShadow200 2016-03-28 20:10:22 +11:00
parent 90e67323ec
commit a45b761358
8 changed files with 367 additions and 234 deletions

View File

@ -1,87 +1,108 @@
/* /*
Copyright 2011 MCForge Copyright 2011 MCForge
Dual-licensed under the Educational Community License, Version 2.0 and Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing, Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS" software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses. permissions and limitations under the Licenses.
*/ */
namespace MCGalaxy.Commands using MCGalaxy.Drawing;
{ using MCGalaxy.Drawing.Brushes;
public sealed class CmdTree : Command using MCGalaxy.Drawing.Ops;
{
namespace MCGalaxy.Commands {
public sealed class CmdTree : Command {
public override string name { get { return "tree"; } } public override string name { get { return "tree"; } }
public override string shortcut { get { return ""; } } public override string shortcut { get { return ""; } }
public override string type { get { return CommandTypes.Building; } } public override string type { get { return CommandTypes.Building; } }
public override bool museumUsable { get { return false; } } public override bool museumUsable { get { return false; } }
public override LevelPermission defaultRank { get { return LevelPermission.Builder; } } public override LevelPermission defaultRank { get { return LevelPermission.Builder; } }
public CmdTree() { } static char[] trimChars = {' '};
public override void Use(Player p, string message) public override void Use(Player p, string message) {
{ if (p == null) { MessageInGameOnly(p); return; }
p.ClearBlockchange(); int mode = TreeDrawOp.T_Tree;
switch (message.ToLower()) string[] parts = message.Split(trimChars, 2);
{ string brushMsg = parts.Length >= 2 ? parts[1] : "";
switch (parts[0].ToLower()) {
case "1":
case "fern": mode = TreeDrawOp.T_Tree; break;
case "2": case "2":
case "cactus": p.Blockchange += new Player.BlockchangeEventHandler(AddCactus); break; case "cactus": mode = TreeDrawOp.T_Cactus; break;
case "3": case "3":
case "notch": p.Blockchange += new Player.BlockchangeEventHandler(AddNotchTree); break; case "notch": mode = TreeDrawOp.T_NotchTree; break;
case "4": case "4":
case "swamp": p.Blockchange += new Player.BlockchangeEventHandler(AddNotchSwampTree); break; case "swamp": mode = TreeDrawOp.T_NotchSwamp; break;
/*case "5": default: brushMsg = message; break;
case "big": p.Blockchange += new Player.BlockchangeEventHandler(AddNotchBigTree); break;
case "6":
case "pine": p.Blockchange += new Player.BlockchangeEventHandler(AddNotchPineTree); break;*/
default: p.Blockchange += new Player.BlockchangeEventHandler(AddTree); break;
} }
CatchPos cpos = default(CatchPos);
cpos.mode = mode;
cpos.brushMsg = brushMsg;
p.ClearBlockchange();
p.blockchangeObject = cpos;
p.Blockchange += new Player.BlockchangeEventHandler(PlaceBlock1);
Player.SendMessage(p, "Select where you wish your tree to grow"); Player.SendMessage(p, "Select where you wish your tree to grow");
p.painting = false;
} }
void AddTree(Player p, ushort x, ushort y, ushort z, byte type, byte extType) void PlaceBlock1(Player p, ushort x, ushort y, ushort z, byte type, byte extType) {
{ RevertAndClearState(p, x, y, z);
TreeGen.AddTree(p.level, x, y, z, p.random, true, true, p); CatchPos cpos = (CatchPos)p.blockchangeObject;
if (!p.staticCommands) p.ClearBlockchange(); type = type < 128 ? p.bindings[type] : type;
}
void AddNotchTree(Player p, ushort x, ushort y, ushort z, byte type, byte extType) TreeDrawOp op = new TreeDrawOp();
{ op.Type = cpos.mode;
TreeGen.AddNotchTree(p.level, x, y, z, p.random, true, true, p); op.random = p.random;
if (!p.staticCommands) p.ClearBlockchange(); op.overwrite = true;
} Brush brush = null;
void AddNotchBigTree(Player p, ushort x, ushort y, ushort z, byte type, byte extType)
{ if (cpos.brushMsg != "") {
TreeGen.AddNotchBigTree(p.level, x, y, z, p.random, true, true, p); if (!p.group.CanExecute("brush")) {
if (!p.staticCommands) p.ClearBlockchange(); Player.SendMessage(p, "You cannot use /brush, so therefore cannot use /tree with a brush."); return;
} }
void AddNotchPineTree(Player p, ushort x, ushort y, ushort z, byte type, byte extType) brush = ParseBrush(cpos.brushMsg, p, type, extType);
{ if (brush == null) return;
TreeGen.AddNotchPineTree(p.level, x, y, z, p.random, true, true, p); }
if (!p.staticCommands) p.ClearBlockchange();
} Vec3U16[] marks = { new Vec3U16(x, y, z) };
void AddNotchSwampTree(Player p, ushort x, ushort y, ushort z, byte type, byte extType) if (!DrawOp.DoDrawOp(op, brush, p, marks))
{ return;
TreeGen.AddNotchSwampTree(p.level, x, y, z, p.random, true, true, p); if (!p.staticCommands)
if (!p.staticCommands) p.ClearBlockchange(); p.Blockchange += new Player.BlockchangeEventHandler(PlaceBlock1);
}
void AddCactus(Player p, ushort x, ushort y, ushort z, byte type, byte extType)
{
TreeGen.AddCactus(p.level, x, y, z, p.random, true, true, p);
if (!p.staticCommands) p.ClearBlockchange();
} }
static Brush ParseBrush(string brushMsg, Player p, byte type, byte extType) {
string[] parts = brushMsg.Split(trimChars, 2);
string brushName = CmdBrush.FindBrush(parts[0]);
if (brushName == null) {
Player.SendMessage(p, "No brush found with name \"" + parts[0] + "\".");
Player.SendMessage(p, "Available brushes: " + CmdBrush.AvailableBrushes);
return null;
}
public override void Help(Player p) string brushMessage = parts.Length >= 2 ? parts[1].ToLower() : "";
{ BrushArgs args = new BrushArgs(p, brushMessage, type, extType);
Player.SendMessage(p, "/tree [type] - Turns tree mode on or off."); return Brush.Brushes[brushName](args);
Player.SendMessage(p, "Types - (Fern | 1), (Cactus | 2), (Notch | 3), (Swamp | 4)"); }
struct CatchPos { public int mode; public string brushMsg; }
public override void Help(Player p) {
Player.SendMessage(p, "%T/tree [type] %H- Draws a tree.");
Player.SendMessage(p, "%HTypes - &fFern/1, Cactus/2, Notch/3, Swamp/4");
Player.SendMessage(p, "%T/tree [type] [brush name] <brush args>");
Player.SendMessage(p, " %HFor help about brushes, type %T/help brush%H.");
} }
} }
} }

View File

@ -82,10 +82,10 @@ namespace MCGalaxy.Drawing.Ops {
public virtual bool DetermineDrawOpMethod(Level lvl, int affected) { public virtual bool DetermineDrawOpMethod(Level lvl, int affected) {
if (affected > Server.DrawReloadLimit) { if (affected > Server.DrawReloadLimit) {
method = MethodSetTile; method = M_PSetTile;
return true; return true;
} else { } else {
method = lvl.bufferblocks ? MethodBlockQueue : MethodBlockChange; method = lvl.bufferblocks ? M_PBlockQueue : M_PBlockChange;
return false; return false;
} }
} }
@ -104,27 +104,38 @@ namespace MCGalaxy.Drawing.Ops {
protected void PlaceBlock(Player p, Level lvl, ushort x, ushort y, ushort z, byte type, byte extType) { protected void PlaceBlock(Player p, Level lvl, ushort x, ushort y, ushort z, byte type, byte extType) {
switch (method) { switch (method) {
case MethodBlockQueue: case M_PBlockQueue:
BlockQueue.Addblock(p, x, y, z, type, extType); BlockQueue.Addblock(p, x, y, z, type, extType);
TotalModified++; TotalModified++;
break; break;
case MethodBlockChange: case M_PBlockChange:
p.level.Blockchange(p, x, y, z, type, extType); lvl.Blockchange(p, x, y, z, type, extType);
TotalModified++; TotalModified++;
break; break;
case MethodSetTile: case M_PSetTile:
byte old = lvl.GetTile(x, y, z); byte old = lvl.GetTile(x, y, z);
if (old == Block.Zero || !lvl.CheckAffectPermissions(p, x, y, z, old, type)) if (old == Block.Zero || !lvl.CheckAffectPermissions(p, x, y, z, old, type))
return; return;
p.level.SetTile(x, y, z, type, p, extType); lvl.SetTile(x, y, z, type, p, extType);
p.loginBlocks++; p.loginBlocks++;
p.overallBlocks++; p.overallBlocks++;
TotalModified++; TotalModified++;
break; break;
case M_BlockChange:
lvl.Blockchange(x, y, z, type, extType);
TotalModified++;
break;
case M_SetTile:
lvl.SetTile(x, y, z, type);
if (type == Block.custom_block)
lvl.SetExtTile(x, y, z, extType);
TotalModified++;
break;
} }
} }
internal const int MethodBlockQueue = 0, MethodBlockChange = 1, MethodSetTile = 2; internal const int M_PBlockQueue = 0, M_PBlockChange = 1, M_PSetTile = 2;
internal const int M_BlockChange = 3, M_SetTile = 4;
public static bool DoDrawOp(DrawOp op, Brush brush, Player p, public static bool DoDrawOp(DrawOp op, Brush brush, Player p,
ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) { ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2) {

View File

@ -0,0 +1,175 @@
/*
Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/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.
*/
// Copyright 2009, 2010 Matvei Stefarov <me@matvei.org>
/*
This generator was developed by Neko_baron.
Ideas, concepts, and code were used from the following two sources:
1) Isaac McGarvey's 'perlin noise generator' code
2) http://www.lighthouse3d.com/opengl/terrain/index.php3?introduction
*/
using System;
using MCGalaxy.Drawing.Brushes;
namespace MCGalaxy.Drawing.Ops {
public class TreeDrawOp : DrawOp {
public override string Name { get { return "Tree"; } }
public Random random;
public bool overwrite = false;
public int Type;
public const int T_Tree = 0, T_NotchTree = 1, T_NotchSwamp = 2, T_Cactus = 3;
static Brush defBrush = new SolidBrush(Block.leaf, 0);
public override int GetBlocksAffected(Level lvl, Vec3U16[] marks) { return -1; }
public override void Perform(Vec3U16[] marks, Player p, Level lvl, Brush brush) {
if (brush == null) brush = defBrush;
Vec3U16 P = marks[0];
if (Type == T_Tree) AddTree(p, lvl, P.X, P.Y, P.Z, brush);
if (Type == T_NotchTree) AddNotchTree(p, lvl, P.X, P.Y, P.Z, brush);
if (Type == T_NotchSwamp) AddNotchSwampTree(p, lvl, P.X, P.Y, P.Z, brush);
if (Type == T_Cactus) AddCactus(p, lvl, P.X, P.Y, P.Z);
}
void AddTree(Player p, Level lvl, ushort x, ushort y, ushort z, Brush brush) {
byte height = (byte)random.Next(5, 8);
short top = (short)(height - random.Next(2, 4));
for (ushort dy = 0; dy < top + height - 1; dy++) {
ushort yy = (ushort)(y + dy);
if (overwrite || lvl.GetTile(x, yy, z) == Block.air || (yy == y && lvl.GetTile(x, yy, z) == Block.shrub))
PlaceBlock(p, lvl, x, yy, z, Block.trunk, 0);
}
for (short dy = (short)-top; dy <= top; ++dy)
for (short dz = (short)-top; dz <= top; ++dz)
for (short dx = (short)-top; dx <= top; ++dx)
{
short dist = (short)(Math.Sqrt(dx * dx + dy * dy + dz * dz));
if ((dist < top + 1) && random.Next(dist) < 2) {
ushort xx = (ushort)(x + dx), yy = (ushort)(y + dy + height), zz = (ushort)(z + dz);
if ((xx != x || zz != z || dy >= top - 1) && (overwrite || lvl.GetTile(xx, yy, zz) == Block.air))
PlaceBlock(p, lvl, xx, yy, zz, brush);
}
}
}
void AddNotchTree(Player p, Level lvl, ushort x, ushort y, ushort z, Brush brush) {
byte height = (byte)random.Next(3, 7);
byte top = (byte)(height - 2);
for (int dy = 0; dy <= height; dy++) {
ushort yy = (ushort)(y + dy);
byte tile = lvl.GetTile(x, yy, z);
if (overwrite || tile == Block.air || (yy == y && tile == Block.shrub))
PlaceBlock(p, lvl, x, yy, z, Block.trunk, 0);
}
for (int dy = top; dy <= height + 1; dy++) {
int dist = dy > height - 1 ? 1 : 2;
for (int dz = -dist; dz <= dist; dz++)
for (int dx = -dist; dx <= dist; dx++)
{
ushort xx = (ushort)(x + dx), yy = (ushort)(y + dy), zz = (ushort)(z + dz);
byte tile = lvl.GetTile(xx, yy, zz);
if ((xx == x && zz == z && dy <= height) || (!overwrite && tile != Block.air))
continue;
if (Math.Abs(dx) == dist && Math.Abs(dz) == dist) {
if (dy > height) continue;
if (random.Next(2) == 0)
PlaceBlock(p, lvl, xx, yy, zz, brush);
} else {
PlaceBlock(p, lvl, xx, yy, zz, brush);
}
}
}
}
void AddNotchSwampTree(Player p, Level lvl, ushort x, ushort y, ushort z, Brush brush) {
byte height = (byte)random.Next(4, 8);
byte top = (byte)(height - 2);
for (int dy = 0; dy <= height; dy++) {
ushort yy = (ushort)(y + dy);
byte tile = lvl.GetTile(x, yy, z);
if (overwrite || tile == Block.air || (yy == y && tile == Block.shrub))
PlaceBlock(p, lvl, x, yy, z, Block.trunk, 0);
}
for (int dy = top; dy <= height + 1; dy++) {
int dist = dy > height - 1 ? 2 : 3;
for (int dz = (short)-dist; dz <= dist; dz++)
for (int dx = (short)-dist; dx <= dist; dx++)
{
ushort xx = (ushort)(x + dx), yy = (ushort)(y + dy), zz = (ushort)(z + dz);
byte tile = lvl.GetTile(xx, yy, zz);
if ((xx == x && zz == z && dy <= height) || (!overwrite && tile != Block.air))
continue;
if (Math.Abs(dz) == dist && Math.Abs(dx) == dist) {
if (dy > height) continue;
if (random.Next(2) == 0)
PlaceBlock(p, lvl, xx, yy, zz, brush);
} else {
PlaceBlock(p, lvl, xx, yy, zz, brush);
}
}
}
}
void AddCactus(Player p, Level lvl, ushort x, ushort y, ushort z) {
byte height = (byte)random.Next(3, 6);
for (ushort dy = 0; dy <= height; dy++) {
if (overwrite || lvl.GetTile(z, (ushort)(y + dy), z) == Block.air)
PlaceBlock(p, lvl, x, (ushort)(y + dy), z, Block.green, 0);
}
int inX = 0, inZ = 0;
switch (random.Next(1, 3)) {
case 1: inX = -1; break;
case 2:
default: inZ = -1; break;
}
for (ushort dy = height; dy <= random.Next(height + 2, height + 5); dy++) {
if (overwrite || lvl.GetTile((ushort)(x + inX), (ushort)(y + dy), (ushort)(z + inZ)) == Block.air)
PlaceBlock(p, lvl, (ushort)(x + inX), (ushort)(y + dy), (ushort)(z + inZ), Block.green, 0);
}
for (ushort dy = height; dy <= random.Next(height + 2, height + 5); dy++) {
if (overwrite || lvl.GetTile((ushort)(x - inX), (ushort)(y + dy), (ushort)(z - inZ)) == Block.air)
PlaceBlock(p, lvl, (ushort)(x - inX), (ushort)(y + dy), (ushort)(z - inZ), Block.green, 0);
}
}
public static bool TreeCheck(Level lvl, ushort x, ushort z, ushort y, short dist) { //return true if tree is near
for (short dy = (short)-dist; dy <= +dist; ++dy)
for (short dz = (short)-dist; dz <= +dist; ++dz)
for (short dx = (short)-dist; dx <= +dist; ++dx)
{
byte tile = lvl.GetTile((ushort)(x + dx), (ushort)(z + dz), (ushort)(y + dy));
if (tile == Block.trunk || tile == Block.green) return true;
}
return false;
}
}
}

View File

@ -0,0 +1,57 @@
/*
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;
namespace MCGalaxy.Games {
/// <summary> Properties of players that are relevant to zombie survival. </summary>
public class ZombieGameProps {
/// <summary> Whether this player is currently in referee mode. </summary>
public bool Referee = false;
/// <summary> Remaining number of blocks that can be manually placed this round. </summary>
internal int BlockCount = 50;
/// <summary> Number of blocks that have been sequentially vertically pillared. </summary>
public int BlocksStacked = 0;
internal int lastYblock = 0, lastXblock = 0, lastZblock = 0;
/// <summary> Whether this player is currently infected. </summary>
public bool Infected = false;
/// <summary> Whether the real name of players are always shown over zombie models. </summary>
public bool AkaMode = false;
public bool flipHead = false;
/// <summary> Total number of other players infected this round. </summary>
public int NumberInfected = 0;
internal string lastSpawnColor = "";
/// <summary> Whether either /like or /dislike has been in this round. </summary>
public bool RatedMap = false;
/// <summary> Whether used /pledge has been used in this round. </summary>
public bool PledgeSurvive = false;
/// <summary> List of custom infect messages. </summary>
public List<string> InfectMessages = null;
}
}

View File

@ -25,6 +25,9 @@ Ideas, concepts, and code were used from the following two sources:
*/ */
using System; using System;
using MCGalaxy.Drawing;
using MCGalaxy.Drawing.Ops;
namespace MCGalaxy { namespace MCGalaxy {
public sealed class RealisticMapGen { public sealed class RealisticMapGen {
@ -36,6 +39,8 @@ namespace MCGalaxy {
Random rand; Random rand;
ushort LiquidLevel; ushort LiquidLevel;
MapGenParams genParams; MapGenParams genParams;
TreeDrawOp treeDrawer;
Vec3U16[] treeCoords;
public bool GenerateMap(Level Lvl, string type, int seed = 0, bool useSeed = false) { public bool GenerateMap(Level Lvl, string type, int seed = 0, bool useSeed = false) {
DateTime startTime = DateTime.UtcNow; DateTime startTime = DateTime.UtcNow;
@ -43,6 +48,12 @@ namespace MCGalaxy {
rand = useSeed ? new System.Random(seed) : new System.Random(); rand = useSeed ? new System.Random(seed) : new System.Random();
if (!MapGenParams.Themes.TryGetValue(type, out genParams)) if (!MapGenParams.Themes.TryGetValue(type, out genParams))
genParams = new MapGenParams(); genParams = new MapGenParams();
if (genParams.GenTrees) {
treeDrawer = new TreeDrawOp();
treeDrawer.random = rand;
treeDrawer.method = DrawOp.M_SetTile;
treeCoords = new Vec3U16[1];
}
try try
{ {
@ -131,11 +142,11 @@ namespace MCGalaxy {
if (genParams.GenTrees && overlay[index] < 0.65f && overlay2[index] < treeDens) { if (genParams.GenTrees && overlay[index] < 0.65f && overlay2[index] < treeDens) {
if (Lvl.GetTile(x, (ushort)(y + 1), z) == Block.air) { if (Lvl.GetTile(x, (ushort)(y + 1), z) == Block.air) {
if (Lvl.GetTile(x, y, z) == Block.grass || genParams.UseCactus) { if (Lvl.GetTile(x, y, z) == Block.grass || genParams.UseCactus) {
if (rand.Next(13) == 0 && !TreeGen.TreeCheck(Lvl, x, y, z, treeDist)) if (rand.Next(13) == 0 && !TreeDrawOp.TreeCheck(Lvl, x, y, z, treeDist)) {
if (genParams.UseCactus) treeDrawer.Type = genParams.UseCactus ? TreeDrawOp.T_Cactus : TreeDrawOp.T_Tree;
TreeGen.AddCactus(Lvl, x, (ushort)(y + 1), z, rand); treeCoords[0].X = x; treeCoords[0].Y = (ushort)(y + 1); treeCoords[0].Z = z;
else treeDrawer.Perform(treeCoords, null, Lvl, null);
TreeGen.AddTree(Lvl, x, (ushort)(y + 1), z, rand); }
} }
} }
} }

View File

@ -1,7 +1,7 @@
/* /*
Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy) Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCGalaxy)
Dual-licensed under the Educational Community License, Version 2.0 and Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at obtain a copy of the Licenses at
@ -29,153 +29,6 @@ namespace MCGalaxy {
public static class TreeGen { public static class TreeGen {
public static void AddTree(Level Lvl, ushort x, ushort y, ushort z, Random Rand, bool blockChange = false, bool overwrite = true, Player p = null)
{
byte height = (byte)Rand.Next(5, 8);
short top = (short)(height - Rand.Next(2, 4));
for (ushort yy = 0; yy < top + height - 1; yy++) {
if (overwrite || Lvl.GetTile(x, (ushort)(y + yy), z) == Block.air || (y + yy == y && Lvl.GetTile(x, (ushort)(y + yy), z) == Block.shrub))
PlaceBlock(Lvl, blockChange, p, x, (ushort)(y + yy), z, Block.trunk);
}
for (short xx = (short)-top; xx <= top; ++xx)
for (short yy = (short)-top; yy <= top; ++yy)
for (short zz = (short)-top; zz <= top; ++zz)
{
short Dist = (short)(Math.Sqrt(xx * xx + yy * yy + zz * zz));
if ((Dist < top + 1) && Rand.Next(Dist) < 2) {
ushort xxx = (ushort)(x + xx), yyy = (ushort)(y + yy + height), zzz = (ushort)(z + zz);
if ((xxx != x || zzz != z || yy >= top - 1) && (overwrite || Lvl.GetTile(xxx, yyy, zzz) == Block.air))
PlaceBlock(Lvl, blockChange, p, xxx, yyy, zzz, Block.leaf);
}
}
}
public static void AddNotchTree(Level Lvl, ushort x, ushort y, ushort z, Random Rand, bool blockChange = false, bool overwrite = true, Player p = null)
{
byte height = (byte)Rand.Next(3, 7);
byte top = (byte)(height - 2);
for (int yy = 0; yy <= height; yy++) {
ushort yyy = (ushort)(y + yy);
byte tile = Lvl.GetTile(x, yyy, z);
if (overwrite || tile == Block.air || (yyy == y && tile == Block.shrub))
PlaceBlock(Lvl, blockChange, p, x, yyy, z, Block.trunk);
}
for (int yy = top; yy <= height + 1; yy++) {
int dist = yy > height - 1 ? 1 : 2;
for (int xx = -dist; xx <= dist; xx++)
for (int zz = -dist; zz <= dist; zz++)
{
ushort xxx = (ushort)(x + xx), yyy = (ushort)(y + yy), zzz = (ushort)(z + zz);
byte tile = Lvl.GetTile(xxx, yyy, zzz);
if ((xxx == x && zzz == z && yy <= height) || (!overwrite && tile != Block.air))
continue;
if (Math.Abs(xx) == dist && Math.Abs(zz) == dist) {
if (yy > height) continue;
if (Rand.Next(2) == 0)
PlaceBlock(Lvl, blockChange, p, xxx, yyy, zzz, Block.leaf);
} else {
PlaceBlock(Lvl, blockChange, p, xxx, yyy, zzz, Block.leaf);
}
}
}
}
public static void AddNotchBigTree(Level Lvl, ushort x, ushort y, ushort z, Random Rand, bool blockChange = false, bool overwrite = true, Player p = null)
{
throw new NotImplementedException();
}
public static void AddNotchPineTree(Level Lvl, ushort x, ushort y, ushort z, Random Rand, bool blockChange = false, bool overwrite = true, Player p = null)
{
throw new NotImplementedException();
//byte height = (byte)Rand.Next(7, 12);
}
public static void AddNotchSwampTree(Level Lvl, ushort x, ushort y, ushort z, Random Rand, bool blockChange = false, bool overwrite = true, Player p = null)
{
byte height = (byte)Rand.Next(4, 8);
byte top = (byte)(height - 2);
for (int yy = 0; yy <= height; yy++) {
ushort yyy = (ushort)(y + yy);
byte tile = Lvl.GetTile(x, yyy, z);
if (overwrite || tile == Block.air || (yyy == y && tile == Block.shrub))
PlaceBlock(Lvl, blockChange, p, x, yyy, z, Block.trunk);
}
for (int yy = top; yy <= height + 1; yy++) {
int dist = yy > height - 1 ? 2 : 3;
for (int xx = (short)-dist; xx <= dist; xx++)
for (int zz = (short)-dist; zz <= dist; zz++)
{
ushort xxx = (ushort)(x + xx), yyy = (ushort)(y + yy), zzz = (ushort)(z + zz);
byte tile = Lvl.GetTile(xxx, yyy, zzz);
if ((xxx == x && zzz == z && yy <= height) || (!overwrite && tile != Block.air))
continue;
if (Math.Abs(xx) == dist && Math.Abs(zz) == dist) {
if (yy > height) continue;
if (Rand.Next(2) == 0)
PlaceBlock(Lvl, blockChange, p, xxx, yyy, zzz, Block.leaf);
} else {
PlaceBlock(Lvl, blockChange, p, xxx, yyy, zzz, Block.leaf);
}
}
}
}
public static void AddCactus(Level Lvl, ushort x, ushort y, ushort z, Random Rand, bool blockChange = false, bool overwrite = true, Player p = null)
{
byte height = (byte)Rand.Next(3, 6);
for (ushort yy = 0; yy <= height; yy++) {
if (overwrite || Lvl.GetTile(z, (ushort)(y + yy), z) == Block.air)
PlaceBlock(Lvl, blockChange, p, x, (ushort)(y + yy), z, Block.green);
}
int inX = 0, inZ = 0;
switch (Rand.Next(1, 3)) {
case 1: inX = -1; break;
case 2:
default: inZ = -1; break;
}
for (ushort yy = height; yy <= Rand.Next(height + 2, height + 5); yy++) {
if (overwrite || Lvl.GetTile((ushort)(x + inX), (ushort)(y + yy), (ushort)(z + inZ)) == Block.air)
PlaceBlock(Lvl, blockChange, p, (ushort)(x + inX), (ushort)(y + yy), (ushort)(z + inZ), Block.green);
}
for (ushort yy = height; yy <= Rand.Next(height + 2, height + 5); yy++) {
if (overwrite || Lvl.GetTile((ushort)(x - inX), (ushort)(y + yy), (ushort)(z - inZ)) == Block.air)
PlaceBlock(Lvl, blockChange, p, (ushort)(x - inX), (ushort)(y + yy), (ushort)(z - inZ), Block.green);
}
}
public static bool TreeCheck(Level Lvl, ushort x, ushort z, ushort y, short dist) { //return true if tree is near
for (short yy = (short)-dist; yy <= +dist; ++yy)
for (short zz = (short)-dist; zz <= +dist; ++zz)
for (short xx = (short)-dist; xx <= +dist; ++xx)
{
byte foundTile = Lvl.GetTile((ushort)(x + xx), (ushort)(z + zz), (ushort)(y + yy));
if (foundTile == Block.trunk || foundTile == Block.green) return true;
}
return false;
}
static void PlaceBlock(Level lvl, bool blockChange, Player p, ushort x, ushort y, ushort z, byte type) {
if (blockChange) {
if (p == null) lvl.Blockchange(x, y, z, type);
else lvl.UpdateBlock(p, x, y, z, type, 0);
} else {
lvl.SetTile(x, y, z, type);
}
}
} }
} }

View File

@ -20,6 +20,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using MCGalaxy.BlockPhysics; using MCGalaxy.BlockPhysics;
using MCGalaxy.Drawing;
using MCGalaxy.Drawing.Ops;
using MCGalaxy.Games; using MCGalaxy.Games;
namespace MCGalaxy { namespace MCGalaxy {
@ -254,17 +256,19 @@ namespace MCGalaxy {
//Check block above //Check block above
} }
if (!growTrees) if (!growTrees) {
{
C.time = 255; C.time = 255;
break; break;
} }
if (C.time < 20) if (C.time < 20) {
{
if (rand.Next(20) == 0) C.time++; if (rand.Next(20) == 0) C.time++;
break; break;
} }
TreeGen.AddTree(this, x, y, z, rand, true, false);
TreeDrawOp op = new TreeDrawOp();
op.random = rand;
op.method = DrawOp.M_BlockChange;
op.Perform(new [] { new Vec3U16(x, y, z) }, null, this, null);
C.time = 255; C.time = 255;
break; break;

View File

@ -419,6 +419,7 @@
<Compile Include="Drawing\DrawOps\SpheroidDrawOp.cs" /> <Compile Include="Drawing\DrawOps\SpheroidDrawOp.cs" />
<Compile Include="Drawing\DrawOps\PyramidDrawOp.cs" /> <Compile Include="Drawing\DrawOps\PyramidDrawOp.cs" />
<Compile Include="Drawing\DrawOps\TorusDrawOp.cs" /> <Compile Include="Drawing\DrawOps\TorusDrawOp.cs" />
<Compile Include="Drawing\DrawOps\TreeDrawOp.cs" />
<Compile Include="Drawing\DrawOps\TriangleDrawOp.cs" /> <Compile Include="Drawing\DrawOps\TriangleDrawOp.cs" />
<Compile Include="Drawing\DrawOps\UndoDrawOp.cs" /> <Compile Include="Drawing\DrawOps\UndoDrawOp.cs" />
<Compile Include="Drawing\DrawOps\WriteDrawOp.cs" /> <Compile Include="Drawing\DrawOps\WriteDrawOp.cs" />