From a5d492043d09e0942c9f499816c057a8f0656335 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 10 Aug 2017 17:34:05 +1000 Subject: [PATCH] Fix multiple instances in which blockprops would be incorrectly set. Also BlockDefinition.GlobalProps now uses half as much memory as before --- MCGalaxy/Blocks/BlockDefinitions.cs | 23 +++--- MCGalaxy/Blocks/BlockProperties.cs | 6 +- MCGalaxy/Commands/CPE/CustomBlockCommand.cs | 11 +-- MCGalaxy/Commands/World/CmdBlockProperties.cs | 75 ++++++++++--------- MCGalaxy/Levels/Level.cs | 9 ++- 5 files changed, 67 insertions(+), 57 deletions(-) diff --git a/MCGalaxy/Blocks/BlockDefinitions.cs b/MCGalaxy/Blocks/BlockDefinitions.cs index 3947c331d..2046736c1 100644 --- a/MCGalaxy/Blocks/BlockDefinitions.cs +++ b/MCGalaxy/Blocks/BlockDefinitions.cs @@ -46,7 +46,7 @@ namespace MCGalaxy { public const string GlobalPath = "blockdefs/global.json", GlobalBackupPath = "blockdefs/global.json.bak"; public static BlockDefinition[] GlobalDefs; - public static BlockProps[] GlobalProps = new BlockProps[Block.Count * 2]; + public static BlockProps[] GlobalProps = new BlockProps[Block.Count]; public BlockDefinition Copy() { BlockDefinition def = new BlockDefinition(); @@ -136,19 +136,21 @@ namespace MCGalaxy { public static void UpdateGlobalBlockProps() { for (int i = 0; i < GlobalProps.Length; i++) { - ExtBlock block = ExtBlock.FromIndex(i); + ExtBlock block = ExtBlock.FromRaw((byte)i); GlobalProps[i] = BlockProps.MakeDefault(); GlobalProps[i] = DefaultProps(block); } - BlockProps.Load("global", GlobalProps, true); + BlockProps.Load("global", GlobalProps, false); } internal static BlockProps DefaultProps(ExtBlock block) { - if (block.IsPhysicsType) return Block.Props[block.Index]; - - if (block.IsCustomType || GlobalDefs[block.BlockID] != null) - return GlobalProps[block.Index]; - return Block.Props[block.Index]; + if (block.IsPhysicsType) { + return Block.Props[block.Index]; + } else if (!block.IsCustomType && GlobalDefs[block.RawID] == null) { + return Block.Props[block.RawID]; + } else { + return GlobalProps[block.RawID]; + } } static void UpdateLoadedLevels(BlockDefinition[] oldGlobalDefs) { @@ -157,8 +159,9 @@ namespace MCGalaxy { for (int i = 0; i < lvl.CustomBlockDefs.Length; i++) { if (lvl.CustomBlockDefs[i] != oldGlobalDefs[i]) continue; - lvl.BlockProps[i] = GlobalProps[i]; - lvl.UpdateCustomBlock((byte)i, GlobalDefs[i]); + ExtBlock block = ExtBlock.FromRaw((byte)i); + lvl.BlockProps[block.Index] = DefaultProps(block); + lvl.UpdateCustomBlock(block.RawID, GlobalDefs[i]); } } } diff --git a/MCGalaxy/Blocks/BlockProperties.cs b/MCGalaxy/Blocks/BlockProperties.cs index 11e9dbf07..644d483f6 100644 --- a/MCGalaxy/Blocks/BlockProperties.cs +++ b/MCGalaxy/Blocks/BlockProperties.cs @@ -83,7 +83,7 @@ namespace MCGalaxy.Blocks { "Killed by water : Killed by lava : Kills players : death message : " + "Animal AI type : Stack block : Is OP block"); for (int i = 0; i < scope.Length; i++) { - if (!scope[i].Changed || !selector(i)) continue; + if (!scope[i].Changed || (selector != null && !selector(i))) continue; BlockProps props = scope[i]; // Convert ext to raw ids int id = i >= Block.Count ? (i - Block.Count) : i; @@ -97,7 +97,7 @@ namespace MCGalaxy.Blocks { } } - public static void Load(string group, BlockProps[] scope, bool custom) { + public static void Load(string group, BlockProps[] scope, bool lbScope) { if (!Directory.Exists("blockprops")) return; if (!File.Exists("blockprops/" + group + ".txt")) return; @@ -118,7 +118,7 @@ namespace MCGalaxy.Blocks { continue; } int idx = raw; - if (custom && raw >= Block.CpeCount) idx += Block.Count; + if (lbScope && raw >= Block.CpeCount) idx += Block.Count; bool.TryParse(parts[1], out scope[idx].IsRails); bool.TryParse(parts[2], out scope[idx].IsTDoor); diff --git a/MCGalaxy/Commands/CPE/CustomBlockCommand.cs b/MCGalaxy/Commands/CPE/CustomBlockCommand.cs index 2d9390bd7..610d51293 100644 --- a/MCGalaxy/Commands/CPE/CustomBlockCommand.cs +++ b/MCGalaxy/Commands/CPE/CustomBlockCommand.cs @@ -115,7 +115,7 @@ namespace MCGalaxy.Commands.CPE { if (srcDef == null) { MessageNoBlock(p, src, global, cmd); return; } if (ExistsInScope(dstDef, dst, global)) { MessageAlreadyBlock(p, dst, global, cmd); return; } - BlockProps props = global ? BlockDefinition.GlobalProps[src.Index] : p.level.BlockProps[src.Index]; + BlockProps props = global ? BlockDefinition.GlobalProps[src.RawID] : p.level.BlockProps[src.Index]; dstDef = srcDef.Copy(); dstDef.BlockID = (byte)dst.RawID; @@ -538,7 +538,7 @@ namespace MCGalaxy.Commands.CPE { return; } - BlockDefinition.GlobalProps[block.Index] = props; + BlockDefinition.GlobalProps[block.RawID] = props; Level[] loaded = LevelInfo.Loaded.Items; byte raw = block.RawID; @@ -558,14 +558,15 @@ namespace MCGalaxy.Commands.CPE { } BlockProps props = BlockProps.MakeDefault(); - BlockDefinition.GlobalProps[block.Index] = props; + if (!block.IsCustomType) props = Block.Props[block.RawID]; + + BlockDefinition.GlobalProps[block.RawID] = props; Level[] loaded = LevelInfo.Loaded.Items; byte raw = block.RawID; - if (!block.IsCustomType) props = Block.Props[raw]; foreach (Level lvl in loaded) { if (lvl.CustomBlockDefs[raw] != BlockDefinition.GlobalDefs[raw]) continue; - lvl.BlockProps[block.Index] = BlockDefinition.GlobalProps[block.Index]; + lvl.BlockProps[block.Index] = BlockDefinition.GlobalProps[block.RawID]; lvl.UpdateBlockHandler(block); } } diff --git a/MCGalaxy/Commands/World/CmdBlockProperties.cs b/MCGalaxy/Commands/World/CmdBlockProperties.cs index ad7c7d74b..ccd4a28b9 100644 --- a/MCGalaxy/Commands/World/CmdBlockProperties.cs +++ b/MCGalaxy/Commands/World/CmdBlockProperties.cs @@ -40,7 +40,7 @@ namespace MCGalaxy.Commands.World { SetProperty(p, scope, block, prop, args); } - BlockProps[] GetScope(Player p, string scope) { + static BlockProps[] GetScope(Player p, string scope) { if (scope.CaselessEq("core")) return Block.Props; if (scope.CaselessEq("global")) return BlockDefinition.GlobalProps; @@ -57,7 +57,7 @@ namespace MCGalaxy.Commands.World { return null; } - ExtBlock GetBlock(Player p, BlockProps[] scope, string input) { + static ExtBlock GetBlock(Player p, BlockProps[] scope, string input) { if (scope == Block.Props) { byte raw; if (!byte.TryParse(input, out raw)) @@ -70,13 +70,17 @@ namespace MCGalaxy.Commands.World { return new ExtBlock(raw, 0); } else if (scope == BlockDefinition.GlobalProps) { byte raw = BlockDefinition.GetBlock(input, BlockDefinition.GlobalDefs); - if (raw == Block.Invalid) + if (raw == Block.Invalid) { Player.Message(p, "&cThere is no global custom block with id or name \"{0}\"", input); + return ExtBlock.Invalid; + } return ExtBlock.FromRaw(raw); } else { byte raw = BlockDefinition.GetBlock(input, p.level.CustomBlockDefs); - if (raw == Block.Invalid) + if (raw == Block.Invalid) { Player.Message(p, "&cThere is no level custom block with id or name \"{0}\"", input); + return ExtBlock.Invalid; + } if (p.level.CustomBlockDefs[raw] == BlockDefinition.GlobalDefs[raw]) { Player.Message(p, "&cUse %T/BlockProps global &cto modify this custom block."); return ExtBlock.Invalid; @@ -85,10 +89,14 @@ namespace MCGalaxy.Commands.World { } } + static int GetIndex(BlockProps[] scope, ExtBlock block) { + return scope == BlockDefinition.GlobalProps ? block.RawID : block.Index; + } + void SetProperty(Player p, BlockProps[] scope, ExtBlock block, string prop, string[] args) { - int i = block.Index; + int i = GetIndex(scope, block); if (prop == "portal") { scope[i].IsPortal = !scope[i].IsPortal; OnToggleSet(p, scope, block, "a portal", scope[i].IsPortal); @@ -115,13 +123,13 @@ namespace MCGalaxy.Commands.World { OnToggleSet(p, scope, block, "a killer block", scope[i].KillerBlock); } else if (prop == "deathmsg" || prop == "deathmessage") { string msg = args.Length > 3 ? args[3] : null; - SetDeathMessage(p, scope, block, msg); + SetDeathMessage(p, scope, block, i, msg); } else if (prop == "animalai" || prop == "animal") { string msg = args.Length > 3 ? args[3] : null; - SetEnum(p, scope, block, msg); + SetEnum(p, scope, block, i, msg); } else if (prop == "stackid" || prop == "stackblock") { string msg = args.Length > 3 ? args[3] : null; - SetStackId(p, scope, block, msg); + SetStackId(p, scope, block, i, msg); } else if (prop == "opblock" || prop == "op") { scope[i].OPBlock = !scope[i].OPBlock; OnToggleSet(p, scope, block, "an OP block", scope[i].OPBlock); @@ -131,28 +139,27 @@ namespace MCGalaxy.Commands.World { } - static void OnToggleSet(Player p, BlockProps[] scope, ExtBlock block, - string type, bool toggled) { - Level lvl = Player.IsSuper(p) ? null : p.level; + static void OnToggleSet(Player p, BlockProps[] scope, ExtBlock block, string type, bool on) { + Level lvl = Player.IsSuper(p) ? null : p.level; Player.Message(p, "Block {0} is {1}: {2}", BlockName(scope, lvl, block), - type, toggled ? "&aYes" : "&cNo"); + type, on ? "&aYes" : "&cNo"); OnPropsChanged(scope, lvl, block); } - static void SetEnum(Player p, BlockProps[] scope, ExtBlock block, string msg) { + static void SetEnum(Player p, BlockProps[] scope, ExtBlock block, int i, 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[block.Index].AnimalAI = ai; + scope[i].AnimalAI = ai; Player.Message(p, "Animal AI for {0} set to: {1}", BlockName(scope, lvl, block), ai); OnPropsChanged(scope, lvl, block); } - static void SetDeathMessage(Player p, BlockProps[] scope, ExtBlock block, string msg) { - scope[block.Index].DeathMessage = msg; + static void SetDeathMessage(Player p, BlockProps[] scope, ExtBlock block, int i, string msg) { + scope[i].DeathMessage = msg; Level lvl = Player.IsSuper(p) ? null : p.level; if (msg == null) { @@ -165,7 +172,7 @@ namespace MCGalaxy.Commands.World { OnPropsChanged(scope, lvl, block); } - static void SetStackId(Player p, BlockProps[] scope, ExtBlock block, string msg) { + static void SetStackId(Player p, BlockProps[] scope, ExtBlock block, int i, string msg) { Level lvl = Player.IsSuper(p) ? null : p.level; ExtBlock stackBlock; @@ -174,7 +181,7 @@ namespace MCGalaxy.Commands.World { } else { if (!CommandParser.GetBlock(p, msg, out stackBlock)) return; } - scope[block.Index].StackId = stackBlock.RawID; + scope[i].StackId = stackBlock.RawID; if (stackBlock.IsAir) { Player.Message(p, "Removed stack block for {0}", @@ -190,43 +197,39 @@ namespace MCGalaxy.Commands.World { static void OnPropsChanged(BlockProps[] scope, Level level, ExtBlock block) { - int idx = block.Index; - scope[idx].Changed = true; - + scope[GetIndex(scope, block)].Changed = true; if (scope == Block.Props) { - BlockProps.Save("core", scope, i => true); - Level[] loaded = LevelInfo.Loaded.Items; - BlockDefinition.GlobalProps[idx] = BlockDefinition.DefaultProps(block); + BlockProps.Save("core", scope, null); + Level[] loaded = LevelInfo.Loaded.Items; + if (!block.IsPhysicsType) + BlockDefinition.GlobalProps[block.RawID] = BlockDefinition.DefaultProps(block); foreach (Level lvl in loaded) { - lvl.BlockProps[idx] = BlockDefinition.GlobalProps[idx]; + if (lvl.HasCustomProps(block)) continue; + + lvl.BlockProps[block.Index] = BlockDefinition.DefaultProps(block); lvl.UpdateBlockHandler(block); } } else if (scope == BlockDefinition.GlobalProps) { Level[] loaded = LevelInfo.Loaded.Items; - BlockProps.Save("global", scope, SelectGlobal); + BlockProps.Save("global", scope, null); byte raw = block.RawID; foreach (Level lvl in loaded) { if (lvl.CustomBlockDefs[raw] != BlockDefinition.GlobalDefs[raw]) continue; - lvl.BlockProps[idx] = BlockDefinition.GlobalProps[idx]; + if (lvl.HasCustomProps(block)) continue; + + lvl.BlockProps[block.Index] = BlockDefinition.DefaultProps(block); lvl.UpdateBlockHandler(block); } } else { - BlockProps.Save("lvl_" + level.name, scope, i => SelectLevel(level, i)); + BlockProps.Save("lvl_" + level.name, scope, idx => SelectLevel(level, idx)); level.UpdateBlockHandler(block); } } - static bool SelectGlobal(int i) { - ExtBlock block = ExtBlock.FromIndex(i); - return !block.IsPhysicsType && BlockDefinition.GlobalDefs[block.RawID] != null; - } - static bool SelectLevel(Level lvl, int i) { - ExtBlock block = ExtBlock.FromIndex(i); - return !block.IsPhysicsType && - lvl.CustomBlockDefs[block.RawID] != BlockDefinition.GlobalDefs[block.RawID]; + return lvl.HasCustomProps(ExtBlock.FromIndex(i)); } static string BlockName(BlockProps[] scope, Level lvl, ExtBlock block) { diff --git a/MCGalaxy/Levels/Level.cs b/MCGalaxy/Levels/Level.cs index f24003ce1..3aa426c8e 100644 --- a/MCGalaxy/Levels/Level.cs +++ b/MCGalaxy/Levels/Level.cs @@ -467,12 +467,15 @@ namespace MCGalaxy { public ushort MinX, MinY, MinZ; } + internal bool HasCustomProps(ExtBlock block) { + if (block.IsPhysicsType) return false; + return CustomBlockDefs[block.RawID] != BlockDefinition.GlobalDefs[block.RawID]; + } + void LoadCoreProps() { for (int i = 0; i < BlockProps.Length; i++) { ExtBlock block = ExtBlock.FromIndex(i); - byte raw = block.RawID; - - if (block.IsPhysicsType || CustomBlockDefs[raw] == BlockDefinition.GlobalDefs[raw]) { + if (!HasCustomProps(block)) { BlockProps[i] = BlockDefinition.DefaultProps(block); } else { BlockProps[i] = MCGalaxy.Blocks.BlockProps.MakeDefault();