From 9e944a8479b774dd4db3f43d2b513605b9004943 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Mon, 12 Jun 2017 23:23:54 +1000 Subject: [PATCH] Optimise getting block AABB for bot and player movement --- MCGalaxy/Blocks/BlockDefinitions.cs | 62 ++++++++++------------ MCGalaxy/Levels/IO/Importers/CwImporter.cs | 2 +- MCGalaxy/Levels/Level.Fields.cs | 6 ++- MCGalaxy/Levels/Level.cs | 39 ++++++-------- MCGalaxy/Player/Player.Handlers.cs | 3 +- MCGalaxy/util/Math/AABB.cs | 2 +- 6 files changed, 52 insertions(+), 62 deletions(-) diff --git a/MCGalaxy/Blocks/BlockDefinitions.cs b/MCGalaxy/Blocks/BlockDefinitions.cs index 88f9c55f8..98f8360db 100644 --- a/MCGalaxy/Blocks/BlockDefinitions.cs +++ b/MCGalaxy/Blocks/BlockDefinitions.cs @@ -128,7 +128,7 @@ namespace MCGalaxy { Server.ErrorLog(ex); } - Save(true, null); + Save(true, null); // As the BlockDefinition instances in levels will now be different // to the instances in GlobalDefs, we need to update them. if (oldDefs != null) UpdateLoadedLevels(oldDefs); @@ -139,7 +139,7 @@ namespace MCGalaxy { for (int i = 0; i < Block.Count; i++) { GlobalProps[i] = Block.Props[i]; GlobalProps[i + Block.Count] = new BlockProps((byte)i); - } + } BlockProps.Load("global", GlobalProps, true); } @@ -148,35 +148,28 @@ namespace MCGalaxy { foreach (Level lvl in loaded) { for (int i = 0; i < lvl.CustomBlockDefs.Length; i++) { if (lvl.CustomBlockDefs[i] != oldGlobalDefs[i]) continue; - lvl.CustomBlockDefs[i] = GlobalDefs[i]; + lvl.BlockProps[i] = GlobalProps[i]; + lvl.UpdateCustomBlock((byte)i, GlobalDefs[i]); } } } public static void Add(BlockDefinition def, BlockDefinition[] defs, Level level) { - byte block = def.BlockID; + byte raw = def.BlockID; bool global = defs == GlobalDefs; - if (global) { - Level[] loaded = LevelInfo.Loaded.Items; - foreach (Level lvl in loaded) { - if (lvl.CustomBlockDefs[block] == null) { - lvl.CustomBlockDefs[block] = def; - lvl.SetBlockHandler(ExtBlock.FromRaw(block)); - } - } - } + if (global) UpdateGlobalCustom(def); - defs[block] = def; + defs[raw] = def; if (global) Block.SetDefaultNames(); - if (!global) level.SetBlockHandler(ExtBlock.FromRaw(block)); + if (!global) level.SetBlockHandler(ExtBlock.FromRaw(raw)); Player[] players = PlayerInfo.Online.Items; foreach (Player pl in players) { if (!global && pl.level != level) continue; if (!pl.hasBlockDefs) continue; - if (global && pl.level.CustomBlockDefs[block] != GlobalDefs[block]) continue; + if (global && pl.level.CustomBlockDefs[raw] != GlobalDefs[raw]) continue; if (pl.HasCpeExt(CpeExt.BlockDefinitionsExt, 2) && def.Shape != 0) { pl.Send(Packet.DefineBlockExt(def, true, pl.hasCP437)); @@ -193,32 +186,35 @@ namespace MCGalaxy { } public static void Remove(BlockDefinition def, BlockDefinition[] defs, Level level) { - byte block = def.BlockID; + byte raw = def.BlockID; bool global = defs == GlobalDefs; - if (global) { - Level[] loaded = LevelInfo.Loaded.Items; - 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) UpdateGlobalCustom(def); + + defs[raw] = null; if (global) Block.SetDefaultNames(); - if (!global) level.SetBlockHandler(ExtBlock.FromRaw(block)); + if (!global) level.SetBlockHandler(ExtBlock.FromRaw(raw)); Player[] players = PlayerInfo.Online.Items; foreach (Player pl in players) { if (!global && pl.level != level) continue; - if (global && pl.level.CustomBlockDefs[block] != null) continue; + if (global && pl.level.CustomBlockDefs[raw] != null) continue; if (pl.hasBlockDefs) - pl.Send(Packet.UndefineBlock(block)); + pl.Send(Packet.UndefineBlock(raw)); } Save(global, level); } + static void UpdateGlobalCustom(BlockDefinition def) { + byte raw = def.BlockID; + Level[] loaded = LevelInfo.Loaded.Items; + + foreach (Level lvl in loaded) { + if (lvl.CustomBlockDefs[raw] != GlobalDefs[raw]) continue; + lvl.UpdateCustomBlock(raw, def); + } + } + public static byte GetBlock(string msg, Player p) { return GetBlock(msg, p.level.CustomBlockDefs); @@ -248,7 +244,7 @@ namespace MCGalaxy { LeftTex = id; RightTex = id; FrontTex = id; BackTex = id; } - + internal static void SendLevelCustomBlocks(Player pl) { BlockDefinition[] defs = pl.level.CustomBlockDefs; for (int i = 1; i < defs.Length; i++) { @@ -265,8 +261,8 @@ namespace MCGalaxy { } } - public static void UpdateFallback(bool global, byte block, Level level) { - Player[] players = PlayerInfo.Online.Items; + public static void UpdateFallback(bool global, byte block, Level level) { + Player[] players = PlayerInfo.Online.Items; foreach (Player pl in players) { if (!global && pl.level != level) continue; if (pl.hasBlockDefs) continue; diff --git a/MCGalaxy/Levels/IO/Importers/CwImporter.cs b/MCGalaxy/Levels/IO/Importers/CwImporter.cs index c28eeebc3..438fbdbe2 100644 --- a/MCGalaxy/Levels/IO/Importers/CwImporter.cs +++ b/MCGalaxy/Levels/IO/Importers/CwImporter.cs @@ -154,7 +154,7 @@ namespace MCGalaxy.Levels.IO { def.SideTex = def.LeftTex; def.Version2 = true; - lvl.CustomBlockDefs[def.BlockID] = def; + lvl.UpdateCustomBlock(def.BlockID, def); hasBlockDefs = true; } diff --git a/MCGalaxy/Levels/Level.Fields.cs b/MCGalaxy/Levels/Level.Fields.cs index 36cd6d662..641ffb41c 100644 --- a/MCGalaxy/Levels/Level.Fields.cs +++ b/MCGalaxy/Levels/Level.Fields.cs @@ -23,6 +23,7 @@ using MCGalaxy.Blocks.Physics; using MCGalaxy.DB; using MCGalaxy.Config; using MCGalaxy.Games; +using MCGalaxy.Maths; using MCGalaxy.Network; using MCGalaxy.Util; @@ -48,8 +49,8 @@ namespace MCGalaxy { public Position SpawnPos { get { return new Position(16 + spawnx * 32, 32 + spawny * 32, 16 + spawnz * 32); } } public Orientation SpawnRot { get { return new Orientation(rotx, roty); } } - public BlockDefinition[] CustomBlockDefs; - public BlockProps[] BlockProps; + public BlockDefinition[] CustomBlockDefs = new BlockDefinition[Block.Count]; + public BlockProps[] BlockProps = new BlockProps[Block.Count * 2]; public ExtrasCollection Extras = new ExtrasCollection(); internal HandleDelete[] deleteHandlers = new HandleDelete[Block.Count * 2]; @@ -57,6 +58,7 @@ namespace MCGalaxy { internal HandleWalkthrough[] walkthroughHandlers = new HandleWalkthrough[Block.Count * 2]; internal HandlePhysics[] physicsHandlers = new HandlePhysics[Block.Count * 2]; internal HandlePhysics[] physicsDoorsHandlers = new HandlePhysics[Block.Count * 2]; + internal AABB[] blockAABBs = new AABB[Block.Count * 2]; public ushort Width, Height, Length; // NOTE: These are for legacy code only, you should use upper case Width/Height/Length diff --git a/MCGalaxy/Levels/Level.cs b/MCGalaxy/Levels/Level.cs index cc8929612..34cf17a58 100644 --- a/MCGalaxy/Levels/Level.cs +++ b/MCGalaxy/Levels/Level.cs @@ -26,10 +26,7 @@ using MCGalaxy.Events; using MCGalaxy.Games; using MCGalaxy.Generator; using MCGalaxy.Levels.IO; -using MCGalaxy.Util; - -//WARNING! DO NOT CHANGE THE WAY THE LEVEL IS SAVED/LOADED! -//You MUST make it able to save and load as a new version other wise you will make old levels incompatible! +using MCGalaxy.Util; namespace MCGalaxy { public enum LevelPermission { @@ -42,22 +39,7 @@ namespace MCGalaxy { public sealed partial class Level : IDisposable { - public Level(string n, ushort x, ushort y, ushort z) { Init(n, x, y, z); } - - [Obsolete("Use MapGen.Generate instead")] - public Level(string n, ushort x, ushort y, ushort z, string theme, int seed = 0, bool useSeed = false) { - Init(n, x, y, z); - string args = useSeed ? seed.ToString() : ""; - MapGen.Generate(this, theme, args, null); - } - - [Obsolete("Use MapGen.Generate instead")] - public Level(string n, ushort x, ushort y, ushort z, string theme, string genArgs) { - Init(n, x, y, z); - MapGen.Generate(this, theme, genArgs, null); - } - - void Init(string n, ushort x, ushort y, ushort z) { + public Level(string n, ushort x, ushort y, ushort z) { Width = x; Height = y; Length = z; if (Width < 16) Width = 16; if (Height < 16) Height = 16; @@ -69,13 +51,15 @@ namespace MCGalaxy { height = Length; depth = Length; #pragma warning restore 0612 - CustomBlockDefs = new BlockDefinition[Block.Count]; for (int i = 0; i < CustomBlockDefs.Length; i++) CustomBlockDefs[i] = BlockDefinition.GlobalDefs[i]; - - BlockProps = new BlockProps[Block.Count * 2]; for (int i = 0; i < BlockProps.Length; i++) BlockProps[i] = BlockDefinition.GlobalProps[i]; + + for (int i = 0; i < blockAABBs.Length; i++) { + ExtBlock block = ExtBlock.FromIndex(i); + blockAABBs[i] = Block.BlockAABB(block, this); + } SetBlockHandlers(); name = n; MapName = n.ToLower(); @@ -402,7 +386,7 @@ namespace MCGalaxy { BlockDefinition[] defs = BlockDefinition.Load(false, lvl); for (int i = 0; i < defs.Length; i++) { if (defs[i] == null) continue; - lvl.CustomBlockDefs[i] = defs[i]; + lvl.UpdateCustomBlock((byte)i, defs[i]); } MCGalaxy.Blocks.BlockProps.Load("lvl_" + lvl.MapName, lvl.BlockProps, true); @@ -524,5 +508,12 @@ namespace MCGalaxy { physicsHandlers[i] = BlockBehaviour.GetPhysicsHandler(block, BlockProps); physicsDoorsHandlers[i] = BlockBehaviour.GetPhysicsDoorsHandler(block, BlockProps); } + + public void UpdateCustomBlock(byte raw, BlockDefinition def) { + CustomBlockDefs[raw] = def; + ExtBlock block = ExtBlock.FromRaw(raw); + SetBlockHandler(block); + blockAABBs[block.Index] = Block.BlockAABB(block, this); + } } } \ No newline at end of file diff --git a/MCGalaxy/Player/Player.Handlers.cs b/MCGalaxy/Player/Player.Handlers.cs index ae86983e8..3648f5ce7 100644 --- a/MCGalaxy/Player/Player.Handlers.cs +++ b/MCGalaxy/Player/Player.Handlers.cs @@ -421,7 +421,8 @@ namespace MCGalaxy { ushort xP = (ushort)x, yP = (ushort)y, zP = (ushort)z; ExtBlock block = level.GetBlock(xP, yP, zP); if (block.BlockID == Block.Invalid) continue; - AABB blockBB = Block.BlockAABB(block, level).Offset(x * 32, y * 32, z * 32); + + AABB blockBB = level.blockAABBs[block.Index].Offset(x * 32, y * 32, z * 32); if (!bb.Intersects(blockBB)) continue; // We can activate only one walkthrough block per movement diff --git a/MCGalaxy/util/Math/AABB.cs b/MCGalaxy/util/Math/AABB.cs index 4b0241eaf..12ff0e0c1 100644 --- a/MCGalaxy/util/Math/AABB.cs +++ b/MCGalaxy/util/Math/AABB.cs @@ -153,7 +153,7 @@ namespace MCGalaxy.Maths { ushort xP = (ushort)x, yP = (ushort)y, zP = (ushort)z; ExtBlock block = lvl.GetBlock(xP, yP, zP); - AABB blockBB = Block.BlockAABB(block, lvl).Offset(x * 32, y * 32, z * 32); + AABB blockBB = lvl.blockAABBs[block.Index].Offset(x * 32, y * 32, z * 32); if (!bb.Intersects(blockBB)) continue; BlockDefinition def = lvl.GetBlockDef(block);