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

@ -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.");
}
public override void Help(Player p)
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) {
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:
@ -959,7 +957,9 @@ namespace MCGalaxy
case Block.shrub:
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 ) {