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) {