diff --git a/MCGalaxy/Blocks/Behaviour/PlaceBehaviour.cs b/MCGalaxy/Blocks/Behaviour/PlaceBehaviour.cs index 9e485891f..bb3bf764e 100644 --- a/MCGalaxy/Blocks/Behaviour/PlaceBehaviour.cs +++ b/MCGalaxy/Blocks/Behaviour/PlaceBehaviour.cs @@ -47,7 +47,7 @@ namespace MCGalaxy.Blocks { internal static void Stairs(Player p, ExtBlock block, ushort x, ushort y, ushort z) { if (!(p.level.physics == 0 || p.level.physics == 5) - || p.level.GetBlock(x, y - 1, z) != (ExtBlock)Block.staircasestep) { + || p.level.GetBlock(x, (ushort)(y - 1), z) != (ExtBlock)Block.staircasestep) { p.ChangeBlock(x, y, z, (ExtBlock)Block.staircasestep); return; } @@ -57,7 +57,7 @@ namespace MCGalaxy.Blocks { internal static void CobbleStairs(Player p, ExtBlock block, ushort x, ushort y, ushort z) { if (!(p.level.physics == 0 || p.level.physics == 5) - || p.level.GetBlock(x, y - 1, z) != (ExtBlock)Block.cobblestoneslab) { + || p.level.GetBlock(x, (ushort)(y - 1), z) != (ExtBlock)Block.cobblestoneslab) { p.ChangeBlock(x, y, z, (ExtBlock)Block.cobblestoneslab); return; } diff --git a/MCGalaxy/Commands/Fun/CmdSlap.cs b/MCGalaxy/Commands/Fun/CmdSlap.cs index a679216c1..75945b4a6 100644 --- a/MCGalaxy/Commands/Fun/CmdSlap.cs +++ b/MCGalaxy/Commands/Fun/CmdSlap.cs @@ -52,21 +52,17 @@ namespace MCGalaxy.Commands.Fun { void DoSlap(Player p, Player who) { int x = who.Pos.BlockX, y = who.Pos.BlockY, z = who.Pos.BlockZ; if (y < 0) y = 0; + Position pos = who.Pos; - string src = p == null ? "(console)" : p.ColoredName; - for (; y <= who.level.Height; y++) { - ExtBlock above = who.level.GetBlock(x, y + 1, z); - if (above.IsInvalid) continue; - if (Collide(who.level, above) != CollideType.Solid) continue; - - pos.Y = (y + 1) * 32 - 6; - BlockDefinition def = who.level.GetBlockDef(above); - if (def != null) pos.Y += def.MinZ * 2; - - who.level.ChatLevel(who.ColoredName + " %Swas slapped into the roof by " + src); - who.SendPos(Entities.SelfID, pos, who.Rot); - return; + + if (who.level.IsValidPos(x, y, z)) { + pos.Y = FindYAbove(who.level, (ushort)x, (ushort)y, (ushort)z); + if (pos.Y != -1) { + who.level.ChatLevel(who.ColoredName + " %Swas slapped into the roof by " + src); + who.SendPos(Entities.SelfID, pos, who.Rot); + return; + } } pos.Y = 1000 * 32; @@ -74,8 +70,23 @@ namespace MCGalaxy.Commands.Fun { who.SendPos(Entities.SelfID, pos, who.Rot); } + static int FindYAbove(Level lvl, ushort x, ushort y, ushort z) { + for (; y <= lvl.Height; y++) { + ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z); + if (above.IsInvalid) continue; + if (Collide(lvl, above) != CollideType.Solid) continue; + + int posY = (y + 1) * 32 - 6; + BlockDefinition def = lvl.GetBlockDef(above); + if (def != null) posY += def.MinZ * 2; + + return posY; + } + return -1; + } + internal static byte Collide(Level lvl, ExtBlock block) { - BlockDefinition def = lvl.GetBlockDef(block); + BlockDefinition def = lvl.GetBlockDef(block); byte collide = def != null ? def.CollideType : CollideType.Solid; if (def == null && !block.IsCustomType) diff --git a/MCGalaxy/Commands/World/CmdDeleteLvl.cs b/MCGalaxy/Commands/World/CmdDeleteLvl.cs index 0894280a2..1423b53c1 100644 --- a/MCGalaxy/Commands/World/CmdDeleteLvl.cs +++ b/MCGalaxy/Commands/World/CmdDeleteLvl.cs @@ -36,7 +36,7 @@ namespace MCGalaxy.Commands.World { if (map == null) return; Level lvl = LevelInfo.FindExact(map); - if (lvl != null && p != null && !lvl.BuildAccess.CheckDetailed(p) > p.Rank) { + if (lvl != null && p != null && !lvl.BuildAccess.CheckDetailed(p)) { Player.Message(p, "Hence you cannot delete this level."); return; } if (lvl == Server.mainLevel) { Player.Message(p, "Cannot delete the main level."); return; } diff --git a/MCGalaxy/Commands/other/CmdAscend.cs b/MCGalaxy/Commands/other/CmdAscend.cs index e028c077b..f80314ca0 100644 --- a/MCGalaxy/Commands/other/CmdAscend.cs +++ b/MCGalaxy/Commands/other/CmdAscend.cs @@ -34,22 +34,32 @@ namespace MCGalaxy.Commands.Misc { int x = p.Pos.BlockX, y = p.Pos.BlockY, z = p.Pos.BlockZ; if (y < 0) y = 0; - for (; y < p.level.Height; y++) { - ExtBlock block = p.level.GetBlock(x, y, z); - if (!block.IsInvalid && CmdSlap.Collide(p.level, block) == CollideType.Solid) continue; - ExtBlock above = p.level.GetBlock(x, y + 1, z); - if (!above.IsInvalid && CmdSlap.Collide(p.level, above) == CollideType.Solid) continue; - - ExtBlock below = p.level.GetBlock(x, y - 1, z); - if (!below.IsInvalid && CmdSlap.Collide(p.level, below) == CollideType.Solid) { - Player.Message(p, "Teleported you up."); - - Position pos = Position.FromFeet(p.Pos.X, y * 32, p.Pos.Z); - p.SendPos(Entities.SelfID, pos, p.Rot); - return; - } + int freeY = -1; + if (p.level.IsValidPos(x, y, z)) { + freeY = FindYAbove(p.level, (ushort)x, (ushort)y, (ushort)z); } - Player.Message(p, "No free spaces found above you"); + + if (freeY == -1) { + Player.Message(p, "No free spaces found above you."); + } else { + Player.Message(p, "Teleported you up."); + Position pos = Position.FromFeet(p.Pos.X, freeY * 32, p.Pos.Z); + p.SendPos(Entities.SelfID, pos, p.Rot); + } + } + + static int FindYAbove(Level lvl, ushort x, ushort y, ushort z) { + for (; y < lvl.Height; y++) { + ExtBlock block = lvl.GetBlock(x, y, z); + if (!block.IsInvalid && CmdSlap.Collide(lvl, block) == CollideType.Solid) continue; + ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z); + if (!above.IsInvalid && CmdSlap.Collide(lvl, above) == CollideType.Solid) continue; + + ExtBlock below = lvl.GetBlock(x, (ushort)(y - 1), z); + if (!below.IsInvalid && CmdSlap.Collide(lvl, below) == CollideType.Solid) + return y; + } + return -1; } public override void Help(Player p) { diff --git a/MCGalaxy/Commands/other/CmdDescend.cs b/MCGalaxy/Commands/other/CmdDescend.cs index c6fbe85a7..9ae08d2f2 100644 --- a/MCGalaxy/Commands/other/CmdDescend.cs +++ b/MCGalaxy/Commands/other/CmdDescend.cs @@ -31,29 +31,38 @@ namespace MCGalaxy.Commands.Misc { if (!Hacks.CanUseHacks(p, p.level)) { Player.Message(p, "You cannot use /descend on this map."); return; } - if (p.Pos.Y < 51 + 4) { Player.Message(p, "No free spaces found below you."); return; } + // Move starting position down half a block since players are a little bit above the ground. - int x = p.Pos.BlockX, y = (p.Pos.Y - 51 - 4) / 32, z = p.Pos.BlockZ; - + int x = p.Pos.BlockX, y = (p.Pos.Y - 51 - 4) / 32, z = p.Pos.BlockZ; if (y > p.level.Height) y = p.level.Height; y--; // start at block below initially - for (; y > 0; y--) { - ExtBlock block = p.level.GetBlock(x, y, z); - if (!block.IsInvalid && CmdSlap.Collide(p.level, block) == CollideType.Solid) continue; - ExtBlock above = p.level.GetBlock(x, y + 1, z); - if (!above.IsInvalid && CmdSlap.Collide(p.level, above) == CollideType.Solid) continue; - - ExtBlock below = p.level.GetBlock(x, y - 1, z); - if (!below.IsInvalid && CmdSlap.Collide(p.level, below) == CollideType.Solid) { - Player.Message(p, "Teleported you down."); - - Position pos = Position.FromFeet(p.Pos.X, y * 32, p.Pos.Z); - p.SendPos(Entities.SelfID, pos, p.Rot); - return; - } + int freeY = -1; + if (p.level.IsValidPos(x, y, z)) { + freeY = FindYBelow(p.level, (ushort)x, (ushort)y, (ushort)z); } - Player.Message(p, "No free spaces found below you."); + + if (freeY == -1) { + Player.Message(p, "No free spaces found below you."); + } else { + Player.Message(p, "Teleported you down."); + Position pos = Position.FromFeet(p.Pos.X, freeY * 32, p.Pos.Z); + p.SendPos(Entities.SelfID, pos, p.Rot); + } + } + + static int FindYBelow(Level lvl, ushort x, ushort y, ushort z) { + for (; y > 0; y--) { + ExtBlock block = lvl.GetBlock(x, y, z); + if (!block.IsInvalid && CmdSlap.Collide(lvl, block) == CollideType.Solid) continue; + ExtBlock above = lvl.GetBlock(x, (ushort)(y + 1), z); + if (!above.IsInvalid && CmdSlap.Collide(lvl, above) == CollideType.Solid) continue; + + ExtBlock below = lvl.GetBlock(x, (ushort)(y - 1), z); + if (!below.IsInvalid && CmdSlap.Collide(lvl, below) == CollideType.Solid) + return y; + } + return -1; } public override void Help(Player p) { diff --git a/MCGalaxy/Levels/Level.Blocks.cs b/MCGalaxy/Levels/Level.Blocks.cs index 2621a7144..635614aeb 100644 --- a/MCGalaxy/Levels/Level.Blocks.cs +++ b/MCGalaxy/Levels/Level.Blocks.cs @@ -68,20 +68,7 @@ namespace MCGalaxy { block.BlockID = blocks[index]; block.ExtID = block.BlockID == Block.custom_block ? GetExtTileNoCheck(x, y, z) : Block.air; return block; - } - - /// Gets the block at the given coordinates. - /// Block.Invalid if coordinates outside map. - public ExtBlock GetBlock(int x, int y, int z) { - if (x < 0 || y < 0 || z < 0 || blocks == null) return ExtBlock.Invalid; - if (x >= Width || y >= Height || z >= Length) return ExtBlock.Invalid; - ExtBlock block; - - block.BlockID = blocks[x + Width * (z + y * Length)]; - block.ExtID = block.BlockID == Block.custom_block - ? GetExtTileNoCheck((ushort)x, (ushort)y, (ushort)z) : Block.air; - return block; - } + } /// Gets whether the block at the given coordinates is air. public bool IsAirAt(ushort x, ushort y, ushort z) {