From ecec7a9843bafac09530939158dc422e691538cc Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 28 Feb 2018 21:43:52 +1100 Subject: [PATCH] Redesign BlockQueue/PhysicsArgs for future extensibility --- MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs | 8 +++++ .../Blocks/Physics/ActivateablePhysics.cs | 6 ++-- MCGalaxy/Blocks/Physics/AirPhysics.cs | 6 +++- MCGalaxy/Blocks/Physics/DoorPhysics.cs | 29 +++++++++++++++---- MCGalaxy/Blocks/Physics/ExtraInfoPhysics.cs | 26 ----------------- MCGalaxy/Blocks/Physics/PhysicsArgs.cs | 7 +---- MCGalaxy/Commands/Information/CmdMapInfo.cs | 2 +- MCGalaxy/Commands/building/CmdAbort.cs | 3 +- MCGalaxy/Levels/BlockQueue.cs | 29 ++++++++++++------- MCGalaxy/Levels/Level.Physics.cs | 2 +- 10 files changed, 62 insertions(+), 56 deletions(-) diff --git a/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs b/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs index 95d6978d5..271d3d281 100644 --- a/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs +++ b/MCGalaxy/Blocks/Behaviour/BlockBehaviour.cs @@ -89,6 +89,10 @@ namespace MCGalaxy.Blocks { /// Retrieves the default physics block handler for the given block. internal static HandlePhysics GetPhysicsHandler(BlockID block, BlockProps[] props) { switch (block) { + case Block.Door_Log_air: return DoorPhysics.Do; + case Block.Door_TNT_air: return DoorPhysics.Do; + case Block.Door_Green_air: return DoorPhysics.Do; + case Block.SnakeTail: return SnakePhysics.DoTail; case Block.Snake: return SnakePhysics.Do; case Block.RocketHead: return RocketPhysics.Do; @@ -166,6 +170,10 @@ namespace MCGalaxy.Blocks { /// Retrieves the default physics block handler for the given block. internal static HandlePhysics GetPhysicsDoorsHandler(BlockID block, BlockProps[] props) { + if (block == Block.Air) return DoorPhysics.Do; + if (block == Block.Door_Log_air) return DoorPhysics.Do; + if (block == Block.Door_TNT_air) return DoorPhysics.Do; + if (block == Block.Door_Green_air) return DoorPhysics.Do; if (props[block].oDoorBlock != Block.Invalid) return DoorPhysics.oDoor; return null; } diff --git a/MCGalaxy/Blocks/Physics/ActivateablePhysics.cs b/MCGalaxy/Blocks/Physics/ActivateablePhysics.cs index 55fa466a1..07cf6f85a 100644 --- a/MCGalaxy/Blocks/Physics/ActivateablePhysics.cs +++ b/MCGalaxy/Blocks/Physics/ActivateablePhysics.cs @@ -84,9 +84,8 @@ namespace MCGalaxy.Blocks.Physics { internal static PhysicsArgs GetDoorArgs(BlockID block, out BlockID physForm) { PhysicsArgs args = default(PhysicsArgs); - args.Type1 = PhysicsArgs.Wait; args.Value1 = 16 - 1; + args.Type1 = PhysicsArgs.Custom; args.Value1 = 16 - 1; args.Type2 = PhysicsArgs.Revert; args.Value2 = (BlockRaw)block; - args.Door = true; args.ExtBlock = block >= Block.Extended; physForm = Block.Door_Log_air; // air @@ -102,9 +101,8 @@ namespace MCGalaxy.Blocks.Physics { internal static PhysicsArgs GetTDoorArgs(BlockID block) { PhysicsArgs args = default(PhysicsArgs); - args.Type1 = PhysicsArgs.Wait; args.Value1 = 16; + args.Type1 = PhysicsArgs.Custom; args.Value1 = 16; args.Type2 = PhysicsArgs.Revert; args.Value2 = (BlockRaw)block; - args.Door = true; args.ExtBlock = block >= Block.Extended; return args; } diff --git a/MCGalaxy/Blocks/Physics/AirPhysics.cs b/MCGalaxy/Blocks/Physics/AirPhysics.cs index d9e68360d..7ffe5c149 100644 --- a/MCGalaxy/Blocks/Physics/AirPhysics.cs +++ b/MCGalaxy/Blocks/Physics/AirPhysics.cs @@ -24,6 +24,10 @@ namespace MCGalaxy.Blocks.Physics { public static class AirPhysics { public static void DoAir(Level lvl, ref PhysInfo C) { + if (C.Data.Type1 == PhysicsArgs.Custom) { + DoorPhysics.Do(lvl, ref C); return; + } + ushort x = C.X, y = C.Y, z = C.Z; ActivateablePhysics.CheckNeighbours(lvl, x, y, z); ActivateablePhysics.CheckAt(lvl, x, (ushort)(y - 1), z); @@ -42,7 +46,7 @@ namespace MCGalaxy.Blocks.Physics { lvl.AddUpdate(C.Index, Block.Air, default(PhysicsArgs)); C.Data.Data = PhysicsArgs.RemoveFromChecks; return; } - + ushort x = C.X, y = C.Y, z = C.Z; FloodAir(lvl, (ushort)(x + 1), y, z, block); FloodAir(lvl, (ushort)(x - 1), y, z, block); diff --git a/MCGalaxy/Blocks/Physics/DoorPhysics.cs b/MCGalaxy/Blocks/Physics/DoorPhysics.cs index 48c732edf..53b576ef2 100644 --- a/MCGalaxy/Blocks/Physics/DoorPhysics.cs +++ b/MCGalaxy/Blocks/Physics/DoorPhysics.cs @@ -20,9 +20,29 @@ using BlockID = System.UInt16; namespace MCGalaxy.Blocks.Physics { public static class DoorPhysics { + + public static void Do(Level lvl, ref PhysInfo C) { + if (C.Data.Type1 != PhysicsArgs.Custom) return; + if (C.Data.Data == 0) { + BlockID block = (BlockID)(C.Data.Value2 | (C.Data.ExtBlock ? Block.Extended : 0)); + bool tdoor = lvl.Props[block].IsTDoor; + + if (tdoor) tDoor(lvl, ref C); + else Door(lvl, ref C); + } + + if (C.Data.Data <= C.Data.Value1) { // value1 for wait time + C.Data.Data++; + } else { + PhysicsArgs dArgs = default(PhysicsArgs); + dArgs.ExtBlock = C.Data.ExtBlock; + lvl.AddUpdate(C.Index, C.Data.Value2, dArgs); + C.Data.Data = PhysicsArgs.RemoveFromChecks; + } + } // Change anys door blocks nearby into air forms - public static void Door(Level lvl, ref PhysInfo C) { + static void Door(Level lvl, ref PhysInfo C) { ushort x = C.X, y = C.Y, z = C.Z; BlockID block = (BlockID)(C.Data.Value2 | (C.Data.ExtBlock ? Block.Extended : 0)); bool instant = block == Block.Door_Air || block == Block.Door_AirActivatable; @@ -42,7 +62,7 @@ namespace MCGalaxy.Blocks.Physics { public static void oDoor(Level lvl, ref PhysInfo C) { ushort x = C.X, y = C.Y, z = C.Z; BlockID block = C.Block; - + ActivateODoor(lvl, block, (ushort)(x - 1), y, z); ActivateODoor(lvl, block, (ushort)(x + 1), y, z); ActivateODoor(lvl, block, x, (ushort)(y - 1), z); @@ -60,10 +80,9 @@ namespace MCGalaxy.Blocks.Physics { if (index >= 0 && block == target) { lvl.AddUpdate(index, target, true); } - } + } - - public static void tDoor(Level lvl, ref PhysInfo C) { + static void tDoor(Level lvl, ref PhysInfo C) { ushort x = C.X, y = C.Y, z = C.Z; ActivateTDoor(lvl, (ushort)(x - 1), y, z); ActivateTDoor(lvl, (ushort)(x + 1), y, z); diff --git a/MCGalaxy/Blocks/Physics/ExtraInfoPhysics.cs b/MCGalaxy/Blocks/Physics/ExtraInfoPhysics.cs index e426ba893..da394b30a 100644 --- a/MCGalaxy/Blocks/Physics/ExtraInfoPhysics.cs +++ b/MCGalaxy/Blocks/Physics/ExtraInfoPhysics.cs @@ -25,19 +25,10 @@ namespace MCGalaxy.Blocks.Physics { public static class ExtraInfoPhysics { public static bool DoDoorsOnly(Level lvl, ref PhysInfo C) { - if (C.Data.Type1 == PhysicsArgs.Custom) return true; if (!C.Data.HasWait && C.Block == Block.Air) C.Data.ResetTypes(); if (!C.Data.HasWait) return false; - if (C.Data.Door && C.Data.Data == 0) { - BlockID block = (BlockID)(C.Data.Value2 | (C.Data.ExtBlock ? Block.Extended : 0)); - bool tdoor = lvl.Props[block].IsTDoor; - - if (tdoor) DoorPhysics.tDoor(lvl, ref C); - else DoorPhysics.Door(lvl, ref C); - } - int waitTime = 0; if (C.Data.Type1 == PhysicsArgs.Wait) waitTime = C.Data.Value1; if (C.Data.Type2 == PhysicsArgs.Wait) waitTime = C.Data.Value2; @@ -46,19 +37,10 @@ namespace MCGalaxy.Blocks.Physics { if (C.Data.Type1 == PhysicsArgs.Wait) C.Data.Type1 = 0; if (C.Data.Type2 == PhysicsArgs.Wait) C.Data.Type2 = 0; - if (C.Data.Door) { - PhysicsArgs dArgs = default(PhysicsArgs); - dArgs.ExtBlock = C.Data.ExtBlock; - lvl.AddUpdate(C.Index, C.Data.Value2, dArgs); - - C.Data.ResetTypes(); - C.Data.Data = PhysicsArgs.RemoveFromChecks; - } return false; } public static bool DoNormal(Level lvl, ref PhysInfo C) { - if (C.Data.Type1 == PhysicsArgs.Custom) return true; if (!C.Data.HasWait && C.Block == Block.Air) C.Data.ResetTypes(); @@ -68,14 +50,6 @@ namespace MCGalaxy.Blocks.Physics { args.ExtBlock = C.Data.ExtBlock; if (args.Wait) { - if (C.Data.Door && C.Data.Data == 0) { - BlockID block = (BlockID)(C.Data.Value2 | (C.Data.ExtBlock ? Block.Extended : 0)); - bool tdoor = lvl.Props[block].IsTDoor; - - if (tdoor) DoorPhysics.tDoor(lvl, ref C); - else DoorPhysics.Door(lvl, ref C); - } - if (C.Data.Data <= args.WaitTime) { C.Data.Data++; return true; } if (C.Data.Type1 == PhysicsArgs.Wait) C.Data.Type1 = 0; if (C.Data.Type2 == PhysicsArgs.Wait) C.Data.Type2 = 0; diff --git a/MCGalaxy/Blocks/Physics/PhysicsArgs.cs b/MCGalaxy/Blocks/Physics/PhysicsArgs.cs index 3ed4ded66..2382e20ce 100644 --- a/MCGalaxy/Blocks/Physics/PhysicsArgs.cs +++ b/MCGalaxy/Blocks/Physics/PhysicsArgs.cs @@ -27,7 +27,7 @@ namespace MCGalaxy.Blocks.Physics { public const uint TypeMask = 0x3F; public const uint TypeBitsMask = 0x07; public const uint ValueBitsMask = 0xFF; - public const uint ExtBit = 1u << 31; + public const uint ExtBit = 1u << 30; /// Indicates that this physics entry should be removed from the list of /// entries that are checked for physics, at the end of the current tick. @@ -58,11 +58,6 @@ namespace MCGalaxy.Blocks.Physics { set { Raw &= ~(ValueBitsMask << 22); Raw |= (uint)value << 22; } } - public bool Door { - get { return (Raw & (1u << 30)) != 0; } - set { Raw &= ~(1u << 30); Raw |= (value ? 1u : 0u) << 30; } - } - public bool ExtBlock { get { return (Raw & ExtBit) != 0; } set { Raw &= ~ExtBit; Raw |= value ? ExtBit : 0u; } diff --git a/MCGalaxy/Commands/Information/CmdMapInfo.cs b/MCGalaxy/Commands/Information/CmdMapInfo.cs index 735c2bc67..39f769b51 100644 --- a/MCGalaxy/Commands/Information/CmdMapInfo.cs +++ b/MCGalaxy/Commands/Information/CmdMapInfo.cs @@ -176,7 +176,7 @@ namespace MCGalaxy.Commands.Info { Player.Message(p, "Water level: &b{0}%S, Bedrock offset: &b{1}%S, Clouds height: &b{2}%S, Max fog distance: &b{3}", cfg.EdgeLevel,cfg.SidesOffset, cfg.CloudsHeight, cfg.MaxFogDistance); Player.Message(p, "Edge Block: &b{0}%S, Horizon Block: &b{1}", - cfg.EdgeBlock, cfg.HorizonBlock); + Block.GetName(p, cfg.EdgeBlock), Block.GetName(p, cfg.HorizonBlock)); Player.Message(p, "Clouds speed: &b{0}%%S, Weather speed: &b{1}%", (cfg.CloudsSpeed / 256f).ToString("F2"), (cfg.WeatherSpeed / 256f).ToString("F2")); diff --git a/MCGalaxy/Commands/building/CmdAbort.cs b/MCGalaxy/Commands/building/CmdAbort.cs index 0c3916b1c..b44c795d5 100644 --- a/MCGalaxy/Commands/building/CmdAbort.cs +++ b/MCGalaxy/Commands/building/CmdAbort.cs @@ -38,8 +38,7 @@ namespace MCGalaxy.Commands.Building { p.DefaultBrushArgs = ""; p.Transform = NoTransform.Instance; - lock (p.level.queueLock) - p.level.blockqueue.RemoveAll(b => (int)((b >> 9) & Player.SessionIDMask) == p.SessionID); + BlockQueue.RemoveAll(p); Player.Message(p, "Every toggle or action was aborted."); } diff --git a/MCGalaxy/Levels/BlockQueue.cs b/MCGalaxy/Levels/BlockQueue.cs index 28096bfb8..478519364 100644 --- a/MCGalaxy/Levels/BlockQueue.cs +++ b/MCGalaxy/Levels/BlockQueue.cs @@ -27,7 +27,10 @@ namespace MCGalaxy { public static int Interval = 100; public static int UpdatesPerTick = 750; static BufferedBlockSender bulkSender = new BufferedBlockSender(); - public const int BlockMask = 0x1FF; + + const int posShift = 32; + const int idShift = 12; + const int blockMask = 0x7FF; public static void Loop(SchedulerTask task) { Level[] loaded = LevelInfo.Loaded.Items; @@ -44,15 +47,21 @@ namespace MCGalaxy { if (index == -1) return; // Bit packing format // 32-63: index - // 9-31: session ID - // 8: is ext block or not - // 0-7: raw type - ulong flags = (ulong)index << 32; - flags |= (ulong)p.SessionID << 9; - flags |= (ulong)block & BlockMask; + // 12-31: session ID + // 0-11: block type + ulong flags = (ulong)index << posShift; + flags |= (ulong)p.SessionID << idShift; + flags |= (ulong)block & blockMask; - lock (p.level.queueLock) + lock (p.level.queueLock) { p.level.blockqueue.Add(flags); + } + } + + public static void RemoveAll(Player p) { + lock (p.level.queueLock) { + p.level.blockqueue.RemoveAll(b => (int)((b >> idShift) & Player.SessionIDMask) == p.SessionID); + } } static void ProcessLevelBlocks(Level lvl) { @@ -67,8 +76,8 @@ namespace MCGalaxy { for (int i = 0; i < count; i++) { ulong flags = lvl.blockqueue[i]; - int index = (int)(flags >> 32); - BlockID block = (BlockID)(flags & BlockMask); + int index = (int)(flags >> posShift); + BlockID block = (BlockID)(flags & blockMask); bulkSender.Add(index, block); } bulkSender.Send(true); diff --git a/MCGalaxy/Levels/Level.Physics.cs b/MCGalaxy/Levels/Level.Physics.cs index f2e11f7f1..96254491c 100644 --- a/MCGalaxy/Levels/Level.Physics.cs +++ b/MCGalaxy/Levels/Level.Physics.cs @@ -156,7 +156,7 @@ namespace MCGalaxy { C.Block = (BlockID)(Block.Extended | GetExtTileNoCheck(C.X, C.Y, C.Z)); } - if ((C.Data.Raw & mask) == 0 || extraHandler(this, ref C)) { + if ((C.Data.Raw & mask) == 0 || C.Data.Type1 == PhysicsArgs.Custom || extraHandler(this, ref C)) { HandlePhysics handler = handlers[C.Block]; if (handler != null) { handler(this, ref C);