diff --git a/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs b/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs index 51dc50ad8..177ac8128 100644 --- a/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs +++ b/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs @@ -66,7 +66,7 @@ namespace MCGalaxy.Blocks { if (props[i].IsPortal) return DeleteBehaviour.DoPortal; if (props[i].IsTDoor) return DeleteBehaviour.RevertDoor; - if (props[i].oDoorId != Block.Invalid) return DeleteBehaviour.ODoor; + if (props[i].oDoorIndex != Block.Invalid) return DeleteBehaviour.oDoor; if (props[i].IsDoor) return DeleteBehaviour.Door; return null; } @@ -157,7 +157,7 @@ namespace MCGalaxy.Blocks { int i = block.Index; HandlePhysics animalAI = AnimalAIHandler(props[i].AnimalAI); if (animalAI != null) return animalAI; - if (props[i].oDoorId != Block.Invalid) return DoorPhysics.oDoor; + if (props[i].oDoorIndex != Block.Invalid) return DoorPhysics.oDoor; i = block.BlockID; // TODO: should this be checking WaterKills/LavaKills // Adv physics updating anything placed next to water or lava @@ -169,7 +169,7 @@ namespace MCGalaxy.Blocks { /// Retrieves the default physics block handler for the given block. internal static HandlePhysics GetPhysicsDoorsHandler(ExtBlock block, BlockProps[] props) { - if (props[block.Index].oDoorId != Block.Invalid) return DoorPhysics.oDoor; + if (props[block.Index].oDoorIndex != Block.Invalid) return DoorPhysics.oDoor; return null; } diff --git a/MCGalaxy/Blocks/Behaviour/DeleteBehaviour.cs b/MCGalaxy/Blocks/Behaviour/DeleteBehaviour.cs index 09fdcd334..7374ce069 100644 --- a/MCGalaxy/Blocks/Behaviour/DeleteBehaviour.cs +++ b/MCGalaxy/Blocks/Behaviour/DeleteBehaviour.cs @@ -89,9 +89,10 @@ namespace MCGalaxy.Blocks { } } - internal static void ODoor(Player p, ExtBlock block, ushort x, ushort y, ushort z) { + internal static void oDoor(Player p, ExtBlock block, ushort x, ushort y, ushort z) { if (block.BlockID == Block.oDoor_Green || block.BlockID == Block.oDoor_Green_air) { - p.level.Blockchange(x, y, z, (ExtBlock)p.level.BlockProps[block.Index].oDoorId); + ushort oDoorOpposite = p.level.BlockProps[block.Index].oDoorIndex; + p.level.Blockchange(x, y, z, ExtBlock.FromIndex(oDoorOpposite)); } else { p.RevertBlock(x, y, z); } diff --git a/MCGalaxy/Blocks/Block.CoreProps.cs b/MCGalaxy/Blocks/Block.CoreProps.cs index c44349d31..53941b3e8 100644 --- a/MCGalaxy/Blocks/Block.CoreProps.cs +++ b/MCGalaxy/Blocks/Block.CoreProps.cs @@ -30,42 +30,46 @@ namespace MCGalaxy { for (int i = 0; i < Block.Count; i++) Props[i] = BlockProps.MakeDefault(); for (int i = 0; i < Block.Count; i++) { - if ((i >= Op_Glass && i <= Op_Lava) || i == Invalid || i == RocketStart || i == Bedrock) + if ((i >= Op_Glass && i <= Op_Lava) || i == Invalid || i == RocketStart || i == Bedrock) { Props[i].OPBlock = true; + } - if ((i >= tDoor_Log && i <= tDoor_Green) || (i >= tDoor_TNT && i <= tDoor_Lava)) + if ((i >= tDoor_Log && i <= tDoor_Green) || (i >= tDoor_TNT && i <= tDoor_Lava)) { Props[i].IsTDoor = true; - - if (i >= MB_White && i <= MB_Lava) + } + if (i >= MB_White && i <= MB_Lava) { Props[i].IsMessageBlock = true; - - if (i == Portal_Blue || i == Portal_Orange || (i >= Portal_Air && i <= Portal_Lava)) + } + if (i == Portal_Blue || i == Portal_Orange || (i >= Portal_Air && i <= Portal_Lava)) { Props[i].IsPortal = true; + } - // ODoor blocks - if (i >= oDoor_Log && i <= oDoor_Wood) - Props[i].oDoorId = (byte)(oDoor_Log_air + (i - oDoor_Log)); - if (i >= oDoor_Green && i <= oDoor_Water) - Props[i].oDoorId = (byte)(oDoor_Green_air + (i - oDoor_Green)); - if (i >= oDoor_Log_air && i <= oDoor_Wood_air) - Props[i].oDoorId = (byte)(oDoor_Log + (i - oDoor_Log_air)); - if (i >= oDoor_Green_air && i <= oDoor_Water_air) - Props[i].oDoorId = (byte)(oDoor_Green + (i - oDoor_Green_air)); + // oDoor blocks + if (i >= oDoor_Log && i <= oDoor_Wood) { + Props[i].oDoorIndex = (byte)(oDoor_Log_air + (i - oDoor_Log)); + } + if (i >= oDoor_Green && i <= oDoor_Water) { + Props[i].oDoorIndex = (byte)(oDoor_Green_air + (i - oDoor_Green)); + } + if (i >= oDoor_Log_air && i <= oDoor_Wood_air) { + Props[i].oDoorIndex = (byte)(oDoor_Log + (i - oDoor_Log_air)); + } + if (i >= oDoor_Green_air && i <= oDoor_Water_air) { + Props[i].oDoorIndex = (byte)(oDoor_Green + (i - oDoor_Green_air)); + } - if ((i >= Red && i <= White) || (i >= LightPink && i <= turquoise)) + if ((i >= Red && i <= White) || (i >= LightPink && i <= turquoise)) { Props[i].LavaKills = true; + } if (i == Air || i == Sapling || (i >= Dandelion && i <= RedMushroom)) { Props[i].LavaKills = true; Props[i].WaterKills = true; } // Door blocks - if (i >= Door_Obsidian && i <= Door_Slab) - Props[i].IsDoor = true; - if (i >= Door_Iron && i <= Door_Bookshelf) - Props[i].IsDoor = true; - if (i >= Door_Orange && i <= Door_White) - Props[i].IsDoor = true; + if (i >= Door_Obsidian && i <= Door_Slab) Props[i].IsDoor = true; + if (i >= Door_Iron && i <= Door_Bookshelf) Props[i].IsDoor = true; + if (i >= Door_Orange && i <= Door_White) Props[i].IsDoor = true; } // Other door blocks, since they aren't in a consistent order @@ -137,7 +141,7 @@ namespace MCGalaxy { "oDoor_Stone", "oDoor_Leaves", "oDoor_Sand", "oDoor_Wood", "oDoor_Green", "oDoor_TNT", "oDoor_Stair", "oDoor_Lava", "oDoor_Water", "Air_Portal", "Water_Portal", "Lava_Portal", "Custom_Block", "Air_Door", "Air_Switch", "Door_Water", "Door_Lava", - "oDoor_Wood_Air", "oDoor_Obsidian_Air", "oDoor_Glass_Air", "oDoor_Stone_Air", + "oDoor_Air", "oDoor_Obsidian_Air", "oDoor_Glass_Air", "oDoor_Stone_Air", "oDoor_Leaves_Air", "oDoor_Sand_Air", "oDoor_Wood_Air", "Blue_Portal", "Orange_Portal", "oDoor_Red", "oDoor_TNT_Air", "oDoor_Stair_Air", "oDoor_Lava_Air", "oDoor_Water_Air", "Small_TNT", "Big_TNT", "TNT_Explosion", "Lava_Fire", "Nuke_TNT", "RocketStart", diff --git a/MCGalaxy/Blocks/BlockPerms.cs b/MCGalaxy/Blocks/BlockPerms.cs index dbba06573..ab1e3dc60 100644 --- a/MCGalaxy/Blocks/BlockPerms.cs +++ b/MCGalaxy/Blocks/BlockPerms.cs @@ -200,7 +200,7 @@ namespace MCGalaxy.Blocks { perms.MinRank = LevelPermission.Admin; } else if (props.OPBlock) { perms.MinRank = LevelPermission.Operator; - } else if (props.IsDoor || props.IsTDoor || props.oDoorId != Block.Invalid) { + } else if (props.IsDoor || props.IsTDoor || props.oDoorIndex != Block.Invalid) { perms.MinRank = LevelPermission.Builder; } else if (props.IsPortal || props.IsMessageBlock) { perms.MinRank = LevelPermission.AdvBuilder; diff --git a/MCGalaxy/Blocks/BlockProperties.cs b/MCGalaxy/Blocks/BlockProperties.cs index 644d483f6..8fbd459c1 100644 --- a/MCGalaxy/Blocks/BlockProperties.cs +++ b/MCGalaxy/Blocks/BlockProperties.cs @@ -36,10 +36,10 @@ namespace MCGalaxy.Blocks { /// Whether this block is considered a tDoor. public bool IsTDoor; - /// Block id this block is converted to when toggled by a neighbouring door. - public byte oDoorId; /// Whether this block is considered a door. public bool IsDoor; + /// Block index of the block this is converted to when toggled by a neighbouring door. + public ushort oDoorIndex; /// Whether this block is considered a message block. public bool IsMessageBlock; @@ -68,7 +68,7 @@ namespace MCGalaxy.Blocks { public static BlockProps MakeDefault() { BlockProps props = default(BlockProps); - props.oDoorId = Block.Invalid; + props.oDoorIndex = Block.Invalid; return props; } @@ -92,7 +92,7 @@ namespace MCGalaxy.Blocks { w.WriteLine(id + ":" + props.IsRails + ":" + props.IsTDoor + ":" + props.IsDoor + ":" + props.IsMessageBlock + ":" + props.IsPortal + ":" + props.WaterKills + ":" + props.LavaKills + ":" + props.KillerBlock + ":" + deathMsg + ":" - + (byte)props.AnimalAI + ":" + props.StackId + ":" + props.OPBlock); + + (byte)props.AnimalAI + ":" + props.StackId + ":" + props.OPBlock + ":" + props.oDoorIndex); } } } @@ -145,6 +145,10 @@ namespace MCGalaxy.Blocks { 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; + } } } } diff --git a/MCGalaxy/Blocks/Physics/ActivateablePhysics.cs b/MCGalaxy/Blocks/Physics/ActivateablePhysics.cs index fede9e1ee..ad260481e 100644 --- a/MCGalaxy/Blocks/Physics/ActivateablePhysics.cs +++ b/MCGalaxy/Blocks/Physics/ActivateablePhysics.cs @@ -66,16 +66,20 @@ namespace MCGalaxy.Blocks.Physics { int i = block.Index; if (lvl.BlockProps[i].IsDoor) { byte physForm; - PhysicsArgs args = GetDoorArgs(block, 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 (lvl.BlockProps[i].IsTDoor) { PhysicsArgs args = GetTDoorArgs(block); lvl.AddUpdate(index, Block.Air, false, args); } else { - byte oDoor = lvl.BlockProps[i].oDoorId; - if (oDoor != Block.Invalid) - lvl.AddUpdate(index, oDoor, true); + ushort oDoorIndex = lvl.BlockProps[i].oDoorIndex; + if (oDoorIndex == Block.Invalid) return; + ExtBlock oDoor = ExtBlock.FromIndex(oDoorIndex); + + PhysicsArgs args = default(PhysicsArgs); + args.ExtBlock = oDoor.BlockID == Block.custom_block; + lvl.AddUpdate(index, oDoor.RawID, true, args); } } diff --git a/MCGalaxy/Blocks/Physics/DoorPhysics.cs b/MCGalaxy/Blocks/Physics/DoorPhysics.cs index 436d87dc6..735ba582b 100644 --- a/MCGalaxy/Blocks/Physics/DoorPhysics.cs +++ b/MCGalaxy/Blocks/Physics/DoorPhysics.cs @@ -42,21 +42,26 @@ namespace MCGalaxy.Blocks.Physics { public static void oDoor(Level lvl, ref Check C) { ushort x, y, z; lvl.IntToPos(C.b, out x, out y, out z); - - int oneY = lvl.Width * lvl.Length; - if (x > 0) ActivateODoor(lvl, ref C, C.b - 1); - if (x < lvl.Width - 1) ActivateODoor(lvl, ref C, C.b + 1); - if (y > 0) ActivateODoor(lvl, ref C, C.b - oneY); - if (y < lvl.Height - 1) ActivateODoor(lvl, ref C, C.b + oneY); - if (z > 0) ActivateODoor(lvl, ref C, C.b - lvl.Width); - if (z < lvl.Length - 1) ActivateODoor(lvl, ref C, C.b + lvl.Width); + ExtBlock block = lvl.GetBlock(x, y, z); + + ActivateODoor(lvl, block, (ushort)(x - 1), y, z); + ActivateODoor(lvl, block, (ushort)(x + 1), y, z); + ActivateODoor(lvl, block, x, (ushort)(y - 1), z); + ActivateODoor(lvl, block, x, (ushort)(y + 1), z); + ActivateODoor(lvl, block, x, y, (ushort)(z - 1)); + ActivateODoor(lvl, block, x, y, (ushort)(z + 1)); C.data.Data = PhysicsArgs.RemoveFromChecks; } - static void ActivateODoor(Level lvl, ref Check C, int index) { - byte block = Block.Props[lvl.blocks[index]].oDoorId; - if (block == lvl.blocks[C.b]) { - lvl.AddUpdate(index, block, true); + static void ActivateODoor(Level lvl, ExtBlock oDoor, ushort x, ushort y, ushort z) { + int index; + ExtBlock block = lvl.GetBlock(x, y, z, out index); + block = ExtBlock.FromIndex(lvl.BlockProps[block.Index].oDoorIndex); + + if (index >= 0 && oDoor == block) { + PhysicsArgs args = default(PhysicsArgs); + args.ExtBlock = oDoor.BlockID == Block.custom_block; + lvl.AddUpdate(index, oDoor.RawID, true, args); } } @@ -69,7 +74,7 @@ namespace MCGalaxy.Blocks.Physics { 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)); ActivateTDoor(lvl, x, y, (ushort)(z + 1)); } @@ -80,7 +85,7 @@ namespace MCGalaxy.Blocks.Physics { if (index >= 0 && lvl.BlockProps[block.Index].IsTDoor) { PhysicsArgs args = ActivateablePhysics.GetTDoorArgs(block); lvl.AddUpdate(index, Block.Air, false, args); - } + } } } } \ No newline at end of file diff --git a/MCGalaxy/Commands/Information/CmdBlocks.cs b/MCGalaxy/Commands/Information/CmdBlocks.cs index eed85a82e..266a4e679 100644 --- a/MCGalaxy/Commands/Information/CmdBlocks.cs +++ b/MCGalaxy/Commands/Information/CmdBlocks.cs @@ -130,7 +130,7 @@ namespace MCGalaxy.Commands.Info { if (props.IsDoor) Player.Message(p, "Block is an ordinary door"); if (props.IsTDoor) Player.Message(p, "Block is a tdoor, which allows other blocks through when open"); - if (props.oDoorId != Block.Invalid) Player.Message(p, "Block is an odoor, which can be toggled by doors and toggles other odoors"); + if (props.oDoorIndex != Block.Invalid) Player.Message(p, "Block is an odoor, which can be toggled by doors and toggles other odoors"); if (Mover(b)) Player.Message(p, "Block can be activated by walking through it"); } diff --git a/MCGalaxy/Commands/World/CmdBlockProperties.cs b/MCGalaxy/Commands/World/CmdBlockProperties.cs index ccd4a28b9..014c82d0a 100644 --- a/MCGalaxy/Commands/World/CmdBlockProperties.cs +++ b/MCGalaxy/Commands/World/CmdBlockProperties.cs @@ -133,7 +133,10 @@ namespace MCGalaxy.Commands.World { } else if (prop == "opblock" || prop == "op") { scope[i].OPBlock = !scope[i].OPBlock; OnToggleSet(p, scope, block, "an OP block", scope[i].OPBlock); - } else { + } else if (prop == "odoor") { + string odoor = args.Length > 3 ? args[3] : null; + SetODoor(p, scope, block, i, odoor); + } else { Help(p); } } @@ -184,8 +187,7 @@ namespace MCGalaxy.Commands.World { scope[i].StackId = stackBlock.RawID; if (stackBlock.IsAir) { - Player.Message(p, "Removed stack block for {0}", - BlockName(scope, lvl, block)); + Player.Message(p, "Removed stack block for {0}", BlockName(scope, lvl, block)); } else { string stackBlockName = Player.IsSuper(p) ? BlockName(scope, lvl, stackBlock) : p.level.BlockName(stackBlock); @@ -195,6 +197,21 @@ namespace MCGalaxy.Commands.World { OnPropsChanged(scope, lvl, block); } + static void SetODoor(Player p, BlockProps[] scope, ExtBlock block, int i, string msg) { + 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)); + } else { + ExtBlock other = GetBlock(p, scope, msg); + if (other.IsInvalid) return; + scope[i].oDoorIndex = (ushort)other.Index; + + Player.Message(p, "oDoor for {0} set to: {1}", + BlockName(scope, lvl, block), BlockName(scope, lvl, other)); + } + OnPropsChanged(scope, lvl, block); + } static void OnPropsChanged(BlockProps[] scope, Level level, ExtBlock block) { scope[GetIndex(scope, block)].Changed = true;