mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-22 12:05:51 -04:00
Support custom dirt/grass blocks.
This commit is contained in:
parent
935a90b0cd
commit
3457a6e5fa
@ -20,13 +20,13 @@ using MCGalaxy.Blocks.Physics;
|
||||
|
||||
namespace MCGalaxy.Blocks {
|
||||
|
||||
/// <summary> Handles the player placing a block at the given coordinates. </summary>
|
||||
/// <summary> Handles the player deleting a block at the given coordinates. </summary>
|
||||
/// <remarks> Use p.ChangeBlock to do a normal player block change (adds to BlockDB, updates dirt/grass beneath) </remarks>
|
||||
public delegate void HandleDelete(Player p, ExtBlock oldBlock, ushort x, ushort y, ushort z);
|
||||
|
||||
/// <summary> Handles the player deleting a block at the given coordinates. </summary>
|
||||
/// <summary> Handles the player placing a block at the given coordinates. </summary>
|
||||
/// <remarks> Use p.ChangeBlock to do a normal player block change (adds to BlockDB, updates dirt/grass beneath) </remarks>
|
||||
public delegate void HandlePlace(Player p, ExtBlock oldBlock, ushort x, ushort y, ushort z);
|
||||
public delegate void HandlePlace(Player p, ExtBlock newBlock, ushort x, ushort y, ushort z);
|
||||
|
||||
/// <summary> Returns whether this block handles the player walking through this block at the given coordinates. </summary>
|
||||
/// <remarks> If this returns true, the usual 'death check' behaviour is skipped. </remarks>
|
||||
@ -40,13 +40,13 @@ namespace MCGalaxy.Blocks {
|
||||
/// <summary> Retrieves the default place block handler for the given block. </summary>
|
||||
internal static HandlePlace GetPlaceHandler(ExtBlock block, BlockProps[] props) {
|
||||
switch (block.BlockID) {
|
||||
case Block.Dirt: return PlaceBehaviour.Dirt;
|
||||
case Block.Grass: return PlaceBehaviour.Grass;
|
||||
case Block.C4: return PlaceBehaviour.C4;
|
||||
case Block.C4Detonator: return PlaceBehaviour.C4Det;
|
||||
}
|
||||
|
||||
if (props[block.Index].StackId != Block.Air) return PlaceBehaviour.Stack(block);
|
||||
if (props[block.Index].GrassIndex != Block.Invalid) return PlaceBehaviour.DirtGrow;
|
||||
if (props[block.Index].DirtIndex != Block.Invalid) return PlaceBehaviour.GrassDie;
|
||||
if (props[block.Index].StackId != Block.Air) return PlaceBehaviour.Stack;
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -120,8 +120,6 @@ namespace MCGalaxy.Blocks {
|
||||
case Block.Deadly_FastLava: return SimpleLiquidPhysics.DoFastLava;
|
||||
|
||||
case Block.Air: return AirPhysics.DoAir;
|
||||
case Block.Dirt: return OtherPhysics.DoDirt;
|
||||
case Block.Grass: return OtherPhysics.DoGrass;
|
||||
case Block.Leaves: return LeafPhysics.DoLeaf;
|
||||
case Block.Sapling: return OtherPhysics.DoShrub;
|
||||
case Block.Fire: return FirePhysics.Do;
|
||||
@ -158,6 +156,8 @@ namespace MCGalaxy.Blocks {
|
||||
HandlePhysics animalAI = AnimalAIHandler(props[i].AnimalAI);
|
||||
if (animalAI != null) return animalAI;
|
||||
if (props[i].oDoorIndex != Block.Invalid) return DoorPhysics.oDoor;
|
||||
if (props[i].GrassIndex != Block.Invalid) return OtherPhysics.DoDirtGrow;
|
||||
if (props[i].DirtIndex != Block.Invalid) return OtherPhysics.DoGrassDie;
|
||||
|
||||
i = block.BlockID; // TODO: should this be checking WaterKills/LavaKills
|
||||
// Adv physics updating anything placed next to water or lava
|
||||
|
@ -22,32 +22,36 @@ namespace MCGalaxy.Blocks {
|
||||
|
||||
internal static class PlaceBehaviour {
|
||||
|
||||
internal static void Grass(Player p, ExtBlock block, ushort x, ushort y, ushort z) {
|
||||
DirtGrass(p, (ExtBlock)Block.Grass, x, y, z);
|
||||
}
|
||||
|
||||
internal static void Dirt(Player p, ExtBlock block, ushort x, ushort y, ushort z) {
|
||||
DirtGrass(p, (ExtBlock)Block.Dirt, x, y, z);
|
||||
}
|
||||
|
||||
static void DirtGrass(Player p, ExtBlock block, ushort x, ushort y, ushort z) {
|
||||
static bool SkipGrassDirt(Player p, ExtBlock block) {
|
||||
Level lvl = p.level;
|
||||
return !lvl.Config.GrassGrow || p.ModeBlock == block || !(lvl.physics == 0 || lvl.physics == 5);
|
||||
}
|
||||
|
||||
internal static void GrassDie(Player p, ExtBlock block, ushort x, ushort y, ushort z) {
|
||||
if (SkipGrassDirt(p, block)) { p.ChangeBlock(x, y, z, block); return; }
|
||||
Level lvl = p.level;
|
||||
if (!lvl.Config.GrassGrow || !(lvl.physics == 0 || lvl.physics == 5)) {
|
||||
p.ChangeBlock(x, y, z, block); return;
|
||||
}
|
||||
if (p.ModeBlock.BlockID == Block.Dirt || p.ModeBlock.BlockID == Block.Grass) {
|
||||
p.ChangeBlock(x, y, z, block); return;
|
||||
}
|
||||
|
||||
ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z);
|
||||
block.BlockID = (above.BlockID == Block.Invalid || lvl.LightPasses(above)) ? Block.Grass : Block.Dirt;
|
||||
|
||||
if (above.BlockID != Block.Invalid && !lvl.LightPasses(above)) {
|
||||
ushort index = p.level.Props[block.Index].DirtIndex;
|
||||
block = ExtBlock.FromIndex(index);
|
||||
}
|
||||
p.ChangeBlock(x, y, z, block);
|
||||
}
|
||||
|
||||
internal static HandlePlace Stack(ExtBlock block) {
|
||||
return (p, b, x, y, z) => Stack(p, block, x, y, z);
|
||||
internal static void DirtGrow(Player p, ExtBlock block, ushort x, ushort y, ushort z) {
|
||||
if (SkipGrassDirt(p, block)) { p.ChangeBlock(x, y, z, block); return; }
|
||||
Level lvl = p.level;
|
||||
ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z);
|
||||
|
||||
if (above.BlockID == Block.Invalid || lvl.LightPasses(above)) {
|
||||
ushort index = p.level.Props[block.Index].GrassIndex;
|
||||
block = ExtBlock.FromIndex(index);
|
||||
}
|
||||
p.ChangeBlock(x, y, z, block);
|
||||
}
|
||||
static void Stack(Player p, ExtBlock block, ushort x, ushort y, ushort z) {
|
||||
|
||||
internal static void Stack(Player p, ExtBlock block, ushort x, ushort y, ushort z) {
|
||||
if (p.level.GetBlock(x, (ushort)(y - 1), z) != block) {
|
||||
p.ChangeBlock(x, y, z, block); return;
|
||||
}
|
||||
|
@ -92,6 +92,7 @@ namespace MCGalaxy {
|
||||
Props[CobblestoneSlab].StackId = Cobblestone;
|
||||
Props[Water].Drownable = true; Props[StillWater].Drownable = true;
|
||||
Props[Lava].Drownable = true; Props[StillLava].Drownable = true;
|
||||
Props[Dirt].GrassIndex = Block.Grass; Props[Grass].DirtIndex = Block.Dirt;
|
||||
|
||||
// Block specific physics properties
|
||||
Props[Block.Bird_Black].AnimalAI = AnimalAI.Fly;
|
||||
|
@ -67,12 +67,20 @@ namespace MCGalaxy.Blocks {
|
||||
/// <summary> Whether players can drown inside this block (e.g. water). </summary>
|
||||
public bool Drownable;
|
||||
|
||||
/// <summary> The block ID this is changed into when exposed to sunlight. </summary>
|
||||
public ushort GrassIndex;
|
||||
|
||||
/// <summary> The block ID this is changed into when no longer exposed to sunlight. </summary>
|
||||
public ushort DirtIndex;
|
||||
|
||||
/// <summary> Whether the properties for this block have been modified and hence require saving. </summary>
|
||||
public bool Changed;
|
||||
|
||||
public static BlockProps MakeDefault() {
|
||||
BlockProps props = default(BlockProps);
|
||||
props.oDoorIndex = Block.Invalid;
|
||||
props.GrassIndex = Block.Invalid;
|
||||
props.DirtIndex = Block.Invalid;
|
||||
return props;
|
||||
}
|
||||
|
||||
@ -90,7 +98,8 @@ namespace MCGalaxy.Blocks {
|
||||
w.WriteLine("# This represents the physics properties for blocks, in the format of:");
|
||||
w.WriteLine("# id : Is rails : Is tdoor : Is door : Is message block : Is portal : " +
|
||||
"Killed by water : Killed by lava : Kills players : death message : " +
|
||||
"Animal AI type : Stack block : Is OP block : oDoor block : Drownable");
|
||||
"Animal AI type : Stack block : Is OP block : oDoor block : Drownable : " +
|
||||
"Grass block : Dirt block");
|
||||
for (int i = 0; i < scope.Length; i++) {
|
||||
if (!scope[i].Changed || (selector != null && !selector(i))) continue;
|
||||
BlockProps props = scope[i];
|
||||
@ -102,7 +111,7 @@ namespace MCGalaxy.Blocks {
|
||||
+ props.IsMessageBlock + ":" + props.IsPortal + ":" + props.WaterKills + ":"
|
||||
+ props.LavaKills + ":" + props.KillerBlock + ":" + deathMsg + ":"
|
||||
+ (byte)props.AnimalAI + ":" + props.StackId + ":" + props.OPBlock + ":"
|
||||
+ props.oDoorIndex + ":" + props.Drownable);
|
||||
+ props.oDoorIndex + ":" + props.Drownable + ":" + props.GrassIndex + ":" + props.DirtIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -154,19 +163,23 @@ namespace MCGalaxy.Blocks {
|
||||
scope[idx].AnimalAI = (AnimalAI)ai;
|
||||
}
|
||||
if (parts.Length > 11) {
|
||||
byte stackId; byte.TryParse(parts[11], out stackId);
|
||||
scope[idx].StackId = stackId;
|
||||
byte.TryParse(parts[11], out scope[idx].StackId);
|
||||
}
|
||||
if (parts.Length > 12) {
|
||||
bool.TryParse(parts[12], out scope[idx].OPBlock);
|
||||
}
|
||||
if (parts.Length > 13) {
|
||||
ushort oDoor; ushort.TryParse(parts[13], out oDoor);
|
||||
scope[idx].oDoorIndex = oDoor;
|
||||
ushort.TryParse(parts[13], out scope[idx].oDoorIndex);
|
||||
}
|
||||
if (parts.Length > 14) {
|
||||
bool.TryParse(parts[14], out scope[idx].Drownable);
|
||||
}
|
||||
if (parts.Length > 15) {
|
||||
ushort.TryParse(parts[15], out scope[idx].GrassIndex);
|
||||
}
|
||||
if (parts.Length > 16) {
|
||||
ushort.TryParse(parts[16], out scope[idx].DirtIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -111,28 +111,36 @@ namespace MCGalaxy.Blocks.Physics {
|
||||
C.data.Data = PhysicsArgs.RemoveFromChecks;
|
||||
}
|
||||
|
||||
public static void DoDirt(Level lvl, ref Check C) {
|
||||
public static void DoDirtGrow(Level lvl, ref Check C) {
|
||||
if (!lvl.Config.GrassGrow) { C.data.Data = PhysicsArgs.RemoveFromChecks; return; }
|
||||
ushort x, y, z;
|
||||
lvl.IntToPos(C.b, out x, out y, out z);
|
||||
|
||||
if (C.data.Data > 20) {
|
||||
if (C.data.Data > 20) {
|
||||
ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z);
|
||||
if (lvl.LightPasses(above)) lvl.AddUpdate(C.b, Block.Grass);
|
||||
if (lvl.LightPasses(above)) {
|
||||
ExtBlock block = lvl.GetBlock(x, y, z);
|
||||
ExtBlock grass = ExtBlock.FromIndex(lvl.Props[block.Index].GrassIndex);
|
||||
lvl.AddUpdate(C.b, grass);
|
||||
}
|
||||
C.data.Data = PhysicsArgs.RemoveFromChecks;
|
||||
} else {
|
||||
C.data.Data++;
|
||||
}
|
||||
}
|
||||
|
||||
public static void DoGrass(Level lvl, ref Check C) {
|
||||
public static void DoGrassDie(Level lvl, ref Check C) {
|
||||
if (!lvl.Config.GrassGrow) { C.data.Data = PhysicsArgs.RemoveFromChecks; return; }
|
||||
ushort x, y, z;
|
||||
lvl.IntToPos(C.b, out x, out y, out z);
|
||||
|
||||
if (C.data.Data > 20) {
|
||||
ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z);
|
||||
if (!lvl.LightPasses(above)) lvl.AddUpdate(C.b, Block.Dirt);
|
||||
if (!lvl.LightPasses(above)) {
|
||||
ExtBlock block = lvl.GetBlock(x, y, z);
|
||||
ExtBlock dirt = ExtBlock.FromIndex(lvl.Props[block.Index].DirtIndex);
|
||||
lvl.AddUpdate(C.b, dirt);
|
||||
}
|
||||
C.data.Data = PhysicsArgs.RemoveFromChecks;
|
||||
} else {
|
||||
C.data.Data++;
|
||||
|
@ -125,7 +125,11 @@ namespace MCGalaxy.Commands.World {
|
||||
} else if (prop == "opblock" || prop == "op") {
|
||||
Toggle(p, scope, block, "an OP block", ref scope[i].OPBlock);
|
||||
} else if (prop == "odoor") {
|
||||
SetODoor(p, scope, block, i, text);
|
||||
SetBlock(p, scope, block, i, text, ref scope[i].oDoorIndex, "oDoor");
|
||||
} else if (prop == "grass") {
|
||||
SetBlock(p, scope, block, i, text, ref scope[i].GrassIndex, "Grass form");
|
||||
} else if (prop == "dirt") {
|
||||
SetBlock(p, scope, block, i, text, ref scope[i].DirtIndex, "Dirt form");
|
||||
} else if (prop == "drownable" || prop == "drown") {
|
||||
Toggle(p, scope, block, "drowns players", ref scope[i].Drownable);
|
||||
} else {
|
||||
@ -134,7 +138,8 @@ namespace MCGalaxy.Commands.World {
|
||||
}
|
||||
|
||||
|
||||
static void Toggle(Player p, BlockProps[] scope, ExtBlock block, string type, ref bool on) {
|
||||
static void Toggle(Player p, BlockProps[] scope, ExtBlock block,
|
||||
string type, ref bool on) {
|
||||
on = !on;
|
||||
Level lvl = Player.IsSuper(p) ? null : p.level;
|
||||
Player.Message(p, "Block {0} is {1}: {2}",
|
||||
@ -143,7 +148,8 @@ namespace MCGalaxy.Commands.World {
|
||||
OnPropsChanged(scope, lvl, block);
|
||||
}
|
||||
|
||||
static void SetEnum(Player p, BlockProps[] scope, ExtBlock block, int i, string msg) {
|
||||
static void SetEnum(Player p, BlockProps[] scope, ExtBlock block,
|
||||
int i, string msg) {
|
||||
Level lvl = Player.IsSuper(p) ? null : p.level;
|
||||
AnimalAI ai = AnimalAI.None;
|
||||
if (!CommandParser.GetEnum(p, msg, "Animal AI", ref ai)) return;
|
||||
@ -154,7 +160,8 @@ namespace MCGalaxy.Commands.World {
|
||||
OnPropsChanged(scope, lvl, block);
|
||||
}
|
||||
|
||||
static void SetDeathMessage(Player p, BlockProps[] scope, ExtBlock block, int i, string msg) {
|
||||
static void SetDeathMessage(Player p, BlockProps[] scope, ExtBlock block,
|
||||
int i, string msg) {
|
||||
scope[i].DeathMessage = msg;
|
||||
Level lvl = Player.IsSuper(p) ? null : p.level;
|
||||
|
||||
@ -168,7 +175,8 @@ namespace MCGalaxy.Commands.World {
|
||||
OnPropsChanged(scope, lvl, block);
|
||||
}
|
||||
|
||||
static void SetStackId(Player p, BlockProps[] scope, ExtBlock block, int i, string msg) {
|
||||
static void SetStackId(Player p, BlockProps[] scope, ExtBlock block,
|
||||
int i, string msg) {
|
||||
Level lvl = Player.IsSuper(p) ? null : p.level;
|
||||
|
||||
ExtBlock stackBlock;
|
||||
@ -190,20 +198,20 @@ namespace MCGalaxy.Commands.World {
|
||||
OnPropsChanged(scope, lvl, block);
|
||||
}
|
||||
|
||||
static void SetODoor(Player p, BlockProps[] scope, ExtBlock block, int i, string msg) {
|
||||
static void SetBlock(Player p, BlockProps[] scope, ExtBlock block,
|
||||
int i, string msg, ref ushort target, string type) {
|
||||
Level lvl = Player.IsSuper(p) ? null : p.level;
|
||||
if (msg == null) {
|
||||
scope[i].oDoorIndex = Block.Invalid;
|
||||
Player.Message(p, "oDoor for {0} removed.", BlockName(scope, lvl, block));
|
||||
target = Block.Invalid;
|
||||
Player.Message(p, "{1} for {0} removed.", BlockName(scope, lvl, block), type);
|
||||
} else {
|
||||
ExtBlock other = GetBlock(p, scope, msg);
|
||||
if (other.IsInvalid) return;
|
||||
if (other == block) { Player.Message(p, "ID of oDoor must be different."); return; }
|
||||
ExtBlock other;
|
||||
if (!CommandParser.GetBlock(p, msg, out other)) return;
|
||||
if (other == block) { Player.Message(p, "ID of {0} must be different.", type); return; }
|
||||
|
||||
scope[i].oDoorIndex = (ushort)other.Index;
|
||||
|
||||
Player.Message(p, "oDoor for {0} set to: {1}",
|
||||
BlockName(scope, lvl, block), BlockName(scope, lvl, other));
|
||||
target = (ushort)other.Index;
|
||||
Player.Message(p, "{2} for {0} set to: {1}", BlockName(scope, lvl, block),
|
||||
BlockName(scope, lvl, other), type);
|
||||
}
|
||||
OnPropsChanged(scope, lvl, block);
|
||||
}
|
||||
@ -302,6 +310,12 @@ namespace MCGalaxy.Commands.World {
|
||||
} else if (message.CaselessEq("drownable")) {
|
||||
Player.Message(p, "%HSets whether this block can drown players.");
|
||||
Player.Message(p, "%T/Map death %Hmust be enabled for players to drown.");
|
||||
} else if (message.CaselessEq("grass")) {
|
||||
Player.Message(p, "%HSets the block that this block is changed into, when exposed to sunlight");
|
||||
Player.Message(p, "%HLeave block blank to remove this behaviour.");
|
||||
} else if (message.CaselessEq("dirt")) {
|
||||
Player.Message(p, "%HSets the block that this block is changed into, when no longer exposed to sunlight");
|
||||
Player.Message(p, "%HLeave block blank to remove this behaviour.");
|
||||
} else {
|
||||
Player.Message(p, "&cUnrecognised property \"{0}\"", message);
|
||||
}
|
||||
|
@ -33,55 +33,55 @@ namespace MCGalaxy.Commands.World {
|
||||
if (!LevelInfo.ValidateAction(p, lvl.name, "use %T/fixgrass %Son this level")) return;
|
||||
|
||||
if (message.Length == 0) {
|
||||
FixDirtAndGrass(p, lvl, ref totalFixed);
|
||||
Fix(p, lvl, ref totalFixed, true, true);
|
||||
} else if (message.CaselessEq("light")) {
|
||||
FixLight(p, lvl, ref totalFixed);
|
||||
} else if (message.CaselessEq("grass")) {
|
||||
FixGrass(p, lvl, ref totalFixed);
|
||||
Fix(p, lvl, ref totalFixed, true, false);
|
||||
} else if (message.CaselessEq("dirt")) {
|
||||
FixDirt(p, lvl, ref totalFixed);
|
||||
Fix(p, lvl, ref totalFixed, false, true);
|
||||
} else {
|
||||
Help(p); return;
|
||||
}
|
||||
|
||||
Player.Message(p, "Fixed " + totalFixed + " blocks.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void FixDirtAndGrass(Player p, Level lvl, ref int totalFixed) {
|
||||
static void Fix(Player p, Level lvl, ref int totalFixed, bool fixGrass, bool fixDirt) {
|
||||
int index = 0, maxY = lvl.Height - 1, oneY = lvl.Width * lvl.Length;
|
||||
BufferedBlockSender buffer = new BufferedBlockSender(lvl);
|
||||
ExtBlock above = default(ExtBlock);
|
||||
ExtBlock dirt = (ExtBlock)Block.Dirt, grass = (ExtBlock)Block.Grass;
|
||||
ExtBlock above = default(ExtBlock), block = default(ExtBlock);
|
||||
|
||||
for (int y = 0; y < lvl.Height; y++)
|
||||
for (int z = 0; z < lvl.Length; z++)
|
||||
for (int x = 0; x < lvl.Width; x++)
|
||||
for (ushort y = 0; y < lvl.Height; y++)
|
||||
for (ushort z = 0; z < lvl.Length; z++)
|
||||
for (ushort x = 0; x < lvl.Width; x++)
|
||||
{
|
||||
byte block = lvl.blocks[index];
|
||||
if (block == Block.Dirt) {
|
||||
block.BlockID = lvl.blocks[index];
|
||||
block.ExtID = 0;
|
||||
if (block.BlockID == Block.custom_block)
|
||||
block.ExtID = lvl.GetExtTile(x, y, z);
|
||||
|
||||
if (fixGrass && lvl.Props[block.Index].GrassIndex != Block.Invalid) {
|
||||
above.BlockID = y == maxY ? Block.Air : lvl.blocks[index + oneY];
|
||||
above.ExtID = 0;
|
||||
if (above.BlockID == Block.custom_block)
|
||||
above.ExtID = lvl.GetExtTile((ushort)x, (ushort)(y + 1), (ushort)z);
|
||||
above.ExtID = lvl.GetExtTile(x, (ushort)(y + 1), z);
|
||||
|
||||
if (lvl.LightPasses(above)) {
|
||||
if (p.level.DoBlockchange(p, (ushort)x, (ushort)y, (ushort)z, grass) == 2) {
|
||||
buffer.Add(index, Block.Grass, 0);
|
||||
totalFixed++;
|
||||
}
|
||||
ExtBlock grass = ExtBlock.FromIndex(lvl.Props[block.Index].GrassIndex);
|
||||
if (lvl.LightPasses(above) && p.level.DoBlockchange(p, x, y, z, grass) == 2) {
|
||||
buffer.Add(index, grass.BlockID, grass.ExtID);
|
||||
totalFixed++;
|
||||
}
|
||||
} else if (block == Block.Grass) {
|
||||
} else if (fixDirt && lvl.Props[block.Index].DirtIndex != Block.Invalid) {
|
||||
above.BlockID = y == maxY ? Block.Air : lvl.blocks[index + oneY];
|
||||
above.ExtID = 0;
|
||||
if (above.BlockID == Block.custom_block)
|
||||
above.ExtID = lvl.GetExtTile((ushort)x, (ushort)(y + 1), (ushort)z);
|
||||
above.ExtID = lvl.GetExtTile(x, (ushort)(y + 1), z);
|
||||
|
||||
if (!lvl.LightPasses(above)) {
|
||||
if (p.level.DoBlockchange(p, (ushort)x, (ushort)y, (ushort)z, dirt) == 2) {
|
||||
buffer.Add(index, Block.Dirt, 0);
|
||||
totalFixed++;
|
||||
}
|
||||
ExtBlock dirt = ExtBlock.FromIndex(lvl.Props[block.Index].DirtIndex);
|
||||
if (!lvl.LightPasses(above) && p.level.DoBlockchange(p, x, y, z, dirt) == 2) {
|
||||
buffer.Add(index, dirt.BlockID, dirt.ExtID);
|
||||
totalFixed++;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
@ -92,99 +92,46 @@ namespace MCGalaxy.Commands.World {
|
||||
static void FixLight(Player p, Level lvl, ref int totalFixed) {
|
||||
int index = 0;
|
||||
BufferedBlockSender buffer = new BufferedBlockSender(lvl);
|
||||
ExtBlock above = default(ExtBlock);
|
||||
ExtBlock dirt = (ExtBlock)Block.Dirt, grass = (ExtBlock)Block.Grass;
|
||||
ExtBlock above = default(ExtBlock), block = default(ExtBlock);
|
||||
|
||||
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++)
|
||||
for (ushort y = 0; y < lvl.Height - 1; y++)
|
||||
for (ushort z = 0; z < lvl.Length; z++)
|
||||
for (ushort x = 0; x < lvl.Width; x++)
|
||||
{
|
||||
byte block = lvl.blocks[index];
|
||||
block.BlockID = lvl.blocks[index];
|
||||
block.ExtID = 0;
|
||||
bool inShadow = false;
|
||||
if (block == Block.Dirt) {
|
||||
if (block.BlockID == Block.custom_block)
|
||||
block.ExtID = lvl.GetExtTile(x, y, z);
|
||||
|
||||
if (lvl.Props[block.Index].GrassIndex != Block.Invalid) {
|
||||
for (int i = 1; i < (lvl.Height - y); i++) {
|
||||
above.BlockID = lvl.blocks[index + (lvl.Width * lvl.Length) * i];
|
||||
above.ExtID = 0;
|
||||
if (above.BlockID == Block.custom_block)
|
||||
above.ExtID = lvl.GetExtTile((ushort)x, (ushort)(y + i), (ushort)z);
|
||||
above.ExtID = lvl.GetExtTile(x, (ushort)(y + i), z);
|
||||
|
||||
if (!lvl.LightPasses(above)) { inShadow = true; break; }
|
||||
}
|
||||
|
||||
if (!inShadow && p.level.DoBlockchange(p, (ushort)x, (ushort)y, (ushort)z, grass) == 2) {
|
||||
buffer.Add(index, Block.Grass, 0);
|
||||
ExtBlock grass = ExtBlock.FromIndex(lvl.Props[block.Index].GrassIndex);
|
||||
if (!inShadow && p.level.DoBlockchange(p, x, (ushort)y, z, grass) == 2) {
|
||||
buffer.Add(index, grass.BlockID, grass.ExtID);
|
||||
totalFixed++;
|
||||
}
|
||||
} else if (block == Block.Grass) {
|
||||
} else if (lvl.Props[block.Index].DirtIndex != Block.Invalid) {
|
||||
for (int i = 1; i < (lvl.Height - y); i++) {
|
||||
above.BlockID = lvl.blocks[index + (lvl.Width * lvl.Length) * i];
|
||||
above.ExtID = 0;
|
||||
if (above.BlockID == Block.custom_block)
|
||||
above.ExtID = lvl.GetExtTile((ushort)x, (ushort)(y + i), (ushort)z);
|
||||
above.ExtID = lvl.GetExtTile(x, (ushort)(y + i), z);
|
||||
|
||||
if (!lvl.LightPasses(above)) { inShadow = true; break; }
|
||||
}
|
||||
|
||||
if (inShadow && p.level.DoBlockchange(p, (ushort)x, (ushort)y, (ushort)z, dirt) == 2) {
|
||||
buffer.Add(index, Block.Dirt, 0);
|
||||
totalFixed++;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
buffer.Send(true);
|
||||
}
|
||||
|
||||
static void FixDirt(Player p, Level lvl, ref int totalFixed) {
|
||||
int index = 0, maxY = lvl.Height - 1, oneY = lvl.Width * lvl.Length;
|
||||
BufferedBlockSender buffer = new BufferedBlockSender(lvl);
|
||||
ExtBlock above = default(ExtBlock);
|
||||
ExtBlock grass = (ExtBlock)Block.Grass;
|
||||
|
||||
for (int y = 0; y < lvl.Height; 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; }
|
||||
|
||||
above.BlockID = y == maxY ? Block.Air : lvl.blocks[index + oneY];
|
||||
above.ExtID = 0;
|
||||
if (above.BlockID == Block.custom_block)
|
||||
above.ExtID = lvl.GetExtTile((ushort)x, (ushort)(y + 1), (ushort)z);
|
||||
|
||||
if (lvl.LightPasses(above)) {
|
||||
if (p.level.DoBlockchange(p, (ushort)x, (ushort)y, (ushort)z, grass) == 2) {
|
||||
buffer.Add(index, Block.Grass, 0);
|
||||
totalFixed++;
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
buffer.Send(true);
|
||||
}
|
||||
|
||||
static void FixGrass(Player p, Level lvl, ref int totalFixed) {
|
||||
int index = 0, maxY = lvl.Height - 1, oneY = lvl.Width * lvl.Length;
|
||||
BufferedBlockSender buffer = new BufferedBlockSender(lvl);
|
||||
ExtBlock above = default(ExtBlock);
|
||||
ExtBlock dirt = (ExtBlock)Block.Dirt;
|
||||
|
||||
for (int y = 0; y < lvl.Height; 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; }
|
||||
|
||||
above.BlockID = y == maxY ? Block.Air : lvl.blocks[index + oneY];
|
||||
above.ExtID = 0;
|
||||
if (above.BlockID == Block.custom_block)
|
||||
above.ExtID = lvl.GetExtTile((ushort)x, (ushort)(y + 1), (ushort)z);
|
||||
|
||||
if (!lvl.LightPasses(above)) {
|
||||
if (p.level.DoBlockchange(p, (ushort)x, (ushort)y, (ushort)z, dirt) == 2) {
|
||||
buffer.Add(index, Block.Dirt, 0);
|
||||
ExtBlock dirt = ExtBlock.FromIndex(lvl.Props[block.Index].DirtIndex);
|
||||
if (inShadow && p.level.DoBlockchange(p, x, (ushort)y, z, dirt) == 2) {
|
||||
buffer.Add(index, dirt.BlockID, dirt.ExtID);
|
||||
totalFixed++;
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ namespace MCGalaxy {
|
||||
bool PlaceBlock(ExtBlock old, ushort x, ushort y, ushort z, ExtBlock block) {
|
||||
HandlePlace handler = level.placeHandlers[block.Index];
|
||||
if (handler != null) {
|
||||
handler(this, old, x, y, z);
|
||||
handler(this, block, x, y, z);
|
||||
return true;
|
||||
}
|
||||
return ChangeBlock(x, y, z, block) == 2;
|
||||
@ -176,14 +176,17 @@ namespace MCGalaxy {
|
||||
level.BlockDB.Cache.Add(this, x, y, z, flags, old, block);
|
||||
|
||||
bool autoGrass = level.Config.GrassGrow && (level.physics == 0 || level.physics == 5);
|
||||
if (!autoGrass) return type;
|
||||
if (!autoGrass) return type;
|
||||
ExtBlock below = level.GetBlock(x, (ushort)(y - 1), z);
|
||||
|
||||
byte below = level.GetTile(x, (ushort)(y - 1), z);
|
||||
if (below == Block.Dirt && block.BlockID == Block.Air) {
|
||||
level.Blockchange(this, x, (ushort)(y - 1), z, (ExtBlock)Block.Grass);
|
||||
ushort grassIdx = level.Props[below.Index].GrassIndex;
|
||||
if (grassIdx != Block.Invalid && block.BlockID == Block.Air) {
|
||||
level.Blockchange(this, x, (ushort)(y - 1), z, ExtBlock.FromIndex(grassIdx));
|
||||
}
|
||||
if (below == Block.Grass && !level.LightPasses(block)) {
|
||||
level.Blockchange(this, x, (ushort)(y - 1), z, (ExtBlock)Block.Dirt);
|
||||
|
||||
ushort dirtIdx = level.Props[below.Index].DirtIndex;
|
||||
if (dirtIdx != Block.Invalid && !level.LightPasses(block)) {
|
||||
level.Blockchange(this, x, (ushort)(y - 1), z, ExtBlock.FromIndex(dirtIdx));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user