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, "&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");

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
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 <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 \"light\": Only dirt/grass in sunlight becomes grass");

View File

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

View File

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

View File

@ -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

View File

@ -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 ) {