Fix grass growing to work with BlockDefinitions. (Thanks goodlyay)

This commit is contained in:
UnknownShadow200 2016-01-28 20:23:22 +11:00
parent 95da74a955
commit ccfa9a2881
6 changed files with 162 additions and 139 deletions

View File

@ -94,7 +94,8 @@ namespace MCGalaxy.Commands
Player.SendMessage(p, "&bComplex information for \"" + message + "\":"); Player.SendMessage(p, "&bComplex information for \"" + message + "\":");
Player.SendMessage(p, "&cBlock will appear as a \"" + Block.Name(Block.Convert(b)) + "\" block"); 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! 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! 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"); if (Block.NeedRestart(b)) Player.SendMessage(p, "The block's physics will auto-start");

View File

@ -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 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 namespace MCGalaxy.Commands
{ {
public sealed class CmdFixGrass : Command public sealed class CmdFixGrass : Command
@ -27,125 +27,140 @@ namespace MCGalaxy.Commands
public override LevelPermission defaultRank { get { return LevelPermission.Admin; } } public override LevelPermission defaultRank { get { return LevelPermission.Admin; } }
public CmdFixGrass() { } public CmdFixGrass() { }
public override void Use(Player p, string message) public override void Use(Player p, string message) {
{
int totalFixed = 0; int totalFixed = 0;
Level lvl = p.level;
switch (message.ToLower()) switch (message.ToLower())
{ {
case "": case "":
for (int i = 0; i < p.level.blocks.Length; i++) FixDirtAndGrass(p, lvl, ref totalFixed); break;
{
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;
case "light": case "light":
for (int i = 0; i < p.level.blocks.Length; i++) FixLight(p, lvl, ref totalFixed); break;
{
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;
case "grass": case "grass":
for (int i = 0; i < p.level.blocks.Length; i++) FixGrass(p, lvl, ref totalFixed); break;
{
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;
case "dirt": case "dirt":
for (int i = 0; i < p.level.blocks.Length; i++) FixDirt(p, lvl, ref totalFixed); break;
{
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;
default: default:
Help(p); Help(p); return;
return;
} }
Player.SendMessage(p, "Fixed " + totalFixed + " blocks."); 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 <type> - Fixes grass based on type"); Player.SendMessage(p, "/fixgrass <type> - Fixes grass based on type");
Player.SendMessage(p, "<type> as \"\": Any grass with something on top is made into dirt, dirt with nothing on top is made grass"); Player.SendMessage(p, "<type> as \"\": Any grass with something on top is made into dirt, dirt with nothing on top is made grass");
Player.SendMessage(p, "<type> as \"light\": Only dirt/grass in sunlight becomes grass"); Player.SendMessage(p, "<type> as \"light\": Only dirt/grass in sunlight becomes grass");

View File

@ -945,10 +945,8 @@ namespace MCGalaxy
return false; return false;
} }
public static bool LightPass(byte type) public static bool LightPass(byte type, byte extType, BlockDefinition[] defs) {
{ switch (Convert(type)) {
switch (Convert(type))
{
case Block.air: case Block.air:
case Block.glass: case Block.glass:
case Block.leaf: case Block.leaf:
@ -957,9 +955,11 @@ namespace MCGalaxy
case Block.mushroom: case Block.mushroom:
case Block.redmushroom: case Block.redmushroom:
case Block.shrub: case Block.shrub:
case Block.rope: case Block.rope:
return true; return true;
case Block.custom_block:
BlockDefinition def = defs[extType];
return def == null ? false : !def.BlocksLight;
default: default:
return false; return false;
} }

View File

@ -343,7 +343,8 @@ namespace MCGalaxy {
Player.GlobalBlockchange(this, x, y, z, type, extType); Player.GlobalBlockchange(this, x, y, z, type, extType);
errorLocation = "Growing grass"; 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); Blockchange(p, x, (ushort)(y - 1), z, Block.dirt);
} }

View File

@ -907,18 +907,18 @@ namespace MCGalaxy
AirPhysics.DoAir(this, C, rand); AirPhysics.DoAir(this, C, rand);
break; break;
case Block.dirt: //Dirt case Block.dirt: //Dirt
if (!GrassGrow) if (!GrassGrow) {
{ C.time = 255; break;
C.time = 255;
break;
} }
if (C.time > 20) 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); AddUpdate(C.b, Block.grass);
}
C.time = 255; C.time = 255;
} }
else else

View File

@ -1353,8 +1353,14 @@ namespace MCGalaxy {
if ( level.physics == 0 || level.physics == 5 ) { if ( level.physics == 0 || level.physics == 5 ) {
switch ( type ) { switch ( type ) {
case Block.dirt: //instant dirt to grass 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 )); byte above = level.GetTile(x, (ushort)(y + 1), z), extAbove = 0;
else level.Blockchange(this, x, y, z, (byte)( Block.dirt )); 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; break;
case Block.staircasestep: //stair handler case Block.staircasestep: //stair handler
if ( level.GetTile(x, (ushort)( y - 1 ), z) == Block.staircasestep ) { if ( level.GetTile(x, (ushort)( y - 1 ), z) == Block.staircasestep ) {