diff --git a/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs b/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs index 0a0e0e6e6..e1bda6eda 100644 --- a/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs +++ b/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs @@ -20,13 +20,13 @@ using MCGalaxy.Blocks.Physics; namespace MCGalaxy.Blocks { - /// Handles the player placing a block at the given coordinates. + /// Handles the player deleting a block at the given coordinates. /// Use p.ChangeBlock to do a normal player block change (adds to BlockDB, updates dirt/grass beneath) public delegate void HandleDelete(Player p, ExtBlock oldBlock, ushort x, ushort y, ushort z); - /// Handles the player deleting a block at the given coordinates. + /// Handles the player placing a block at the given coordinates. /// Use p.ChangeBlock to do a normal player block change (adds to BlockDB, updates dirt/grass beneath) - 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); /// Returns whether this block handles the player walking through this block at the given coordinates. /// If this returns true, the usual 'death check' behaviour is skipped. @@ -40,13 +40,13 @@ namespace MCGalaxy.Blocks { /// Retrieves the default place block handler for the given block. 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 diff --git a/MCGalaxy/Blocks/Behaviour/PlaceBehaviour.cs b/MCGalaxy/Blocks/Behaviour/PlaceBehaviour.cs index 5511747de..d5e0e3ab6 100644 --- a/MCGalaxy/Blocks/Behaviour/PlaceBehaviour.cs +++ b/MCGalaxy/Blocks/Behaviour/PlaceBehaviour.cs @@ -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; } diff --git a/MCGalaxy/Blocks/Block.CoreProps.cs b/MCGalaxy/Blocks/Block.CoreProps.cs index 2954a863b..797382799 100644 --- a/MCGalaxy/Blocks/Block.CoreProps.cs +++ b/MCGalaxy/Blocks/Block.CoreProps.cs @@ -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; diff --git a/MCGalaxy/Blocks/BlockProperties.cs b/MCGalaxy/Blocks/BlockProperties.cs index 4b48e77bd..ed619d43c 100644 --- a/MCGalaxy/Blocks/BlockProperties.cs +++ b/MCGalaxy/Blocks/BlockProperties.cs @@ -67,12 +67,20 @@ namespace MCGalaxy.Blocks { /// Whether players can drown inside this block (e.g. water). public bool Drownable; + /// The block ID this is changed into when exposed to sunlight. + public ushort GrassIndex; + + /// The block ID this is changed into when no longer exposed to sunlight. + public ushort DirtIndex; + /// Whether the properties for this block have been modified and hence require saving. 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); + } } } } diff --git a/MCGalaxy/Blocks/Physics/OtherPhysics.cs b/MCGalaxy/Blocks/Physics/OtherPhysics.cs index 88a7b220d..2d7cf45af 100644 --- a/MCGalaxy/Blocks/Physics/OtherPhysics.cs +++ b/MCGalaxy/Blocks/Physics/OtherPhysics.cs @@ -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++; diff --git a/MCGalaxy/Commands/World/CmdBlockProperties.cs b/MCGalaxy/Commands/World/CmdBlockProperties.cs index c98551f5f..21d65ce1f 100644 --- a/MCGalaxy/Commands/World/CmdBlockProperties.cs +++ b/MCGalaxy/Commands/World/CmdBlockProperties.cs @@ -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); } diff --git a/MCGalaxy/Commands/World/CmdFixGrass.cs b/MCGalaxy/Commands/World/CmdFixGrass.cs index 34bfcf835..b3ed08267 100644 --- a/MCGalaxy/Commands/World/CmdFixGrass.cs +++ b/MCGalaxy/Commands/World/CmdFixGrass.cs @@ -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++; } } diff --git a/MCGalaxy/Player/Player.Handlers.cs b/MCGalaxy/Player/Player.Handlers.cs index e15cf87da..68aed3740 100644 --- a/MCGalaxy/Player/Player.Handlers.cs +++ b/MCGalaxy/Player/Player.Handlers.cs @@ -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; }