diff --git a/Blocks/Behaviour/Block.Behaviour.cs b/Blocks/Behaviour/Block.Behaviour.cs index ab873a209..f8c05e610 100644 --- a/Blocks/Behaviour/Block.Behaviour.cs +++ b/Blocks/Behaviour/Block.Behaviour.cs @@ -25,12 +25,12 @@ namespace MCGalaxy { /// Returns whether this block handles the player placing a block at the given coordinates. /// If this returns true, the usual 'dirt/grass below' behaviour and 'adding to the BlockDB' is skipped. - public delegate bool HandleDelete(Player p, byte block, ushort x, ushort y, ushort z); + public delegate bool HandleDelete(Player p, byte oldBlock, ushort x, ushort y, ushort z); internal static HandleDelete[] deleteHandlers = new HandleDelete[256]; /// Returns whether this block handles the player deleting a block at the given coordinates. /// If this returns true, the usual 'checking dirt/grass below' and 'adding to the BlockDB' is skipped. - public delegate bool HandlePlace(Player p, byte block, ushort x, ushort y, ushort z); + public delegate bool HandlePlace(Player p, byte oldBlock, ushort x, ushort y, ushort z); internal static HandlePlace[] placeHandlers = new Block.HandlePlace[256]; /// Returns whether this block handles the player walking through this block at the given coordinates. @@ -51,14 +51,21 @@ namespace MCGalaxy { deleteHandlers[Block.c4det] = DeleteBehaviour.C4Det; placeHandlers[Block.dirt] = PlaceBehaviour.Dirt; placeHandlers[Block.staircasestep] = PlaceBehaviour.Stairs; + walkthroughHandlers[Block.air_switch] = WalkthroughBehaviour.Door; + walkthroughHandlers[Block.water_door] = WalkthroughBehaviour.Door; + walkthroughHandlers[Block.lava_door] = WalkthroughBehaviour.Door; for (int i = 0; i < 256; i++) { if (Block.mb((byte)i)) { - walkthroughHandlers[i] = WalkthroughBehaviour.MessageBlock; - deleteHandlers[i] = WalkthroughBehaviour.MessageBlock; + walkthroughHandlers[i] = (p, block, x, y, z) => + WalkthroughBehaviour.MessageBlock(p, block, x, y, z, true); + deleteHandlers[i] = (p, block, x, y, z) => + WalkthroughBehaviour.MessageBlock(p, block, x, y, z, false); } else if (Block.portal((byte)i)) { - walkthroughHandlers[i] = WalkthroughBehaviour.Portal; - deleteHandlers[i] = WalkthroughBehaviour.Portal; + walkthroughHandlers[i] = (p, block, x, y, z) => + WalkthroughBehaviour.Portal(p, block, x, y, z, true); + deleteHandlers[i] = (p, block, x, y, z) => + WalkthroughBehaviour.Portal(p, block, x, y, z, false); } byte doorAir = Block.DoorAirs((byte)i); // if not 0, means i is a door block diff --git a/Blocks/Behaviour/WalkthroughBehaviour.cs b/Blocks/Behaviour/WalkthroughBehaviour.cs index 77b9cffa4..bc83d9eaf 100644 --- a/Blocks/Behaviour/WalkthroughBehaviour.cs +++ b/Blocks/Behaviour/WalkthroughBehaviour.cs @@ -23,7 +23,8 @@ namespace MCGalaxy.BlockBehaviour { internal static class WalkthroughBehaviour { - internal static bool Portal(Player p, byte block, ushort x, ushort y, ushort z) { + internal static bool Portal(Player p, byte block, ushort x, ushort y, ushort z, bool checkPos) { + if (checkPos && p.level.PosToInt(x, y, z) == p.lastWalkthrough) return true; p.RevertBlock(x, y, z); try { //safe against SQL injections because no user input is given here @@ -53,7 +54,8 @@ namespace MCGalaxy.BlockBehaviour { } static char[] trimChars = { ' ' }; - internal static bool MessageBlock(Player p, byte block, ushort x, ushort y, ushort z) { + internal static bool MessageBlock(Player p, byte block, ushort x, ushort y, ushort z, bool checkPos) { + if (checkPos && p.level.PosToInt(x, y, z) == p.lastWalkthrough) return true; p.RevertBlock(x, y, z); try { //safe against SQL injections because no user input is given here @@ -88,5 +90,10 @@ namespace MCGalaxy.BlockBehaviour { } return true; } + + internal static bool Door(Player p, byte block, ushort x, ushort y, ushort z) { + p.level.Blockchange(x, y, z, Block.DoorAirs(block)); + return true; + } } } diff --git a/Blocks/Block.cs b/Blocks/Block.cs index b36b7841d..e3913f559 100644 --- a/Blocks/Block.cs +++ b/Blocks/Block.cs @@ -202,25 +202,7 @@ namespace MCGalaxy public static bool Mover(byte type) { - switch (type) - { - case Block.air_portal: - case Block.water_portal: - case Block.lava_portal: - - case Block.air_switch: - case Block.water_door: - case Block.lava_door: - - case Block.MsgAir: - case Block.MsgWater: - case Block.MsgLava: - - case Block.flagbase: - case Block.checkpoint: - return true; - } - return false; + return walkthroughHandlers[type] != null; } public static bool FireKill(byte type) { diff --git a/Blocks/BlockProps.cs b/Blocks/BlockProps.cs new file mode 100644 index 000000000..c50130b61 --- /dev/null +++ b/Blocks/BlockProps.cs @@ -0,0 +1,39 @@ +/* + Copyright 2015 MCGalaxy + + Dual-licensed under the Educational Community License, Version 2.0 and + the GNU General Public License, Version 3 (the "Licenses"); you may + not use this file except in compliance with the Licenses. You may + obtain a copy of the Licenses at + + http://www.opensource.org/licenses/ecl2.php + http://www.gnu.org/licenses/gpl-3.0.html + + Unless required by applicable law or agreed to in writing, + software distributed under the Licenses are distributed on an "AS IS" + BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + or implied. See the Licenses for the specific language governing + permissions and limitations under the Licenses. + */ +using System; + +namespace MCGalaxy.Blocks { + + public struct BlockProps { + + /// Standard block id sent to clients in map and block update packets. + public byte ConvertId; + + /// Block id converted to when the map is saved to a .lvl file. + public byte SaveConvertId; + + /// Block name used for in commands. + public string Name; + + public BlockProps(byte type) { + ConvertId = type; + SaveConvertId = type; + Name = "unknown"; + } + } +} diff --git a/MCGalaxy_.csproj b/MCGalaxy_.csproj index 992cba62e..be1bed2b9 100644 --- a/MCGalaxy_.csproj +++ b/MCGalaxy_.csproj @@ -109,6 +109,7 @@ + diff --git a/Player/Player.Handlers.cs b/Player/Player.Handlers.cs index acdd88630..909108ac4 100644 --- a/Player/Player.Handlers.cs +++ b/Player/Player.Handlers.cs @@ -122,7 +122,7 @@ namespace MCGalaxy { } //else if ( !painting && action == 0 ) { - bP.flags |= 1; + bP.flags |= 1; if (DeleteBlock(b, x, y, z, type, extType)) level.blockCache.Add(bP); } else { @@ -155,7 +155,7 @@ namespace MCGalaxy { Block.HandlePlace handler = Block.placeHandlers[type]; if (handler != null) { - if (handler(this, type, x, y, z)) return false; + if (handler(this, b, x, y, z)) return false; } else { ChangeBlock(x, y, z, type, extType); } @@ -794,19 +794,16 @@ return; byte bHead = level.GetTile(x, y, z); byte bFeet = level.GetTile(x, (ushort)(y - 1), z); - if ( Block.Mover(bHead) || Block.Mover(bFeet) ) { - if ( Block.DoorAirs(bHead) != 0 ) - level.Blockchange(x, y, z, Block.DoorAirs(bHead)); - if ( Block.DoorAirs(bFeet) != 0 ) - level.Blockchange(x, (ushort)(y - 1), z, Block.DoorAirs(bFeet)); - - if (level.PosToInt(x, y, z) != oldIndex) { - Block.HandleWalkthrough handler = Block.walkthroughHandlers[bHead]; - if (handler != null && handler(this, bHead, x, y, z)) return; - handler = Block.walkthroughHandlers[bFeet]; - if (handler != null && handler(this, bFeet, x, (ushort)(y - 1), z)) return; - } + Block.HandleWalkthrough handler = Block.walkthroughHandlers[bHead]; + if (handler != null && handler(this, bHead, x, y, z)) { + lastWalkthrough = level.PosToInt(x, y, z); return; } + handler = Block.walkthroughHandlers[bFeet]; + if (handler != null && handler(this, bFeet, x, (ushort)(y - 1), z)) { + lastWalkthrough = level.PosToInt(x, (ushort)(y - 1), z); return; + } + + lastWalkthrough = level.PosToInt(x, y, z); if ( ( bHead == Block.tntexplosion || bFeet == Block.tntexplosion ) && PlayingTntWars ) { } else if ( Block.Death(bHead) ) HandleDeath(bHead); else if ( Block.Death(bFeet) ) HandleDeath(bFeet); diff --git a/Player/Player.cs b/Player/Player.cs index 9c6763def..0c5992a55 100644 --- a/Player/Player.cs +++ b/Player/Player.cs @@ -227,7 +227,7 @@ namespace MCGalaxy { public int[] BcVar; //Movement - public int oldIndex = -1, oldFallY = 10000; + public int oldIndex = -1, lastWalkthrough = -1, oldFallY = 10000; public int fallCount = 0, drownCount = 0; //Games