From ccfa9a28815a615cc970db4867f40faa05548c6a Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 28 Jan 2016 20:23:22 +1100 Subject: [PATCH] Fix grass growing to work with BlockDefinitions. (Thanks goodlyay) --- Commands/Information/CmdBlocks.cs | 3 +- Commands/World/CmdFixGrass.cs | 259 ++++++++++++++++-------------- Levels/Block.cs | 12 +- Levels/Level.Blocks.cs | 3 +- Levels/Level.cs | 14 +- Player/Player.cs | 10 +- 6 files changed, 162 insertions(+), 139 deletions(-) diff --git a/Commands/Information/CmdBlocks.cs b/Commands/Information/CmdBlocks.cs index e28befc78..17a09c314 100644 --- a/Commands/Information/CmdBlocks.cs +++ b/Commands/Information/CmdBlocks.cs @@ -94,7 +94,8 @@ namespace MCGalaxy.Commands Player.SendMessage(p, "&bComplex information for \"" + message + "\":"); Player.SendMessage(p, "&cBlock will appear as a \"" + Block.Name(Block.Convert(b)) + "\" block"); - if (Block.LightPass(b)) Player.SendMessage(p, "Block will allow light through"); + if (Block.LightPass(b, 0, BlockDefinition.GlobalDefs)) + Player.SendMessage(p, "Block will allow light through"); if (Block.Physics(b)) Player.SendMessage(p, "Block affects physics in some way"); //AFFECT! else Player.SendMessage(p, "Block will not affect physics in any way"); //It's AFFECT! if (Block.NeedRestart(b)) Player.SendMessage(p, "The block's physics will auto-start"); diff --git a/Commands/World/CmdFixGrass.cs b/Commands/World/CmdFixGrass.cs index 495c8a965..e210ef9b1 100644 --- a/Commands/World/CmdFixGrass.cs +++ b/Commands/World/CmdFixGrass.cs @@ -1,21 +1,21 @@ /* - Copyright 2010 MCLawl Team - Written by Valek (Modified for use with MCGalaxy) + Copyright 2010 MCLawl Team - Written by Valek (Modified for use with 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. -*/ + 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. + */ namespace MCGalaxy.Commands { public sealed class CmdFixGrass : Command @@ -27,125 +27,140 @@ namespace MCGalaxy.Commands public override LevelPermission defaultRank { get { return LevelPermission.Admin; } } public CmdFixGrass() { } - public override void Use(Player p, string message) - { + public override void Use(Player p, string message) { int totalFixed = 0; - + Level lvl = p.level; switch (message.ToLower()) { case "": - for (int i = 0; i < p.level.blocks.Length; i++) - { - try - { - ushort x, y, z; - p.level.IntToPos(i, out x, out y, out z); - - if (p.level.blocks[i] == Block.dirt) - { - if (Block.LightPass(p.level.blocks[p.level.IntOffset(i, 0, 1, 0)])) - { - p.level.Blockchange(p, x, y, z, Block.grass); - totalFixed++; - } - } - else if (p.level.blocks[i] == Block.grass) - { - if (!Block.LightPass(p.level.blocks[p.level.IntOffset(i, 0, 1, 0)])) - { - p.level.Blockchange(p, x, y, z, Block.dirt); - totalFixed++; - } - } - } - catch { } - } break; + FixDirtAndGrass(p, lvl, ref totalFixed); break; case "light": - for (int i = 0; i < p.level.blocks.Length; i++) - { - try - { - ushort x, y, z; bool skipMe = false; - p.level.IntToPos(i, out x, out y, out z); - - if (p.level.blocks[i] == Block.dirt) - { - for (int iL = 1; iL < (p.level.Height - y); iL++) - { - if (!Block.LightPass(p.level.blocks[p.level.IntOffset(i, 0, iL, 0)])) - { - skipMe = true; break; - } - } - if (!skipMe) - { - p.level.Blockchange(p, x, y, z, Block.grass); - totalFixed++; - } - } - else if (p.level.blocks[i] == Block.grass) - { - for (int iL = 1; iL < (p.level.Height - y); iL++) - { - // Used to change grass to dirt only if all the upper blocks weren't Lightpass. - if (!Block.LightPass(p.level.blocks[p.level.IntOffset(i, 0, iL, 0)])) - { - skipMe = true; break; - } - } - if (skipMe) - { - p.level.Blockchange(p, x, y, z, Block.dirt); - totalFixed++; - } - } - } - catch { } - } break; + FixLight(p, lvl, ref totalFixed); break; case "grass": - for (int i = 0; i < p.level.blocks.Length; i++) - { - try - { - ushort x, y, z; - p.level.IntToPos(i, out x, out y, out z); - - if (p.level.blocks[i] == Block.grass) - if (!Block.LightPass(p.level.blocks[p.level.IntOffset(i, 0, 1, 0)])) - { - p.level.Blockchange(p, x, y, z, Block.dirt); - totalFixed++; - } - } - catch { } - } break; + FixGrass(p, lvl, ref totalFixed); break; case "dirt": - for (int i = 0; i < p.level.blocks.Length; i++) - { - try - { - ushort x, y, z; - p.level.IntToPos(i, out x, out y, out z); - - if (p.level.blocks[i] == Block.dirt) - if (Block.LightPass(p.level.blocks[p.level.IntOffset(i, 0, 1, 0)])) - { - p.level.Blockchange(p, x, y, z, Block.grass); - totalFixed++; - } - } - catch { } - } break; + FixDirt(p, lvl, ref totalFixed); break; default: - Help(p); - return; + Help(p); return; } - Player.SendMessage(p, "Fixed " + totalFixed + " blocks."); } + + + static void FixDirtAndGrass(Player p, Level lvl, ref int totalFixed) { + int index = 0; + for (int y = 0; y < lvl.Height - 1; y++) + for (int z = 0; z < lvl.Length; z++) + for (int x = 0; x < lvl.Width; x++) + { + byte block = lvl.blocks[index]; + if (block == Block.dirt) { + byte above = lvl.blocks[index + lvl.Width * lvl.Length], extAbove = 0; + if (above == Block.custom_block) + extAbove = lvl.GetExtTile((ushort)x, (ushort)(y + 1), (ushort)z); + + if (Block.LightPass(above, extAbove, lvl.CustomBlockDefs)) { + p.level.Blockchange(p, (ushort)x, (ushort)y, (ushort)z, Block.grass); + totalFixed++; + } + } else if (block == Block.grass) { + byte above = lvl.blocks[index + lvl.Width * lvl.Length], extAbove = 0; + if (above == Block.custom_block) + extAbove = lvl.GetExtTile((ushort)x, (ushort)(y + 1), (ushort)z); + + if (!Block.LightPass(above, extAbove, lvl.CustomBlockDefs)) { + p.level.Blockchange(p, (ushort)x, (ushort)y, (ushort)z, Block.dirt); + totalFixed++; + } + } + index++; + } + } + + static void FixLight(Player p, Level lvl, ref int totalFixed) { + int index = 0; + for (int y = 0; y < lvl.Height - 1; y++) + for (int z = 0; z < lvl.Length; z++) + for (int x = 0; x < lvl.Width; x++) + { + byte block = lvl.blocks[index]; + bool inShadow = false; + if (block == Block.dirt) { + for (int i = 1; i < (lvl.Height - y); i++) { + byte above = lvl.blocks[index + (lvl.Width * lvl.Length) * i], extAbove = 0; + if (above == Block.custom_block) + extAbove = lvl.GetExtTile((ushort)x, (ushort)(y + i), (ushort)z); + + if (!Block.LightPass(above, extAbove, lvl.CustomBlockDefs)) { + inShadow = true; break; + } + } + + if (!inShadow) { + p.level.Blockchange(p, (ushort)x, (ushort)y, (ushort)z, Block.grass); + totalFixed++; + } + } else if (block == Block.grass) { + for (int i = 1; i < (lvl.Height - y); i++) { + byte above = lvl.blocks[index + (lvl.Width * lvl.Length) * i], extAbove = 0; + if (above == Block.custom_block) + extAbove = lvl.GetExtTile((ushort)x, (ushort)(y + i), (ushort)z); + + if (!Block.LightPass(above, extAbove, lvl.CustomBlockDefs)) { + inShadow = true; break; + } + } + + if (inShadow) { + p.level.Blockchange(p, (ushort)x, (ushort)y, (ushort)z, Block.dirt); + totalFixed++; + } + } + index++; + } + } + + static void FixDirt(Player p, Level lvl, ref int totalFixed) { + int index = 0; + for (int y = 0; y < lvl.Height - 1; y++) + for (int z = 0; z < lvl.Length; z++) + for (int x = 0; x < lvl.Width; x++) + { + byte block = lvl.blocks[index]; + if (block != Block.dirt) { index++; continue; } + byte above = lvl.blocks[index + lvl.Width * lvl.Length], extAbove = 0; + if (above == Block.custom_block) + extAbove = lvl.GetExtTile((ushort)x, (ushort)(y + 1), (ushort)z); + + if (Block.LightPass(above, extAbove, lvl.CustomBlockDefs)) { + p.level.Blockchange(p, (ushort)x, (ushort)y, (ushort)z, Block.grass); + totalFixed++; + } + index++; + } + } + + static void FixGrass(Player p, Level lvl, ref int totalFixed) { + int index = 0; + for (int y = 0; y < lvl.Height - 1; y++) + for (int z = 0; z < lvl.Length; z++) + for (int x = 0; x < lvl.Width; x++) + { + byte block = lvl.blocks[index]; + if (block != Block.grass) { index++; continue; } + byte above = lvl.blocks[index + lvl.Width * lvl.Length], extAbove = 0; + if (above == Block.custom_block) + extAbove = lvl.GetExtTile((ushort)x, (ushort)(y + 1), (ushort)z); + + if (!Block.LightPass(above, extAbove, lvl.CustomBlockDefs)) { + p.level.Blockchange(p, (ushort)x, (ushort)y, (ushort)z, Block.dirt); + totalFixed++; + } + index++; + } + } - public override void Help(Player p) - { + public override void Help(Player p) { Player.SendMessage(p, "/fixgrass - Fixes grass based on type"); Player.SendMessage(p, " as \"\": Any grass with something on top is made into dirt, dirt with nothing on top is made grass"); Player.SendMessage(p, " as \"light\": Only dirt/grass in sunlight becomes grass"); diff --git a/Levels/Block.cs b/Levels/Block.cs index d2a35e7b3..13de687cc 100644 --- a/Levels/Block.cs +++ b/Levels/Block.cs @@ -945,10 +945,8 @@ namespace MCGalaxy return false; } - public static bool LightPass(byte type) - { - switch (Convert(type)) - { + public static bool LightPass(byte type, byte extType, BlockDefinition[] defs) { + switch (Convert(type)) { case Block.air: case Block.glass: case Block.leaf: @@ -957,9 +955,11 @@ namespace MCGalaxy case Block.mushroom: case Block.redmushroom: case Block.shrub: - case Block.rope: + case Block.rope: return true; - + case Block.custom_block: + BlockDefinition def = defs[extType]; + return def == null ? false : !def.BlocksLight; default: return false; } diff --git a/Levels/Level.Blocks.cs b/Levels/Level.Blocks.cs index 30711781d..b87b891ee 100644 --- a/Levels/Level.Blocks.cs +++ b/Levels/Level.Blocks.cs @@ -343,7 +343,8 @@ namespace MCGalaxy { Player.GlobalBlockchange(this, x, y, z, type, extType); errorLocation = "Growing grass"; - if (GetTile(x, (ushort)(y - 1), z) == Block.grass && GrassDestroy && !Block.LightPass(type)) { + if (GetTile(x, (ushort)(y - 1), z) == Block.grass && GrassDestroy + && !Block.LightPass(type, extType, CustomBlockDefs)) { Blockchange(p, x, (ushort)(y - 1), z, Block.dirt); } diff --git a/Levels/Level.cs b/Levels/Level.cs index e243d9186..619669987 100644 --- a/Levels/Level.cs +++ b/Levels/Level.cs @@ -907,18 +907,18 @@ namespace MCGalaxy AirPhysics.DoAir(this, C, rand); break; case Block.dirt: //Dirt - if (!GrassGrow) - { - C.time = 255; - break; + if (!GrassGrow) { + C.time = 255; break; } if (C.time > 20) { - if (Block.LightPass(GetTile(x, (ushort)(y + 1), z))) - { + byte type = GetTile(x, (ushort)(y + 1), z), extType = 0; + if (type == Block.custom_block) + extType = GetExtTile(x, (ushort)(y + 1), z); + + if (Block.LightPass(type, extType, CustomBlockDefs)) AddUpdate(C.b, Block.grass); - } C.time = 255; } else diff --git a/Player/Player.cs b/Player/Player.cs index 7bdee5bb1..00699fbe1 100644 --- a/Player/Player.cs +++ b/Player/Player.cs @@ -1353,8 +1353,14 @@ namespace MCGalaxy { if ( level.physics == 0 || level.physics == 5 ) { switch ( type ) { case Block.dirt: //instant dirt to grass - if ( Block.LightPass(level.GetTile(x, (ushort)( y + 1 ), z)) ) level.Blockchange(this, x, y, z, (byte)( Block.grass )); - else level.Blockchange(this, x, y, z, (byte)( Block.dirt )); + byte above = level.GetTile(x, (ushort)(y + 1), z), extAbove = 0; + if (type == Block.custom_block) + extAbove = level.GetExtTile(x, (ushort)(y + 1), z); + + if (Block.LightPass(above, extAbove, level.CustomBlockDefs)) + level.Blockchange(this, x, y, z, (byte)Block.grass); + else + level.Blockchange(this, x, y, z, (byte)Block.dirt); break; case Block.staircasestep: //stair handler if ( level.GetTile(x, (ushort)( y - 1 ), z) == Block.staircasestep ) {