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

@ -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.");
} }
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, "/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:
@ -959,7 +957,9 @@ namespace MCGalaxy
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 ) {