diff --git a/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs b/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs index 8c5e4a1dc..d3e4cb015 100644 --- a/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs +++ b/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs @@ -36,32 +36,7 @@ namespace MCGalaxy.Blocks { public delegate void HandlePhysics(Level lvl, ref Check C); public static class BlockBehaviour { - internal static HandleDelete[] deleteHandlers = new HandleDelete[Block.Count]; - internal static HandlePlace[] placeHandlers = new HandlePlace[Block.Count]; - internal static HandleWalkthrough[] walkthroughHandlers = new HandleWalkthrough[Block.Count]; - internal static HandlePhysics[] physicsHandlers = new HandlePhysics[Block.Count]; - internal static HandlePhysics[] physicsDoorsHandlers = new HandlePhysics[Block.Count]; - - /// Initalises default deleting, placing, and walkthrough handling behaviour for the core blocks. - internal static void SetDefaultHandlers() { - for (int i = 0; i < Block.Count; i++) { - SetDefaultHandler(i); - } - } - - internal static void SetDefaultHandler(int i) { - ExtBlock block = new ExtBlock((byte)i, 0); - deleteHandlers[i] = GetDeleteHandler(block, Block.Props); - placeHandlers[i] = GetPlaceHandler(block, Block.Props); - - bool nonSolid = Block.Walkthrough(Block.Convert((byte)i)); - walkthroughHandlers[i] = GetWalkthroughHandler(block, Block.Props, nonSolid); - - physicsHandlers[i] = GetPhysicsHandler(block, Block.Props); - physicsDoorsHandlers[i] = GetPhysicsDoorsHandler(block, Block.Props); - } - - + /// Retrieves the default place block handler for the given block. internal static HandlePlace GetPlaceHandler(ExtBlock block, BlockProps[] props) { switch (block.BlockID) { @@ -81,7 +56,6 @@ namespace MCGalaxy.Blocks { case Block.rocketstart: return DeleteBehaviour.RocketStart; case Block.firework: return DeleteBehaviour.Firework; case Block.c4det: return DeleteBehaviour.C4Det; - case Block.custom_block: return DeleteBehaviour.CustomBlock; case Block.door_tree_air: return DeleteBehaviour.RevertDoor; case Block.door_tnt_air: return DeleteBehaviour.RevertDoor; case Block.door_green_air: return DeleteBehaviour.RevertDoor; @@ -106,7 +80,6 @@ namespace MCGalaxy.Blocks { case Block.water_door: return WalkthroughBehaviour.Door; case Block.lava_door: return WalkthroughBehaviour.Door; case Block.train: return WalkthroughBehaviour.Train; - case Block.custom_block: return WalkthroughBehaviour.CustomBlock; } int i = block.Index; diff --git a/MCGalaxy/Blocks/Behaviour/DeleteBehaviour.cs b/MCGalaxy/Blocks/Behaviour/DeleteBehaviour.cs index 8b6a3abfb..553d5fa94 100644 --- a/MCGalaxy/Blocks/Behaviour/DeleteBehaviour.cs +++ b/MCGalaxy/Blocks/Behaviour/DeleteBehaviour.cs @@ -91,7 +91,7 @@ namespace MCGalaxy.Blocks { internal static void ODoor(Player p, ExtBlock block, ushort x, ushort y, ushort z) { if (block.BlockID == Block.odoor8 || block.BlockID == Block.odoor8_air) { - p.level.Blockchange(x, y, z, (ExtBlock)Block.Props[block.BlockID].ODoorId); + p.level.Blockchange(x, y, z, (ExtBlock)p.level.BlockProps[block.Index].ODoorId); } else { p.RevertBlock(x, y, z); } @@ -112,20 +112,5 @@ namespace MCGalaxy.Blocks { p.ChangeBlock(x, y, z, ExtBlock.Air); } } - - internal static void CustomBlock(Player p, ExtBlock block, ushort x, ushort y, ushort z) { - byte extBlock = p.level.GetExtTile(x, y, z); - if (p.level.CustomBlockProps[extBlock].IsPortal) { - DoPortal(p, block, x, y, z); - } else if (p.level.CustomBlockProps[extBlock].IsMessageBlock) { - DoMessageBlock(p, block, x, y, z); - } else if (p.level.CustomBlockProps[extBlock].IsTDoor) { - RevertDoor(p, block, x, y, z); - } else if (p.level.CustomBlockProps[extBlock].IsDoor) { - Door(p, block, x, y, z); - } else { - p.ChangeBlock(x, y, z, ExtBlock.Air); - } - } } } diff --git a/MCGalaxy/Blocks/Behaviour/WalkthroughBehaviour.cs b/MCGalaxy/Blocks/Behaviour/WalkthroughBehaviour.cs index 40710e76a..7eda87370 100644 --- a/MCGalaxy/Blocks/Behaviour/WalkthroughBehaviour.cs +++ b/MCGalaxy/Blocks/Behaviour/WalkthroughBehaviour.cs @@ -37,24 +37,7 @@ namespace MCGalaxy.Blocks { internal static bool Train(Player p, ExtBlock block, ushort x, ushort y, ushort z) { if (!p.trainInvincible) p.HandleDeath((ExtBlock)Block.train); return true; - } - - internal static bool CustomBlock(Player p, ExtBlock block, ushort x, ushort y, ushort z) { - byte extBlock = p.level.GetExtTile(x, y, z); - BlockDefinition def = p.level.CustomBlockDefs[extBlock]; - if (def == null) return false; // custom block was removed - if (def.CollideType == CollideType.Solid) return false; - - if (p.level.CustomBlockProps[extBlock].IsPortal) { - return DoPortal(p, block, x, y, z); - } else if (p.level.CustomBlockProps[extBlock].IsMessageBlock) { - return DoMessageBlock(p, block, x, y, z); - } else if (p.level.CustomBlockProps[extBlock].IsDoor) { - return Door(p, block, x, y, z); - } - return false; - } - + } internal static bool DoPortal(Player p, ExtBlock block, ushort x, ushort y, ushort z) { if (p.level.PosToInt(x, y, z) == p.lastWalkthrough) return true; diff --git a/MCGalaxy/Blocks/Block.cs b/MCGalaxy/Blocks/Block.cs index 8c68a678c..b7b023960 100644 --- a/MCGalaxy/Blocks/Block.cs +++ b/MCGalaxy/Blocks/Block.cs @@ -95,12 +95,6 @@ namespace MCGalaxy { return block >= water && block <= lavastill; } - [Obsolete] - public static bool OPBlocks(byte block) { return Props[block].OPBlock; } - - [Obsolete] - public static bool Death(byte block) { return Props[block].KillerBlock; } - public static bool BuildIn(byte block) { if (block == op_water || block == op_lava || Props[block].IsPortal || Props[block].IsMessageBlock) return false; @@ -108,16 +102,9 @@ namespace MCGalaxy { return block >= water && block <= lavastill; } - public static bool Mover(byte block) { return BlockBehaviour.walkthroughHandlers[block] != null; } - - [Obsolete] - public static bool FireKill(byte block) { return block != air && Props[block].LavaKills; } - - [Obsolete] - public static bool LavaKill(byte block) { return Props[block].LavaKills; } - - [Obsolete] - public static bool WaterKill(byte block) { return Props[block].WaterKills; } + public static bool Mover(byte block) { + return BlockBehaviour.GetWalkthroughHandler(new ExtBlock(block, 0), Block.Props, Walkthrough(Convert(block))) != null; + } public static bool LightPass(byte block) { switch (Convert(block)) { @@ -178,12 +165,6 @@ namespace MCGalaxy { return false; } - [Obsolete] - public static bool portal(byte block) { return Props[block].IsPortal; } - - [Obsolete] - public static bool mb(byte block) { return Props[block].IsMessageBlock; } - public static bool Physics(byte block) { //returns false if placing block cant actualy cause any physics to happen if (Props[block].IsMessageBlock || Props[block].IsPortal) return false; if (Props[block].IsDoor || Props[block].IsTDoor) return false; @@ -218,12 +199,6 @@ namespace MCGalaxy { return true; } } - - [Obsolete] - public static bool tDoor(byte block) { return Props[block].IsTDoor; } - - [Obsolete] - public static byte odoor(byte block) { return Props[block].ODoorId; } public static AABB BlockAABB(ExtBlock block, Level lvl) { BlockDefinition def = lvl.GetBlockDef(block); @@ -242,8 +217,12 @@ namespace MCGalaxy { public static void SetBlocks() { SetCoreProperties(); BlockProps.Load("core", Block.Props); - BlockPerms.Load(); - BlockBehaviour.SetDefaultHandlers(); + BlockPerms.Load(); + + Level[] loaded = LevelInfo.Loaded.Items; + foreach (Level lvl in loaded) { + lvl.SetBlockHandlers(); + } } [Obsolete("Use BlockPerms.CanModify()")] diff --git a/MCGalaxy/Blocks/BlockDefinitions.cs b/MCGalaxy/Blocks/BlockDefinitions.cs index 3620552dd..831babe46 100644 --- a/MCGalaxy/Blocks/BlockDefinitions.cs +++ b/MCGalaxy/Blocks/BlockDefinitions.cs @@ -146,7 +146,7 @@ namespace MCGalaxy { for (int i = 0; i < lvl.CustomBlockDefs.Length; i++) { if (lvl.CustomBlockDefs[i] != oldGlobalDefs[i]) continue; lvl.CustomBlockDefs[i] = GlobalDefs[i]; - lvl.CustomBlockProps[i] = GlobalProps[i]; + lvl.BlockProps[i] = GlobalProps[i]; } } } @@ -160,11 +160,14 @@ namespace MCGalaxy { foreach (Level lvl in loaded) { if (lvl.CustomBlockDefs[block] == null) { lvl.CustomBlockDefs[block] = def; + lvl.SetBlockHandler(ExtBlock.FromRaw(block)); } } } + defs[block] = def; if (global) Block.SetDefaultNames(); + if (!global) level.SetBlockHandler(ExtBlock.FromRaw(block)); Player[] players = PlayerInfo.Online.Items; foreach (Player pl in players) { @@ -194,11 +197,13 @@ namespace MCGalaxy { foreach (Level lvl in loaded) { if (lvl.CustomBlockDefs[block] == GlobalDefs[block]) { lvl.CustomBlockDefs[block] = null; + lvl.SetBlockHandler(ExtBlock.FromRaw(block)); } } } defs[block] = null; if (global) Block.SetDefaultNames(); + if (!global) level.SetBlockHandler(ExtBlock.FromRaw(block)); Player[] players = PlayerInfo.Online.Items; foreach (Player pl in players) { diff --git a/MCGalaxy/Blocks/Physics/ActivateablePhysics.cs b/MCGalaxy/Blocks/Physics/ActivateablePhysics.cs index 6b0cbd314..12b2c4e28 100644 --- a/MCGalaxy/Blocks/Physics/ActivateablePhysics.cs +++ b/MCGalaxy/Blocks/Physics/ActivateablePhysics.cs @@ -59,31 +59,21 @@ namespace MCGalaxy.Blocks.Physics { /// Activates doors, tdoors and toggles odoors at (x, y, z) public static void DoDoors(Level lvl, ushort x, ushort y, ushort z, bool instant) { - int index = lvl.PosToInt(x, y, z); - if (index < 0) return; + int index; + ExtBlock block = lvl.GetBlock(x, y, z, out index); + if (index == -1) return; - byte block = lvl.blocks[index]; - bool ext = block == Block.custom_block; - BlockProps[] props = Block.Props; - ExtBlock block2 = default(ExtBlock); // TODO: temp hack - block2.BlockID = block; - - if (ext) { - block = lvl.GetExtTile(x, y, z); - block2.ExtID = block; - props = lvl.CustomBlockProps; - } - - if (props[block].IsDoor) { + int i = block.Index; + if (lvl.BlockProps[i].IsDoor) { byte physForm; - PhysicsArgs args = GetDoorArgs(block2, out physForm); + PhysicsArgs args = GetDoorArgs(block, out physForm); if (!instant) lvl.AddUpdate(index, physForm, false, args); else lvl.Blockchange(index, (ExtBlock)physForm, false, args); - } else if (props[block].IsTDoor) { - PhysicsArgs args = GetTDoorArgs(block, ext); + } else if (lvl.BlockProps[i].IsTDoor) { + PhysicsArgs args = GetTDoorArgs(block); lvl.AddUpdate(index, Block.air, false, args); } else { - byte oDoor = props[block].ODoorId; + byte oDoor = lvl.BlockProps[i].ODoorId; if (oDoor != Block.Invalid) lvl.AddUpdate(index, oDoor, true); } @@ -108,12 +98,12 @@ namespace MCGalaxy.Blocks.Physics { return args; } - internal static PhysicsArgs GetTDoorArgs(byte raw, bool isExt) { + internal static PhysicsArgs GetTDoorArgs(ExtBlock block) { PhysicsArgs args = default(PhysicsArgs); args.Type1 = PhysicsArgs.Wait; args.Value1 = 16; - args.Type2 = PhysicsArgs.Revert; args.Value2 = raw; + args.Type2 = PhysicsArgs.Revert; args.Value2 = block.RawID; args.Door = true; - args.ExtBlock = isExt; + args.ExtBlock = block.BlockID == Block.custom_block; return args; } diff --git a/MCGalaxy/Blocks/Physics/DoorPhysics.cs b/MCGalaxy/Blocks/Physics/DoorPhysics.cs index 1e9bed7da..4a01f4ade 100644 --- a/MCGalaxy/Blocks/Physics/DoorPhysics.cs +++ b/MCGalaxy/Blocks/Physics/DoorPhysics.cs @@ -67,28 +67,22 @@ namespace MCGalaxy.Blocks.Physics { lvl.IntToPos(C.b, out x, out y, out z); int oneY = lvl.Width * lvl.Length; - if (x > 0) ActivateTDoor(lvl, C.b - 1); - if (x < lvl.Width - 1) ActivateTDoor(lvl, C.b + 1); - if (y > 0) ActivateTDoor(lvl, C.b - oneY); - if (y < lvl.Height - 1) ActivateTDoor(lvl, C.b + oneY); - if (z > 0) ActivateTDoor(lvl, C.b - lvl.Width); - if (z < lvl.Length - 1) ActivateTDoor(lvl, C.b + lvl.Width); + ActivateTDoor(lvl, (ushort)(x - 1), y, z); + ActivateTDoor(lvl, (ushort)(x + 1), y, z); + ActivateTDoor(lvl, x, (ushort)(y - 1), z); + ActivateTDoor(lvl, x, (ushort)(y + 1), z); + ActivateTDoor(lvl, x, y, (ushort)(z -1)); + ActivateTDoor(lvl, x, y, (ushort)(z + 1)); } - static void ActivateTDoor(Level lvl, int index) { - byte block = lvl.blocks[index]; - if (block != Block.custom_block) { - if (!Block.Props[block].IsTDoor) return; - - PhysicsArgs args = ActivateablePhysics.GetTDoorArgs(block, false); + static void ActivateTDoor(Level lvl, ushort x, ushort y, ushort z) { + int index; + ExtBlock block = lvl.GetBlock(x, y, z, out index); + + if (index >= 0 && lvl.BlockProps[block.Index].IsTDoor) { + PhysicsArgs args = ActivateablePhysics.GetTDoorArgs(block); lvl.AddUpdate(index, Block.air, false, args); - } else { - block = lvl.GetExtTile(index); - if (!lvl.CustomBlockProps[block].IsTDoor) return; - - PhysicsArgs args = ActivateablePhysics.GetTDoorArgs(block, true); - lvl.AddUpdate(index, Block.air, false, args); - } + } } } } \ No newline at end of file diff --git a/MCGalaxy/Blocks/Physics/ExtLiquidPhysics.cs b/MCGalaxy/Blocks/Physics/ExtLiquidPhysics.cs index 219e24d13..22102c810 100644 --- a/MCGalaxy/Blocks/Physics/ExtLiquidPhysics.cs +++ b/MCGalaxy/Blocks/Physics/ExtLiquidPhysics.cs @@ -52,8 +52,10 @@ namespace MCGalaxy.Blocks.Physics { } static void MagmaFlow(Level lvl, int x, int y, int z, ref bool flowUp) { - int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z); - if (index >= 0 && Block.LavaKill(lvl.blocks[index])) { + int index; + ExtBlock block = lvl.GetBlock((ushort)x, (ushort)y, (ushort)z, out index); + + if (index >= 0 && lvl.BlockProps[block.Index].LavaKills) { lvl.AddUpdate(index, Block.magma); flowUp = true; } @@ -89,8 +91,10 @@ namespace MCGalaxy.Blocks.Physics { } static void GeyserFlow(Level lvl, int x, int y, int z, ref bool flowUp) { - int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z); - if (index >= 0 && Block.WaterKill(lvl.blocks[index])) { + int index; + ExtBlock block = lvl.GetBlock((ushort)x, (ushort)y, (ushort)z, out index); + + if (index >= 0 && lvl.BlockProps[block.Index].WaterKills) { lvl.AddUpdate(index, Block.geyser); flowUp = true; } diff --git a/MCGalaxy/Blocks/Physics/ExtraInfoPhysics.cs b/MCGalaxy/Blocks/Physics/ExtraInfoPhysics.cs index a83f5efc1..0c5d968fc 100644 --- a/MCGalaxy/Blocks/Physics/ExtraInfoPhysics.cs +++ b/MCGalaxy/Blocks/Physics/ExtraInfoPhysics.cs @@ -30,9 +30,8 @@ namespace MCGalaxy.Blocks.Physics { if (!C.data.HasWait) return false; if (C.data.Door && C.data.Data == 0) { - bool tdoor = false; - if (!C.data.ExtBlock) tdoor = Block.Props[C.data.Value2].IsTDoor; - else tdoor = lvl.CustomBlockProps[C.data.Value2].IsTDoor; + int i = C.data.Value2 + (C.data.ExtBlock ? 256 : 0); + bool tdoor = lvl.BlockProps[i].IsTDoor; if (tdoor) DoorPhysics.tDoor(lvl, ref C); else DoorPhysics.Door(lvl, ref C); @@ -69,9 +68,8 @@ namespace MCGalaxy.Blocks.Physics { if (args.Wait) { if (C.data.Door && C.data.Data == 0) { - bool tdoor = false; - if (!C.data.ExtBlock) tdoor = Block.Props[C.data.Value2].IsTDoor; - else tdoor = lvl.CustomBlockProps[C.data.Value2].IsTDoor; + int i = C.data.Value2 + (C.data.ExtBlock ? 256 : 0); + bool tdoor = lvl.BlockProps[i].IsTDoor; if (tdoor) DoorPhysics.tDoor(lvl, ref C); else DoorPhysics.Door(lvl, ref C); diff --git a/MCGalaxy/Blocks/Physics/FirePhysics.cs b/MCGalaxy/Blocks/Physics/FirePhysics.cs index 842f221c2..66d4abfa5 100644 --- a/MCGalaxy/Blocks/Physics/FirePhysics.cs +++ b/MCGalaxy/Blocks/Physics/FirePhysics.cs @@ -31,15 +31,9 @@ namespace MCGalaxy.Blocks.Physics { static void ExpandDiagonal(Level lvl, ushort x, ushort y, ushort z, int dx, int dy, int dz) { - byte block = lvl.GetTile((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz)); - if (block == Block.air) return; - - if (block == Block.custom_block) { - block = lvl.GetExtTile((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz)); - if (!lvl.CustomBlockProps[block].LavaKills) return; - } else { - if (!Block.Props[block].LavaKills) return; - } + ExtBlock block = lvl.GetBlock((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz)); + if (block.BlockID == Block.air) return; + if (!lvl.BlockProps[block.Index].LavaKills) return; if (dx != 0) lvl.AddUpdate(lvl.PosToInt((ushort)(x + dx), y, z), Block.fire); @@ -50,19 +44,13 @@ namespace MCGalaxy.Blocks.Physics { } static void ExpandAvanced(Level lvl, int x, int y, int z) { - int index = lvl.PosToInt((ushort)x, (ushort)y, (ushort)z); - if (index < 0) return; + int index; + ExtBlock block = lvl.GetBlock((ushort)x, (ushort)y, (ushort)z, out index); + if (index < 0 || block.BlockID == Block.air) return; - byte block = lvl.blocks[index]; - if (block == Block.air) return; - - if (block == Block.tnt) { + if (block.BlockID == Block.tnt) { lvl.MakeExplosion((ushort)x, (ushort)y, (ushort)z, -1); - } else if (block == Block.custom_block) { - block = lvl.GetExtTileNoCheck((ushort)x, (ushort)y, (ushort)z); - if (lvl.CustomBlockProps[block].LavaKills) - lvl.AddUpdate(index, Block.fire); - } else if (Block.Props[block].LavaKills) { + } else if (lvl.BlockProps[block.Index].LavaKills) { lvl.AddUpdate(index, Block.fire); } } diff --git a/MCGalaxy/Blocks/Physics/LiquidPhysics.cs b/MCGalaxy/Blocks/Physics/LiquidPhysics.cs index 650cc6444..b092025f1 100644 --- a/MCGalaxy/Blocks/Physics/LiquidPhysics.cs +++ b/MCGalaxy/Blocks/Physics/LiquidPhysics.cs @@ -22,12 +22,13 @@ namespace MCGalaxy.Blocks.Physics { public static class LiquidPhysics { public static void PhysWater(Level lvl, ushort x, ushort y, ushort z, byte type) { - int b = lvl.PosToInt(x, y, z); + int b; + ExtBlock block = lvl.GetBlock(x, y, z, out b); if (b == -1) return; if (Server.lava.active && Server.lava.map == lvl && Server.lava.InSafeZone(x, y, z)) return; - switch (lvl.blocks[b]) { + switch (block.BlockID) { case Block.air: if (!lvl.CheckSpongeWater(x, y, z)) lvl.AddUpdate(b, type); break; @@ -44,14 +45,8 @@ namespace MCGalaxy.Blocks.Physics { lvl.AddCheck(b); break; default: - // //Adv physics kills flowers and mushrooms in water - byte block = lvl.blocks[b]; - if (block != Block.custom_block) { - if (!Block.Props[block].WaterKills) break; - } else { - block = lvl.GetExtTile(x, y, z); - if (!lvl.CustomBlockProps[block].WaterKills) break; - } + // Adv physics kills flowers and mushrooms in water + if (!lvl.BlockProps[block.Index].WaterKills) break; if (lvl.physics > 1 && !lvl.CheckSpongeWater(x, y, z)) lvl.AddUpdate(b, Block.air); @@ -60,12 +55,13 @@ namespace MCGalaxy.Blocks.Physics { } public static void PhysLava(Level lvl, ushort x, ushort y, ushort z, byte type) { - int b = lvl.PosToInt(x, y, z); + int b; + ExtBlock block = lvl.GetBlock(x, y, z, out b); if (b == -1) return; if (Server.lava.active && Server.lava.map == lvl && Server.lava.InSafeZone(x, y, z)) return; - switch (lvl.blocks[b]) { + switch (block.BlockID) { case Block.air: if (!lvl.CheckSpongeLava(x, y, z)) lvl.AddUpdate(b, type); break; @@ -87,13 +83,7 @@ namespace MCGalaxy.Blocks.Physics { default: //Adv physics kills flowers, wool, mushrooms, and wood type blocks in lava - byte block = lvl.blocks[b]; - if (block != Block.custom_block) { - if (!Block.Props[block].LavaKills) break; - } else { - block = lvl.GetExtTile(x, y, z); - if (!lvl.CustomBlockProps[block].LavaKills) break; - } + if (!lvl.BlockProps[block.Index].LavaKills) break; if (lvl.physics > 1 && !lvl.CheckSpongeLava(x, y, z)) lvl.AddUpdate(b, Block.air); diff --git a/MCGalaxy/Blocks/Physics/SimpleLiquidPhysics.cs b/MCGalaxy/Blocks/Physics/SimpleLiquidPhysics.cs index 8f1233bfd..4f3619dd1 100644 --- a/MCGalaxy/Blocks/Physics/SimpleLiquidPhysics.cs +++ b/MCGalaxy/Blocks/Physics/SimpleLiquidPhysics.cs @@ -138,13 +138,13 @@ namespace MCGalaxy.Blocks.Physics { } static bool WaterBlocked(Level lvl, ushort x, ushort y, ushort z) { - int b = lvl.PosToInt(x, y, z); - if (b == -1) - return true; + int b; + ExtBlock block = lvl.GetBlock(x, y, z, out b); + if (b == -1) return true; if (Server.lava.active && Server.lava.map == lvl && Server.lava.InSafeZone(x, y, z)) return true; - switch (lvl.blocks[b]) { + switch (block.BlockID) { case Block.air: case Block.lava: case Block.lava_fast: @@ -158,14 +158,8 @@ namespace MCGalaxy.Blocks.Physics { return false; default: - //Adv physics kills flowers, mushroom blocks in water - byte block = lvl.blocks[b]; - if (block != Block.custom_block) { - if (!Block.Props[block].WaterKills) return true; - } else { - block = lvl.GetExtTile(x, y, z); - if (!lvl.CustomBlockProps[block].WaterKills) return true; - } + // Adv physics kills flowers, mushroom blocks in water + if (!lvl.BlockProps[block.Index].WaterKills) break; if (lvl.physics > 1 && !lvl.CheckSpongeWater(x, y, z)) return false; break; @@ -256,12 +250,13 @@ namespace MCGalaxy.Blocks.Physics { } static bool LavaBlocked(Level lvl, ushort x, ushort y, ushort z) { - int b = lvl.PosToInt(x, y, z); + int b; + ExtBlock block = lvl.GetBlock(x, y, z, out b); if (b == -1) return true; if (Server.lava.active && Server.lava.map == lvl && Server.lava.InSafeZone(x, y, z)) return true; - switch (lvl.blocks[b]) { + switch (block.BlockID) { case Block.air: return false; @@ -275,14 +270,8 @@ namespace MCGalaxy.Blocks.Physics { return false; default: - //Adv physics kills flowers, wool, mushrooms, and wood type blocks in lava - byte block = lvl.blocks[b]; - if (block != Block.custom_block) { - if (!Block.Props[block].LavaKills) return true; - } else { - block = lvl.GetExtTile(x, y, z); - if (!lvl.CustomBlockProps[block].LavaKills) return true; - } + // Adv physics kills flowers, wool, mushrooms, and wood type blocks in lava + if (!lvl.BlockProps[block.Index].LavaKills) break; if (lvl.physics > 1 && !lvl.CheckSpongeLava(x, y, z)) return false; break; diff --git a/MCGalaxy/Blocks/Physics/TntPhysics.cs b/MCGalaxy/Blocks/Physics/TntPhysics.cs index f4c0fba7e..33aed1847 100644 --- a/MCGalaxy/Blocks/Physics/TntPhysics.cs +++ b/MCGalaxy/Blocks/Physics/TntPhysics.cs @@ -121,8 +121,10 @@ namespace MCGalaxy.Blocks.Physics { bool force = false, TntWarsGame game = null) { Random rand = new Random(); if ((lvl.physics < 2 || lvl.physics == 5) && !force) return; - int index = lvl.PosToInt(x, y, z); - if (index >= 0 && !Block.Props[lvl.blocks[index]].OPBlock) + + int index; + ExtBlock block = lvl.GetBlock(x, y, z, out index); + if (index >= 0 && !lvl.BlockProps[block.Index].OPBlock) lvl.AddUpdate(index, Block.tntexplosion, true); Explode(lvl, x, y, z, size + 1, rand, -1, game); diff --git a/MCGalaxy/Blocks/Physics/TrainPhysics.cs b/MCGalaxy/Blocks/Physics/TrainPhysics.cs index b581e6ab9..15f11641c 100644 --- a/MCGalaxy/Blocks/Physics/TrainPhysics.cs +++ b/MCGalaxy/Blocks/Physics/TrainPhysics.cs @@ -33,33 +33,22 @@ namespace MCGalaxy.Blocks.Physics { for (int dy = -dirY; dy != 2 * dirY; dy += dirY) for (int dz = -dirZ; dz != 2 * dirZ; dz += dirZ) { - byte tileBelow = lvl.GetTile((ushort)(x + dx),(ushort)(y + dy - 1), (ushort)(z + dz)); - byte tile = lvl.GetTile((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz)); + ExtBlock below = lvl.GetBlock((ushort)(x + dx),(ushort)(y + dy - 1), (ushort)(z + dz)); + ExtBlock block = lvl.GetBlock((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz)); + bool isRails = lvl.BlockProps[below.BlockID].IsRails; - bool isRails = false; - if (tileBelow != Block.custom_block) { - isRails = Block.Props[tileBelow].IsRails; - } else { - byte extBelow = lvl.GetExtTile((ushort)(x + dx), (ushort)(y + dy - 1), (ushort)(z + dz)); - isRails = lvl.CustomBlockProps[extBelow].IsRails; - } - - if (isRails && (tile == Block.air || tile == Block.water) + if (isRails && (block.BlockID == Block.air || block.BlockID == Block.water) && !lvl.listUpdateExists.Get(x + dx, y + dy, z + dz)) { - lvl.AddUpdate(lvl.PosToInt((ushort)(x + dx), - (ushort)(y + dy), (ushort)(z + dz)), Block.train); + lvl.AddUpdate(lvl.PosToInt((ushort)(x + dx), (ushort)(y + dy), (ushort)(z + dz)), Block.train); lvl.AddUpdate(C.b, Block.air); - byte newBlock = tileBelow == Block.op_air ? Block.glass : Block.obsidian; + byte newBlock = below.BlockID == Block.op_air ? Block.glass : Block.obsidian; - tileBelow = lvl.GetTile(x, (ushort)(y - 1), z); + below = lvl.GetBlock(x, (ushort)(y - 1), z); PhysicsArgs args = default(PhysicsArgs); args.Type1 = PhysicsArgs.Wait; args.Value1 = 5; - args.Type2 = PhysicsArgs.Revert; args.Value2 = tileBelow; + args.Type2 = PhysicsArgs.Revert; args.Value2 = below.RawID; + args.ExtBlock = below.BlockID == Block.custom_block; - if (tileBelow == Block.custom_block) { - args.Value2 = lvl.GetExtTile(x, (ushort)(y - 1), z); - args.ExtBlock = true; - } lvl.AddUpdate(lvl.IntOffset(C.b, 0, -1, 0), newBlock, true, args); return; } diff --git a/MCGalaxy/Commands/CPE/CustomBlockCommand.cs b/MCGalaxy/Commands/CPE/CustomBlockCommand.cs index 36d5c825a..b9b103862 100644 --- a/MCGalaxy/Commands/CPE/CustomBlockCommand.cs +++ b/MCGalaxy/Commands/CPE/CustomBlockCommand.cs @@ -115,7 +115,7 @@ namespace MCGalaxy.Commands.CPE { if (src == null) { MessageNoBlock(p, srcId, global, cmd); return; } if (ExistsInScope(dst, dstId, global)) { MessageAlreadyBlock(p, dstId, global, cmd); return; } - BlockProps props = global ? BlockDefinition.GlobalProps[srcId] : p.level.CustomBlockProps[srcId]; + BlockProps props = global ? BlockDefinition.GlobalProps[srcId] : p.level.BlockProps[srcId]; dst = src.Copy(); props.BlockId = (byte)dstId; dst.BlockID = (byte)dstId; @@ -550,14 +550,14 @@ namespace MCGalaxy.Commands.CPE { static void UpdateBlockProps(bool global, Player p, BlockProps props) { byte block = props.BlockId; if (!global) { - p.level.CustomBlockProps[block] = props; + p.level.BlockProps[block] = props; } else { BlockDefinition.GlobalProps[block] = props; Level[] loaded = LevelInfo.Loaded.Items; foreach (Level lvl in loaded) { if (lvl.CustomBlockDefs[block] != null) continue; - lvl.CustomBlockProps[block] = props; + lvl.BlockProps[block] = props; } } } @@ -565,16 +565,16 @@ namespace MCGalaxy.Commands.CPE { static void RemoveBlockProps(bool global, byte id, Player p) { // Level block reverts to using global block if (!global && BlockDefinition.GlobalDefs[id] != null) { - p.level.CustomBlockProps[id] = BlockDefinition.GlobalProps[id]; + p.level.BlockProps[id] = BlockDefinition.GlobalProps[id]; } else if (!global) { - p.level.CustomBlockProps[id] = new BlockProps((byte)id); + p.level.BlockProps[id] = new BlockProps((byte)id); } else { BlockDefinition.GlobalProps[id] = new BlockProps((byte)id); Level[] loaded = LevelInfo.Loaded.Items; foreach (Level lvl in loaded) { if (lvl.CustomBlockDefs[id] != BlockDefinition.GlobalDefs[id]) continue; - lvl.CustomBlockProps[id] = new BlockProps((byte)id); + lvl.BlockProps[id] = new BlockProps((byte)id); } } } diff --git a/MCGalaxy/Commands/Fun/CmdGun.cs b/MCGalaxy/Commands/Fun/CmdGun.cs index b7189d43e..d7d6423eb 100644 --- a/MCGalaxy/Commands/Fun/CmdGun.cs +++ b/MCGalaxy/Commands/Fun/CmdGun.cs @@ -55,8 +55,8 @@ namespace MCGalaxy.Commands.Fun { pos.Y = (ushort)Math.Round(start.Y + (double)(dir.Y * t)); pos.Z = (ushort)Math.Round(start.Z + (double)(dir.Z * t)); - byte by = p.level.GetTile(pos.X, pos.Y, pos.Z); - if (by != Block.air && !allBlocks.Contains(pos) && HandlesHitBlock(p, by, bp.ending, pos, true)) + ExtBlock cur = p.level.GetBlock(pos.X, pos.Y, pos.Z); + if (cur.BlockID != Block.air && !allBlocks.Contains(pos) && HandlesHitBlock(p, cur, bp.ending, pos, true)) break; p.level.Blockchange(pos.X, pos.Y, pos.Z, block); diff --git a/MCGalaxy/Commands/Fun/CmdMissile.cs b/MCGalaxy/Commands/Fun/CmdMissile.cs index 1c5e9f772..e0925677f 100644 --- a/MCGalaxy/Commands/Fun/CmdMissile.cs +++ b/MCGalaxy/Commands/Fun/CmdMissile.cs @@ -95,10 +95,10 @@ namespace MCGalaxy.Commands.Fun { target.Y = (ushort)Math.Round(start.Y + (double)(dir.Y * i)); target.Z = (ushort)Math.Round(start.Z + (double)(dir.Z * i)); - byte tile = p.level.GetTile(target.X, target.Y, target.Z); - if (tile == Block.Invalid) break; + ExtBlock block = p.level.GetBlock(target.X, target.Y, target.Z); + if (block.BlockID == Block.Invalid) break; - if (tile != Block.air && !args.allBlocks.Contains(target) && HandlesHitBlock(p, tile, args.ending, target, false)) + if (block.BlockID != Block.air && !args.allBlocks.Contains(target) && HandlesHitBlock(p, block, args.ending, target, false)) break; Player hit = GetPlayer(p, target, true); @@ -113,8 +113,8 @@ namespace MCGalaxy.Commands.Fun { static bool MoveMissile(MissileArgs args, Vec3U16 pos, Vec3U16 target) { Player p = args.player; - byte tile = p.level.GetTile(pos.X, pos.Y, pos.Z); - if (tile != Block.air && !args.allBlocks.Contains(pos) && HandlesHitBlock(p, tile, args.ending, pos, true)) + ExtBlock block = p.level.GetBlock(pos.X, pos.Y, pos.Z); + if (block.BlockID != Block.air && !args.allBlocks.Contains(pos) && HandlesHitBlock(p, block, args.ending, pos, true)) return false; p.level.Blockchange(pos.X, pos.Y, pos.Z, args.block); diff --git a/MCGalaxy/Commands/Fun/WeaponCmd.cs b/MCGalaxy/Commands/Fun/WeaponCmd.cs index 3cebe8cc2..f75e10d88 100644 --- a/MCGalaxy/Commands/Fun/WeaponCmd.cs +++ b/MCGalaxy/Commands/Fun/WeaponCmd.cs @@ -161,15 +161,16 @@ namespace MCGalaxy.Commands.Fun { } } - protected static bool HandlesHitBlock(Player p, byte type, EndType ending, Vec3U16 pos, bool doExplode) { + protected static bool HandlesHitBlock(Player p, ExtBlock block, EndType ending, Vec3U16 pos, bool doExplode) { if (p.level.physics < 2 || ending == EndType.Teleport || ending == EndType.Normal) return true; if (ending == EndType.Destroy) { - if ((!Block.FireKill(type) && !Block.NeedRestart(type)) && type != Block.glass) { + bool fireKills = block.BlockID != Block.air && p.level.BlockProps[block.Index].LavaKills; + if ((!fireKills && !Block.NeedRestart(block.BlockID)) && block.BlockID != Block.glass) { return true; } } else if (p.level.physics >= 3) { - if (type != Block.glass && doExplode) { + if (block.BlockID != Block.glass && doExplode) { p.level.MakeExplosion(pos.X, pos.Y, pos.Z, 1); return true; } diff --git a/MCGalaxy/Commands/World/CmdBlockProperties.cs b/MCGalaxy/Commands/World/CmdBlockProperties.cs index 06b598c5d..b865b2ca4 100644 --- a/MCGalaxy/Commands/World/CmdBlockProperties.cs +++ b/MCGalaxy/Commands/World/CmdBlockProperties.cs @@ -32,10 +32,10 @@ namespace MCGalaxy.Commands.World { if (args.Length < 3) { Help(p); return; } BlockProps[] scope = GetScope(p, args[0]); - if (scope == null) return; + if (scope == null) return; + ExtBlock block = GetBlock(p, scope, args[1]); + if (block.IsInvalid) return; - byte block = GetBlock(p, scope, args[1]); - if (block == Block.Invalid) return; string prop = args[2].ToLower(); SetProperty(p, scope, block, prop, args); } @@ -50,79 +50,82 @@ namespace MCGalaxy.Commands.World { Player.Message(p, "Cannot use level scope from {0}.", src); return null; } - return p.level.CustomBlockProps; + return p.level.BlockProps; } Player.Message(p, "&cScope must \"core\", \"global\", or \"level\""); return null; } - byte GetBlock(Player p, BlockProps[] scope, string input) { - byte block = 0; + ExtBlock GetBlock(Player p, BlockProps[] scope, string input) { if (scope == Block.Props) { - if (!byte.TryParse(input, out block)) - block = Block.Byte(input); + byte raw; + if (!byte.TryParse(input, out raw)) + raw = Block.Byte(input); - if (Block.Name(block).CaselessEq("unknown")) { + if (Block.Name(raw).CaselessEq("unknown")) { Player.Message(p, "&cThere is no block with id or name \"{0}\"", input); - block = Block.Invalid; + return ExtBlock.Invalid; } + return new ExtBlock(raw, 0); } else if (scope == BlockDefinition.GlobalProps) { - block = BlockDefinition.GetBlock(input, BlockDefinition.GlobalDefs); - if (block == Block.Invalid) + byte raw = BlockDefinition.GetBlock(input, BlockDefinition.GlobalDefs); + if (raw == Block.Invalid) Player.Message(p, "&cThere is no global custom block with id or name \"{0}\"", input); + return ExtBlock.FromRaw(raw); } else { - block = BlockDefinition.GetBlock(input, p.level.CustomBlockDefs); - if (block == Block.Invalid) + byte raw = BlockDefinition.GetBlock(input, p.level.CustomBlockDefs); + if (raw == Block.Invalid) Player.Message(p, "&cThere is no level custom block with id or name \"{0}\"", input); - if (p.level.CustomBlockDefs[block] == BlockDefinition.GlobalDefs[block]) { - Player.Message(p, "&cUse %T/blockprops global &cto modify this custom block."); return Block.Invalid; + + if (p.level.CustomBlockDefs[raw] == BlockDefinition.GlobalDefs[raw]) { + Player.Message(p, "&cUse %T/blockprops global &cto modify this custom block."); return ExtBlock.Invalid; } + return ExtBlock.FromRaw(raw); } - return block; } - void SetProperty(Player p, BlockProps[] scope, byte id, + void SetProperty(Player p, BlockProps[] scope, ExtBlock block, string prop, string[] args) { if (prop == "portal") { - Toggle(p, scope, id, "a portal", + Toggle(p, scope, block, "a portal", (ref BlockProps props) => props.IsPortal = !props.IsPortal, (BlockProps props) => props.IsPortal); } else if (prop == "mb" || prop == "messageblock") { - Toggle(p, scope, id, "a message block", + Toggle(p, scope, block, "a message block", (ref BlockProps props) => props.IsMessageBlock = !props.IsMessageBlock, (BlockProps props) => props.IsMessageBlock); } else if (prop == "rails") { - Toggle(p, scope, id, "train rails", + Toggle(p, scope, block, "train rails", (ref BlockProps props) => props.IsRails = !props.IsRails, (BlockProps props) => props.IsRails); } else if (prop == "waterkills") { - Toggle(p, scope, id, "killed by water", + Toggle(p, scope, block, "killed by water", (ref BlockProps props) => props.WaterKills = !props.WaterKills, (BlockProps props) => props.WaterKills); } else if (prop == "lavakills") { - Toggle(p, scope, id, "killed by lava", + Toggle(p, scope, block, "killed by lava", (ref BlockProps props) => props.LavaKills = !props.LavaKills, (BlockProps props) => props.LavaKills); } else if (prop == "door") { - Toggle(p, scope, id, "a door", + Toggle(p, scope, block, "a door", (ref BlockProps props) => props.IsDoor = !props.IsDoor, (BlockProps props) => props.IsDoor); } else if (prop == "tdoor") { - Toggle(p, scope, id, "a tdoor", + Toggle(p, scope, block, "a tdoor", (ref BlockProps props) => props.IsTDoor = !props.IsTDoor, (BlockProps props) => props.IsTDoor); } else if (prop == "killer" || prop == "death") { - Toggle(p, scope, id, "a killer block", + Toggle(p, scope, block, "a killer block", (ref BlockProps props) => props.KillerBlock = !props.KillerBlock, (BlockProps props) => props.KillerBlock); } else if (prop == "deathmsg" || prop == "deathmessage") { string msg = args.Length > 3 ? args[3] : null; - SetDeathMessage(p, scope, id, msg); + SetDeathMessage(p, scope, block, msg); } else if (prop == "animalai" || prop == "animal") { string msg = args.Length > 3 ? args[3] : null; - SetEnum(p, scope, id, msg); + SetEnum(p, scope, block, msg); } else { Help(p); } @@ -130,73 +133,82 @@ namespace MCGalaxy.Commands.World { delegate void BoolSetter(ref BlockProps props); - static void Toggle(Player p, BlockProps[] scope, byte id, string type, + static void Toggle(Player p, BlockProps[] scope, ExtBlock block, string type, BoolSetter setter, Func getter) { - BlockProps props = scope[id]; + BlockProps props = scope[block.Index]; setter(ref props); - scope[id] = props; + scope[block.Index] = props; Level lvl = Player.IsSuper(p) ? null : p.level; Player.Message(p, "Block {0} is {1}: {2}", - BlockName(scope, lvl, id), + BlockName(scope, lvl, block), type, getter(props) ? "&aYes" : "&cNo"); - OnPropsChanged(scope, lvl, id, false); + OnPropsChanged(scope, lvl, block, false); } - static void SetEnum(Player p, BlockProps[] scope, byte id, string msg) { + static void SetEnum(Player p, BlockProps[] scope, ExtBlock block, string msg) { Level lvl = Player.IsSuper(p) ? null : p.level; AnimalAI ai = AnimalAI.None; if (!CommandParser.GetEnum(p, msg, "Animal AI", ref ai)) return; - scope[id].AnimalAI = ai; + scope[block.Index].AnimalAI = ai; Player.Message(p, "Animal AI for {0} set to: {1}", - BlockName(scope, lvl, id), ai); - OnPropsChanged(scope, lvl, id, true); + BlockName(scope, lvl, block), ai); + OnPropsChanged(scope, lvl, block, true); } - static void SetDeathMessage(Player p, BlockProps[] scope, byte id, string msg) { - scope[id].DeathMessage = msg; + static void SetDeathMessage(Player p, BlockProps[] scope, ExtBlock block, string msg) { + scope[block.Index].DeathMessage = msg; Level lvl = Player.IsSuper(p) ? null : p.level; if (msg == null) { Player.Message(p, "Death message for {0} removed.", - BlockName(scope, lvl, id)); + BlockName(scope, lvl, block)); } else { Player.Message(p, "Death message for {0} set to: {1}", - BlockName(scope, lvl, id), msg); + BlockName(scope, lvl, block), msg); } - OnPropsChanged(scope, lvl, id, false); + OnPropsChanged(scope, lvl, block, false); } - static void OnPropsChanged(BlockProps[] scope, Level level, byte id, bool physics) { - scope[id].Changed = true; + static void OnPropsChanged(BlockProps[] scope, Level level, ExtBlock block, bool physics) { + scope[block.Index].Changed = true; if (scope == Block.Props) { - BlockBehaviour.SetDefaultHandler(id); - BlockProps.Save("core", scope); + BlockProps.Save("core", scope); + Level[] loaded = LevelInfo.Loaded.Items; + + foreach (Level lvl in loaded) { + lvl.SetBlockHandler(block); + lvl.BlockProps[block.Index] = BlockDefinition.GlobalProps[block.Index]; + } } else if (scope == BlockDefinition.GlobalProps) { Level[] loaded = LevelInfo.Loaded.Items; - foreach (Level lvl in loaded) { - if (lvl.CustomBlockDefs[id] != BlockDefinition.GlobalDefs[id]) continue; - lvl.CustomBlockProps[id] = BlockDefinition.GlobalProps[id]; - } BlockProps.Save("global", scope); + + byte raw = block.RawID; + foreach (Level lvl in loaded) { + if (lvl.CustomBlockDefs[raw] != BlockDefinition.GlobalDefs[raw]) continue; + lvl.BlockProps[block.Index] = BlockDefinition.GlobalProps[block.Index]; + lvl.SetBlockHandler(block); + } } else { BlockProps.Save("lvl_" + level.name, scope); + level.SetBlockHandler(block); } } - static string BlockName(BlockProps[] scope, Level lvl, byte raw) { - if (scope == Block.Props) return Block.Name(raw); + static string BlockName(BlockProps[] scope, Level lvl, ExtBlock block) { + if (scope == Block.Props) return Block.Name(block.RawID); BlockDefinition def = null; if (scope == BlockDefinition.GlobalProps) { - def = BlockDefinition.GlobalDefs[raw]; + def = BlockDefinition.GlobalDefs[block.RawID]; } else { - def = lvl.CustomBlockDefs[raw]; + def = lvl.CustomBlockDefs[block.RawID]; } - return def == null ? raw.ToString() : def.Name.Replace(" ", ""); + return def == null ? block.RawID.ToString() : def.Name.Replace(" ", ""); } diff --git a/MCGalaxy/Commands/building/CmdMark.cs b/MCGalaxy/Commands/building/CmdMark.cs index af17a3562..e1d4715d2 100644 --- a/MCGalaxy/Commands/building/CmdMark.cs +++ b/MCGalaxy/Commands/building/CmdMark.cs @@ -55,7 +55,7 @@ namespace MCGalaxy.Commands.Building { ExtBlock old = p.level.GetBlock(P.X, P.Y, P.Z); if (!p.CheckManualChange(old, ExtBlock.Air, false)) return; - HandleDelete handler = BlockBehaviour.deleteHandlers[old.BlockID]; + HandleDelete handler = p.level.deleteHandlers[old.Index]; if (handler != null) { handler(p, old, P.X, P.Y, P.Z); } else { diff --git a/MCGalaxy/Commands/building/CmdMessageBlock.cs b/MCGalaxy/Commands/building/CmdMessageBlock.cs index 1727725d0..4fa6af7dd 100644 --- a/MCGalaxy/Commands/building/CmdMessageBlock.cs +++ b/MCGalaxy/Commands/building/CmdMessageBlock.cs @@ -70,7 +70,7 @@ namespace MCGalaxy.Commands.Building { if (name == "show") { ShowMessageBlocks(p); return ExtBlock.Invalid; } block = BlockDefinition.GetBlock(name, p); - if (p.level.CustomBlockProps[block].IsMessageBlock) + if (p.level.BlockProps[block].IsMessageBlock) return ExtBlock.FromRaw(block); // Hardcoded aliases for backwards compatibility @@ -214,7 +214,7 @@ namespace MCGalaxy.Commands.Building { string blocks = Block.Props.Join(props => Format(props)); if (!Player.IsSuper(p)) { - string custom = p.level.CustomBlockProps.Join(props => FormatCustom(p.level, props)); + string custom = p.level.BlockProps.Join(props => FormatCustom(p.level, props)); if (blocks != "" && custom != "") blocks = blocks + ", " + custom; } diff --git a/MCGalaxy/Commands/building/CmdPortal.cs b/MCGalaxy/Commands/building/CmdPortal.cs index be3e938c6..a064f30ac 100644 --- a/MCGalaxy/Commands/building/CmdPortal.cs +++ b/MCGalaxy/Commands/building/CmdPortal.cs @@ -60,7 +60,7 @@ namespace MCGalaxy.Commands.Building { if (name == "show") { ShowPortals(p); return ExtBlock.Invalid; } block = BlockDefinition.GetBlock(name, p); - if (p.level.CustomBlockProps[block].IsPortal) + if (p.level.BlockProps[block].IsPortal) return ExtBlock.FromRaw(block); // Hardcoded aliases for backwards compatibility @@ -218,7 +218,7 @@ namespace MCGalaxy.Commands.Building { string blocks = Block.Props.Join(props => Format(props)); if (!Player.IsSuper(p)) { - string custom = p.level.CustomBlockProps.Join(props => FormatCustom(p.level, props)); + string custom = p.level.BlockProps.Join(props => FormatCustom(p.level, props)); if (blocks != "" && custom != "") blocks = blocks + ", " + custom; } diff --git a/MCGalaxy/CorePlugin/MiscHandlers.cs b/MCGalaxy/CorePlugin/MiscHandlers.cs index 5580558fd..c54ef2a7a 100644 --- a/MCGalaxy/CorePlugin/MiscHandlers.cs +++ b/MCGalaxy/CorePlugin/MiscHandlers.cs @@ -93,16 +93,10 @@ namespace MCGalaxy.Core { byte entity, ushort x, ushort y, ushort z, TargetBlockFace face) { if (p.level.Deletable || action != MouseAction.Pressed || !p.level.IsValidPos(x, y, z)) return; - byte block = p.level.GetTile(x, y, z); - bool isMB = Block.Props[block].IsMessageBlock; - bool isPortal = Block.Props[block].IsPortal; - - if (block == Block.custom_block) { - block = p.level.GetExtTile(x, y, z); - isMB = p.level.CustomBlockProps[block].IsMessageBlock; - isPortal = p.level.CustomBlockProps[block].IsMessageBlock; - } - + ExtBlock block = p.level.GetBlock(x, y, z); + bool isMB = p.level.BlockProps[block.Index].IsMessageBlock; + bool isPortal = p.level.BlockProps[block.Index].IsPortal; + if (isMB) { MessageBlock.Handle(p, x, y, z, true); } if (isPortal) { Portal.Handle(p, x, y, z); } } diff --git a/MCGalaxy/Database/BlockDB/BlockDBChange.cs b/MCGalaxy/Database/BlockDB/BlockDBChange.cs index 9cbaabe2d..abc29c71c 100644 --- a/MCGalaxy/Database/BlockDB/BlockDBChange.cs +++ b/MCGalaxy/Database/BlockDB/BlockDBChange.cs @@ -47,11 +47,7 @@ namespace MCGalaxy.DB { public static void OutputMessageBlock(Player p, ExtBlock block, ushort x, ushort y, ushort z) { - if (block.BlockID == Block.custom_block) { - if (!p.level.CustomBlockProps[block.ExtID].IsMessageBlock) return; - } else { - if (!Block.Props[block.BlockID].IsMessageBlock) return; - } + if (!p.level.BlockProps[block.Index].IsMessageBlock) return; try { if (!Database.Backend.TableExists("Messages" + p.level.name)) return; @@ -69,11 +65,7 @@ namespace MCGalaxy.DB { public static void OutputPortal(Player p, ExtBlock block, ushort x, ushort y, ushort z) { - if (block.BlockID == Block.custom_block) { - if (!p.level.CustomBlockProps[block.ExtID].IsPortal) return; - } else { - if (!Block.Props[block.BlockID].IsPortal) return; - } + if (!p.level.BlockProps[block.Index].IsPortal) return; try { if (!Database.Backend.TableExists("Portals" + p.level.name)) return; diff --git a/MCGalaxy/Games/CTF/CtfTeam.cs b/MCGalaxy/Games/CTF/CtfTeam.cs index e73e5f272..4625dfefa 100644 --- a/MCGalaxy/Games/CTF/CtfTeam.cs +++ b/MCGalaxy/Games/CTF/CtfTeam.cs @@ -129,10 +129,10 @@ namespace MCGalaxy.Games if (mapOn.GetBlock(x, y, z) != (ExtBlock)Block.flagbase) { mapOn.Blockchange(x, y, z, (ExtBlock)Block.flagbase); } - if (mapOn.GetBlock(x, y + 1, z) != (ExtBlock)Block.mushroom) { + if (mapOn.GetBlock(x, (ushort)(y + 1), z) != (ExtBlock)Block.mushroom) { mapOn.Blockchange(x, (ushort)(y + 1), z, (ExtBlock)Block.mushroom); } - if (mapOn.GetBlock(x, y + 2, z) != (ExtBlock)GetColorBlock(color)) { + if (mapOn.GetBlock(x, (ushort)(y + 2), z) != (ExtBlock)GetColorBlock(color)) { mapOn.Blockchange(x, (ushort)(y + 2), z, (ExtBlock)GetColorBlock(color)); } diff --git a/MCGalaxy/Levels/Level.Blocks.cs b/MCGalaxy/Levels/Level.Blocks.cs index 968c95e7d..2621a7144 100644 --- a/MCGalaxy/Levels/Level.Blocks.cs +++ b/MCGalaxy/Levels/Level.Blocks.cs @@ -54,8 +54,19 @@ namespace MCGalaxy { ExtBlock block; block.BlockID = blocks[x + Width * (z + y * Length)]; - block.ExtID = block.BlockID == Block.custom_block - ? GetExtTileNoCheck(x, y, z) : Block.air; + 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(ushort x, ushort y, ushort z, out int index) { + if (x >= Width || y >= Height || z >= Length || blocks == null) { index = -1; return ExtBlock.Invalid; } + ExtBlock block; + + index = x + Width * (z + y * Length); + block.BlockID = blocks[index]; + block.ExtID = block.BlockID == Block.custom_block ? GetExtTileNoCheck(x, y, z) : Block.air; return block; } @@ -354,9 +365,10 @@ namespace MCGalaxy { try { - if (!overRide) - if (Block.Props[old.BlockID].OPBlock || (Block.Props[block.BlockID].OPBlock && data.Raw != 0)) + if (!overRide) { + if (BlockProps[old.Index].OPBlock || (BlockProps[block.Index].OPBlock && data.Raw != 0)) return false; + } if (old.BlockID == Block.sponge && physics > 0 && block.BlockID != Block.sponge) OtherPhysics.DoSpongeRemoved(this, b, false); diff --git a/MCGalaxy/Levels/Level.Fields.cs b/MCGalaxy/Levels/Level.Fields.cs index da2dee748..cef9ac5bd 100644 --- a/MCGalaxy/Levels/Level.Fields.cs +++ b/MCGalaxy/Levels/Level.Fields.cs @@ -49,9 +49,15 @@ namespace MCGalaxy { public Orientation SpawnRot { get { return new Orientation(rotx, roty); } } public BlockDefinition[] CustomBlockDefs; - public BlockProps[] CustomBlockProps; + public BlockProps[] BlockProps; public ExtrasCollection Extras = new ExtrasCollection(); + internal HandleDelete[] deleteHandlers = new HandleDelete[Block.Count * 2]; + internal HandlePlace[] placeHandlers = new HandlePlace[Block.Count * 2]; + internal HandleWalkthrough[] walkthroughHandlers = new HandleWalkthrough[Block.Count * 2]; + internal HandlePhysics[] physicsHandlers = new HandlePhysics[Block.Count * 2]; + internal HandlePhysics[] physicsDoorsHandlers = new HandlePhysics[Block.Count * 2]; + public ushort Width, Height, Length; // NOTE: These are for legacy code only, you should use upper case Width/Height/Length // as these correctly map Y to being Height diff --git a/MCGalaxy/Levels/Level.Physics.cs b/MCGalaxy/Levels/Level.Physics.cs index a4157eb9f..c7719f460 100644 --- a/MCGalaxy/Levels/Level.Physics.cs +++ b/MCGalaxy/Levels/Level.Physics.cs @@ -137,10 +137,10 @@ namespace MCGalaxy { lastCheck = ListCheck.Count; const uint mask = PhysicsArgs.TypeMask; - HandlePhysics[] handlers = BlockBehaviour.physicsHandlers; + HandlePhysics[] handlers = physicsHandlers; ExtraInfoHandler extraHandler = ExtraInfoPhysics.DoNormal; if (physics == 5) { - handlers = BlockBehaviour.physicsDoorsHandlers; + handlers = physicsDoorsHandlers; extraHandler = ExtraInfoPhysics.DoDoorsOnly; } @@ -350,11 +350,10 @@ namespace MCGalaxy { if (block.BlockID != Block.custom_block) return Block.Physics(block.BlockID); - BlockProps[] props = CustomBlockProps; - byte extBlock = block.ExtID; - if (props[extBlock].IsMessageBlock || props[extBlock].IsPortal) return false; - if (props[extBlock].IsDoor || props[extBlock].IsTDoor) return false; - if (props[extBlock].OPBlock) return false; + int i = block.Index; + if (BlockProps[i].IsMessageBlock || BlockProps[i].IsPortal) return false; + if (BlockProps[i].IsDoor || BlockProps[i].IsTDoor) return false; + if (BlockProps[i].OPBlock) return false; return true; } diff --git a/MCGalaxy/Levels/Level.cs b/MCGalaxy/Levels/Level.cs index d2ae50ef4..f2848c86c 100644 --- a/MCGalaxy/Levels/Level.cs +++ b/MCGalaxy/Levels/Level.cs @@ -72,9 +72,9 @@ namespace MCGalaxy { CustomBlockDefs = new BlockDefinition[256]; for (int i = 0; i < CustomBlockDefs.Length; i++) CustomBlockDefs[i] = BlockDefinition.GlobalDefs[i]; - CustomBlockProps = new BlockProps[256]; - for (int i = 0; i < CustomBlockProps.Length; i++) - CustomBlockProps[i] = BlockDefinition.GlobalProps[i]; + BlockProps = new BlockProps[256]; + for (int i = 0; i < BlockProps.Length; i++) + BlockProps[i] = BlockDefinition.GlobalProps[i]; name = n; MapName = n.ToLower(); BlockDB = new BlockDB(this); @@ -91,6 +91,7 @@ namespace MCGalaxy { spawny = (ushort)(Height * 0.75f); spawnz = (ushort)(Length / 2); rotx = 0; roty = 0; + SetBlockHandlers(); ZoneList = new List(); VisitAccess = new LevelAccessController(this, true); @@ -401,9 +402,9 @@ namespace MCGalaxy { for (int i = 0; i < defs.Length; i++) { if (defs[i] == null) continue; lvl.CustomBlockDefs[i] = defs[i]; - lvl.CustomBlockProps[i] = new BlockProps((byte)i); + lvl.BlockProps[i] = new BlockProps((byte)i); } - BlockProps.Load("lvl_" + lvl.MapName, lvl.CustomBlockProps); + MCGalaxy.Blocks.BlockProps.Load("lvl_" + lvl.MapName, lvl.BlockProps); } public static bool CheckLoadOnGoto(string givenName) { @@ -499,5 +500,31 @@ namespace MCGalaxy { public ushort bigX, bigY, bigZ; public ushort smallX, smallY, smallZ; } + + public void SetBlockHandlers() { + for (int i = 0; i < Block.Count; i++) { + SetBlockHandler(new ExtBlock((byte)i, 0)); + SetBlockHandler(new ExtBlock(Block.custom_block, (byte)i)); + } + } + + public void SetBlockHandler(ExtBlock block) { + bool notCustom = !block.IsCustomType && + (block.BlockID >= Block.CpeCount || CustomBlockDefs[block.BlockID] == null); + + bool nonSolid; + if (notCustom) { + nonSolid = Block.Walkthrough(Block.Convert(block.BlockID)); + } else { + nonSolid = CustomBlockDefs[block.BlockID].CollideType != CollideType.Solid; + } + + int i = block.Index; + deleteHandlers[i] = BlockBehaviour.GetDeleteHandler(block, BlockProps); + placeHandlers[i] = BlockBehaviour.GetPlaceHandler(block, BlockProps); + walkthroughHandlers[i] = BlockBehaviour.GetWalkthroughHandler(block, BlockProps, nonSolid); + physicsHandlers[i] = BlockBehaviour.GetPhysicsHandler(block, BlockProps); + physicsDoorsHandlers[i] = BlockBehaviour.GetPhysicsDoorsHandler(block, BlockProps); + } } } \ No newline at end of file diff --git a/MCGalaxy/Levels/LevelDB.cs b/MCGalaxy/Levels/LevelDB.cs index c6782ffa4..be7d0ed62 100644 --- a/MCGalaxy/Levels/LevelDB.cs +++ b/MCGalaxy/Levels/LevelDB.cs @@ -65,13 +65,8 @@ namespace MCGalaxy { ushort y = ushort.Parse(row["EntryY"].ToString()); ushort z = ushort.Parse(row["EntryZ"].ToString()); - byte block = level.GetTile(x, y, z); - if (block == Block.custom_block) { - block = level.GetExtTile(x, y, z); - if (level.CustomBlockProps[block].IsPortal) continue; - } else { - if (Block.Props[block].IsPortal) continue; - } + ExtBlock block = level.GetBlock(x, y, z); + if (level.BlockProps[block.Index].IsPortal) continue; Database.Backend.DeleteRows("Portals" + name, "WHERE EntryX=@0 AND EntryY=@1 AND EntryZ=@2", x, y, z); } @@ -88,13 +83,8 @@ namespace MCGalaxy { ushort y = ushort.Parse(row["Y"].ToString()); ushort z = ushort.Parse(row["Z"].ToString()); - byte block = level.GetTile(x, y, z); - if (block == Block.custom_block) { - block = level.GetExtTile(x, y, z); - if (level.CustomBlockProps[block].IsMessageBlock) continue; - } else { - if (Block.Props[block].IsMessageBlock) continue; - } + ExtBlock block = level.GetBlock(x, y, z); + if (level.BlockProps[block.Index].IsMessageBlock) continue; Database.Backend.DeleteRows("Messages" + name, "WHERE X=@0 AND Y=@1 AND Z=@2", x, y, z); } diff --git a/MCGalaxy/Player/Player.Handlers.cs b/MCGalaxy/Player/Player.Handlers.cs index 3391860b4..ae86983e8 100644 --- a/MCGalaxy/Player/Player.Handlers.cs +++ b/MCGalaxy/Player/Player.Handlers.cs @@ -142,7 +142,7 @@ namespace MCGalaxy { bool DeleteBlock(ExtBlock old, ushort x, ushort y, ushort z, ExtBlock block) { if (deleteMode) { return ChangeBlock(x, y, z, ExtBlock.Air) == 2; } - HandleDelete handler = BlockBehaviour.deleteHandlers[old.BlockID]; + HandleDelete handler = level.deleteHandlers[old.Index]; if (handler != null) { handler(this, old, x, y, z); return true; @@ -151,7 +151,7 @@ namespace MCGalaxy { } bool PlaceBlock(ExtBlock old, ushort x, ushort y, ushort z, ExtBlock block) { - HandlePlace handler = BlockBehaviour.placeHandlers[block.BlockID]; + HandlePlace handler = level.placeHandlers[block.Index]; if (handler != null) { handler(this, old, x, y, z); return true; @@ -426,7 +426,7 @@ namespace MCGalaxy { // We can activate only one walkthrough block per movement if (!hitWalkthrough) { - HandleWalkthrough handler = BlockBehaviour.walkthroughHandlers[block.BlockID]; + HandleWalkthrough handler = level.walkthroughHandlers[block.Index]; if (handler != null && handler(this, block, xP, yP, zP)) { lastWalkthrough = level.PosToInt(xP, yP, zP); hitWalkthrough = true; @@ -434,12 +434,9 @@ namespace MCGalaxy { } // Some blocks will cause death of players - byte coreID = block.BlockID; - if (coreID != Block.custom_block && !Block.Props[coreID].KillerBlock) continue; - if (coreID == Block.custom_block && !level.CustomBlockProps[block.ExtID].KillerBlock) continue; - - if (coreID == Block.tntexplosion && PlayingTntWars) continue; // TODO: hardcoded behaviour is icky - if (coreID == Block.train && trainInvincible) continue; + if (!level.BlockProps[block.Index].KillerBlock) continue; + if (block.BlockID == Block.tntexplosion && PlayingTntWars) continue; // TODO: hardcoded behaviour is icky + if (block.BlockID == Block.train && trainInvincible) continue; HandleDeath(block); } @@ -463,12 +460,7 @@ namespace MCGalaxy { onTrain = false; trainInvincible = false; trainGrab = false; ushort x = (ushort)Pos.BlockX, y = (ushort)Pos.BlockY, z = (ushort)Pos.BlockZ; - string deathMsg = null; - if (block.BlockID != Block.custom_block) { - deathMsg = Block.Props[block.BlockID].DeathMessage; - } else { - deathMsg = level.CustomBlockProps[block.ExtID].DeathMessage; - } + string deathMsg = level.BlockProps[block.Index].DeathMessage; if (deathMsg != null) { Chat.MessageLevel(this, deathMsg.Replace("@p", ColoredName), false, level); }