diff --git a/Source/Core/General/MapManager.cs b/Source/Core/General/MapManager.cs index 37086126..01d41845 100755 --- a/Source/Core/General/MapManager.cs +++ b/Source/Core/General/MapManager.cs @@ -2553,6 +2553,16 @@ namespace CodeImp.DoomBuilder foreach(Thing t in General.Map.Map.Things) t.TranslateToUDMF(); } + // Make sure the raw flags are up to date + if (oldiotype == typeof(DoomMapSetIO) || oldiotype == typeof(HexenMapSetIO)) + { + foreach (Thing t in General.Map.map.Things) + t.UpdateRawFlagsFromFlags(); + + foreach (Linedef ld in General.Map.Map.Linedefs) + ld.UpdateRawFlagsFromFlags(); + } + config = new GameConfiguration(configinfo.Configuration); //mxd configinfo.ApplyDefaults(config); General.Editing.UpdateCurrentEditModes(); @@ -2607,6 +2617,16 @@ namespace CodeImp.DoomBuilder for(int i = 0; i < t.Args.Length; i++) t.Args[i] = 0; } + // Make sure the flags dictionary is up to date with flags that did not exist in the old game configuration + if ((oldiotype == typeof(DoomMapSetIO) || oldiotype == typeof(HexenMapSetIO)) && (io is DoomMapSetIO || io is HexenMapSetIO)) + { + foreach (Thing t in General.Map.Map.Things) + t.UpdateFlagsFromRawFlags(); + + foreach (Linedef ld in General.Map.Map.Linedefs) + ld.UpdateFlagsFromRawFlags(); + } + map.UpdateCustomLinedefColors(); // Reload resources diff --git a/Source/Core/IO/ClipboardStreamReader.cs b/Source/Core/IO/ClipboardStreamReader.cs index 897f456f..a321b9b5 100755 --- a/Source/Core/IO/ClipboardStreamReader.cs +++ b/Source/Core/IO/ClipboardStreamReader.cs @@ -248,7 +248,7 @@ namespace CodeImp.DoomBuilder.IO Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); if(l != null) { - l.Update(stringflags, 0, tags, special, args); + l.Update(stringflags, 0, 0, tags, special, args); l.UpdateCache(); // Add custom fields @@ -381,7 +381,7 @@ namespace CodeImp.DoomBuilder.IO Thing t = map.CreateThing(); if(t != null) { - t.Update(type, x, y, height, angledeg, pitch, roll, scaleX, scaleY, stringflags, tag, special, args); + t.Update(type, x, y, height, angledeg, pitch, roll, scaleX, scaleY, stringflags, 0, tag, special, args); // Add custom fields t.Fields.BeforeFieldsChange(); diff --git a/Source/Core/IO/DoomMapSetIO.cs b/Source/Core/IO/DoomMapSetIO.cs index 6aee0b66..3a954039 100755 --- a/Source/Core/IO/DoomMapSetIO.cs +++ b/Source/Core/IO/DoomMapSetIO.cs @@ -141,19 +141,18 @@ namespace CodeImp.DoomBuilder.IO int y = reader.ReadInt16(); int angle = reader.ReadInt16(); int type = reader.ReadUInt16(); - int flags = reader.ReadUInt16(); + ushort flags = reader.ReadUInt16(); // Make string flags Dictionary stringflags = new Dictionary(StringComparer.Ordinal); foreach(KeyValuePair f in manager.Config.ThingFlags) { - int fnum; - if(int.TryParse(f.Key, out fnum)) stringflags[f.Key] = ((flags & fnum) == fnum); + if (int.TryParse(f.Key, out int fnum)) stringflags[f.Key] = ((flags & fnum) == fnum); } // Create new item Thing t = map.CreateThing(); - t.Update(type, x, y, 0, angle, 0, 0, 1.0f, 1.0f, stringflags, 0, 0, new int[Thing.NUM_ARGS]); + t.Update(type, x, y, 0, angle, 0, 0, 1.0f, 1.0f, stringflags, flags, 0, 0, new int[Thing.NUM_ARGS]); } // Done @@ -299,7 +298,7 @@ namespace CodeImp.DoomBuilder.IO // Read properties from stream int v1 = readline.ReadUInt16(); int v2 = readline.ReadUInt16(); - int flags = readline.ReadUInt16(); + ushort flags = readline.ReadUInt16(); int action = readline.ReadUInt16(); int tag = readline.ReadUInt16(); int s1 = readline.ReadUInt16(); @@ -320,7 +319,7 @@ namespace CodeImp.DoomBuilder.IO if(Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f) { Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); - l.Update(stringflags, 0, new List { tag }, action, new int[Linedef.NUM_ARGS]); + l.Update(stringflags, flags, 0, new List { tag }, action, new int[Linedef.NUM_ARGS]); l.UpdateCache(); string thigh, tmid, tlow; @@ -440,20 +439,14 @@ namespace CodeImp.DoomBuilder.IO // Go for all things foreach(Thing t in map.Things) { - // Convert flags - int flags = 0; - foreach(KeyValuePair f in t.Flags) - { - int fnum; - if(f.Value && int.TryParse(f.Key, out fnum)) flags |= fnum; - } + t.UpdateRawFlagsFromFlags(); // Write properties to stream writer.Write((Int16)t.Position.x); writer.Write((Int16)t.Position.y); writer.Write((Int16)t.AngleDoom); writer.Write((UInt16)t.Type); - writer.Write((UInt16)flags); + writer.Write(t.RawFlags); } // Find insert position and remove old lump @@ -505,18 +498,12 @@ namespace CodeImp.DoomBuilder.IO // Go for all lines foreach(Linedef l in map.Linedefs) { - // Convert flags - int flags = 0; - foreach(KeyValuePair f in l.Flags) - { - int fnum; - if(f.Value && int.TryParse(f.Key, out fnum)) flags |= fnum; - } + l.UpdateRawFlagsFromFlags(); // Write properties to stream writer.Write((UInt16)vertexids[l.Start]); writer.Write((UInt16)vertexids[l.End]); - writer.Write((UInt16)flags); + writer.Write(l.RawFlags); writer.Write((UInt16)l.Action); writer.Write((UInt16)l.Tag); diff --git a/Source/Core/IO/HexenMapSetIO.cs b/Source/Core/IO/HexenMapSetIO.cs index 5bbff679..52910f9c 100755 --- a/Source/Core/IO/HexenMapSetIO.cs +++ b/Source/Core/IO/HexenMapSetIO.cs @@ -143,7 +143,7 @@ namespace CodeImp.DoomBuilder.IO int z = reader.ReadInt16(); int angle = reader.ReadInt16(); int type = reader.ReadUInt16(); - int flags = reader.ReadUInt16(); + ushort flags = reader.ReadUInt16(); int action = reader.ReadByte(); args[0] = reader.ReadByte(); args[1] = reader.ReadByte(); @@ -155,13 +155,12 @@ namespace CodeImp.DoomBuilder.IO Dictionary stringflags = new Dictionary(StringComparer.Ordinal); foreach(KeyValuePair f in manager.Config.ThingFlags) { - int fnum; - if(int.TryParse(f.Key, out fnum)) stringflags[f.Key] = ((flags & fnum) == fnum); + if (int.TryParse(f.Key, out int fnum)) stringflags[f.Key] = ((flags & fnum) == fnum); } // Create new item Thing t = map.CreateThing(); - t.Update(type, x, y, z, angle, 0, 0, 1.0f, 1.0f, stringflags, tag, action, args); + t.Update(type, x, y, z, angle, 0, 0, 1.0f, 1.0f, stringflags, flags, tag, action, args); } // Done @@ -309,7 +308,7 @@ namespace CodeImp.DoomBuilder.IO // Read properties from stream int v1 = readline.ReadUInt16(); int v2 = readline.ReadUInt16(); - int flags = readline.ReadUInt16(); + ushort flags = readline.ReadUInt16(); int action = readline.ReadByte(); args[0] = readline.ReadByte(); args[1] = readline.ReadByte(); @@ -334,7 +333,7 @@ namespace CodeImp.DoomBuilder.IO if(Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f) { Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); - l.Update(stringflags, (flags & manager.Config.LinedefActivationsFilter), new List { 0 }, action, args); + l.Update(stringflags, flags, (flags & manager.Config.LinedefActivationsFilter), new List { 0 }, action, args); l.UpdateCache(); Sidedef s; @@ -454,15 +453,8 @@ namespace CodeImp.DoomBuilder.IO // Go for all things foreach(Thing t in map.Things) { - // Convert flags - int flags = 0; - foreach(KeyValuePair f in t.Flags) - { - int fnum; - if(f.Value && int.TryParse(f.Key, out fnum)) flags |= fnum; - } + t.UpdateRawFlagsFromFlags(); - // Write properties to stream // Write properties to stream writer.Write((UInt16)t.Tag); writer.Write((Int16)t.Position.x); @@ -470,7 +462,7 @@ namespace CodeImp.DoomBuilder.IO writer.Write((Int16)t.Position.z); writer.Write((Int16)t.AngleDoom); writer.Write((UInt16)t.Type); - writer.Write((UInt16)flags); + writer.Write(t.RawFlags); writer.Write((Byte)t.Action); writer.Write((Byte)t.Args[0]); writer.Write((Byte)t.Args[1]); @@ -526,16 +518,11 @@ namespace CodeImp.DoomBuilder.IO // Go for all lines foreach(Linedef l in map.Linedefs) { - // Convert flags - int flags = 0; - foreach(KeyValuePair f in l.Flags) - { - int fnum; - if(f.Value && int.TryParse(f.Key, out fnum)) flags |= fnum; - } + l.UpdateRawFlagsFromFlags(); + ushort flags = l.RawFlags; // Add activates to flags - flags |= (l.Activate & manager.Config.LinedefActivationsFilter); + flags |= (ushort)(l.Activate & manager.Config.LinedefActivationsFilter); // Write properties to stream writer.Write((UInt16)vertexids[l.Start]); diff --git a/Source/Core/IO/UniversalStreamReader.cs b/Source/Core/IO/UniversalStreamReader.cs index 9bc1b447..725e812e 100755 --- a/Source/Core/IO/UniversalStreamReader.cs +++ b/Source/Core/IO/UniversalStreamReader.cs @@ -217,7 +217,7 @@ namespace CodeImp.DoomBuilder.IO Thing t = map.CreateThing(); if(t != null) { - t.Update(type, x, y, height, angledeg, pitch, roll, scaleX, scaleY, stringflags, tag, special, args); + t.Update(type, x, y, height, angledeg, pitch, roll, scaleX, scaleY, stringflags, 0, tag, special, args); // Custom fields ReadCustomFields(c, t, "thing"); @@ -296,7 +296,7 @@ namespace CodeImp.DoomBuilder.IO Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]); if(l != null) { - l.Update(stringflags, 0, tags, special, args); + l.Update(stringflags, 0, 0,tags, special, args); l.UpdateCache(); // Custom fields diff --git a/Source/Core/Map/Linedef.cs b/Source/Core/Map/Linedef.cs index d98b41b1..36dc3990 100755 --- a/Source/Core/Map/Linedef.cs +++ b/Source/Core/Map/Linedef.cs @@ -68,6 +68,7 @@ namespace CodeImp.DoomBuilder.Map // Properties private Dictionary flags; + private ushort rawflags; // The actual flags bitmap that also might include unknown flags private int action; private int activate; private List tags; //mxd @@ -92,6 +93,7 @@ namespace CodeImp.DoomBuilder.Map public Sidedef Back { get { return back; } } public Line2D Line { get { return new Line2D(start.Position, end.Position); } } internal Dictionary Flags { get { return flags; } } + public ushort RawFlags { get { return rawflags; } } public int Action { get { return action; } set { BeforePropsChange(); action = value; UpdateColorPreset(); } } public int Activate { get { return activate; } set { BeforePropsChange(); activate = value; UpdateColorPreset(); } } @@ -310,6 +312,7 @@ namespace CodeImp.DoomBuilder.Map l.action = action; l.args = (int[])args.Clone(); l.flags = new Dictionary(flags); + l.rawflags = rawflags; l.tags = new List(tags); //mxd l.updateneeded = true; l.activate = activate; @@ -317,7 +320,40 @@ namespace CodeImp.DoomBuilder.Map l.UpdateColorPreset();//mxd base.CopyPropertiesTo(l); } - + + /// + /// Updates the raw flag bit map from the flags dictionary. Has to be called before the flags in the game config changed. Has to be called in conjunction with UpdateFlagsFromRawFlags. + /// + internal void UpdateRawFlagsFromFlags() + { + foreach (KeyValuePair f in flags) + { + if (ushort.TryParse(f.Key, out ushort fnum)) + { + // Set bit to 0 + rawflags &= (ushort)~fnum; + + // Set bit if necessary + if (f.Value) + rawflags |= fnum; + } + } + } + + /// + /// Updates the flags dictionary from the raw flags. Has to be called after the flags in the game config changed. Has to be called in conjunction with UpdateRawFlagsFromFlags. + /// + internal void UpdateFlagsFromRawFlags() + { + foreach (string fname in General.Map.Config.LinedefFlags.Keys) + { + if (ushort.TryParse(fname, out ushort fnum)) + { + flags[fname] = (rawflags & fnum) == fnum; + } + } + } + // This attaches a sidedef on the front internal void AttachFront(Sidedef s) { @@ -1403,12 +1439,13 @@ namespace CodeImp.DoomBuilder.Map #region ================== Changes // This updates all properties - public void Update(Dictionary flags, int activate, List tags, int action, int[] args) + public void Update(Dictionary flags, ushort rawflags, int activate, List tags, int action, int[] args) { BeforePropsChange(); // Apply changes this.flags = new Dictionary(flags); + this.rawflags = rawflags; this.tags = new List(tags); //mxd this.activate = activate; this.action = action; diff --git a/Source/Core/Map/Thing.cs b/Source/Core/Map/Thing.cs index f1f174e3..49f71588 100755 --- a/Source/Core/Map/Thing.cs +++ b/Source/Core/Map/Thing.cs @@ -63,6 +63,7 @@ namespace CodeImp.DoomBuilder.Map private int angledoom; // Angle as entered / stored in file private double anglerad; // Angle in radians private Dictionary flags; + private ushort rawflags; // The actual flags bitmap that also might include unknown flags private int tag; private int action; private int[] args; @@ -111,6 +112,7 @@ namespace CodeImp.DoomBuilder.Map public double Angle { get { return anglerad; } } public int AngleDoom { get { return angledoom; } } internal Dictionary Flags { get { return flags; } } + public ushort RawFlags { get { return rawflags; } } public int Action { get { return action; } set { BeforePropsChange(); action = value; } } public int[] Args { get { return args; } } public float Size { get { return size * GetObjectScale(); } } @@ -259,6 +261,7 @@ namespace CodeImp.DoomBuilder.Map t.spritescale = spritescale; //mxd t.pos = pos; t.flags = new Dictionary(flags); + t.rawflags = rawflags; t.tag = tag; t.action = action; t.args = (int[])args.Clone(); @@ -274,6 +277,39 @@ namespace CodeImp.DoomBuilder.Map base.CopyPropertiesTo(t); } + /// + /// Updates the raw flag bit map from the flags dictionary. Has to be called before the flags in the game config changed. Has to be called in conjunction with UpdateFlagsFromRawFlags. + /// + internal void UpdateRawFlagsFromFlags() + { + foreach (KeyValuePair f in flags) + { + if (ushort.TryParse(f.Key, out ushort fnum)) + { + // Set bit to 0 + rawflags &= (ushort)~fnum; + + // Set bit if necessary + if (f.Value) + rawflags |= fnum; + } + } + } + + /// + /// Updates the flags dictionary from the raw flags. Has to be called after the flags in the game config changed. Has to be called in conjunction with UpdateRawFlagsFromFlags. + /// + internal void UpdateFlagsFromRawFlags() + { + foreach (string fname in General.Map.Config.ThingFlags.Keys) + { + if (ushort.TryParse(fname, out ushort fnum)) + { + flags[fname] = (rawflags & fnum) == fnum; + } + } + } + // This determines which sector the thing is in and links it public void DetermineSector() { @@ -555,7 +591,7 @@ namespace CodeImp.DoomBuilder.Map // This updates all properties // NOTE: This does not update sector! (call DetermineSector) public void Update(int type, double x, double y, double zoffset, int angle, int pitch, int roll, double scaleX, double scaleY, - Dictionary flags, int tag, int action, int[] args) + Dictionary flags, ushort rawflags, int tag, int action, int[] args) { // Apply changes this.type = type; @@ -566,6 +602,7 @@ namespace CodeImp.DoomBuilder.Map this.scaleX = (scaleX == 0 ? 1.0f : scaleX); //mxd this.scaleY = (scaleY == 0 ? 1.0f : scaleY); //mxd this.flags = new Dictionary(flags); + this.rawflags = rawflags; this.tag = tag; this.action = action; this.args = new int[NUM_ARGS]; diff --git a/Source/Core/ZDoom/ZScriptActorStructure.cs b/Source/Core/ZDoom/ZScriptActorStructure.cs index 68abd587..e0793c4c 100755 --- a/Source/Core/ZDoom/ZScriptActorStructure.cs +++ b/Source/Core/ZDoom/ZScriptActorStructure.cs @@ -676,7 +676,7 @@ namespace CodeImp.DoomBuilder.ZDoom // try to read in a variable/method. bool bmethod = false; - string[] availablemodifiers = new string[] { "static", "native", "action", "readonly", "protected", "private", "virtual", "override", "meta", "transient", "deprecated", "final", "play", "ui", "clearscope", "virtualscope", "version", "const", "abstract" }; + string[] availablemodifiers = new string[] { "static", "native", "action", "internal", "readonly", "protected", "private", "virtual", "override", "meta", "transient", "deprecated", "final", "play", "ui", "clearscope", "virtualscope", "version", "const", "abstract" }; string[] versionedmodifiers = new string[] { "version", "deprecated" }; string[] methodmodifiers = new string[] { "action", "virtual", "override", "final", "abstract" }; HashSet modifiers = new HashSet(); diff --git a/Source/Plugins/3DFloorMode/ThreeDFloor.cs b/Source/Plugins/3DFloorMode/ThreeDFloor.cs index 44081406..79864701 100644 --- a/Source/Plugins/3DFloorMode/ThreeDFloor.cs +++ b/Source/Plugins/3DFloorMode/ThreeDFloor.cs @@ -228,7 +228,7 @@ namespace CodeImp.DoomBuilder.ThreeDFloorMode { // We need to update the linedef's args, but we can't do it directly because otherwise their state will not be saved for the undo snapshot, // so we're using the linedef's update method - sd.Line.Update(sd.Line.GetFlags(), sd.Line.Activate, sd.Line.Tags, sd.Line.Action, new int[] { sd.Line.Args[0], type, flags, alpha, sd.Line.Args[4] }); + sd.Line.Update(sd.Line.GetFlags(), sd.Line.RawFlags, sd.Line.Activate, sd.Line.Tags, sd.Line.Action, new int[] { sd.Line.Args[0], type, flags, alpha, sd.Line.Args[4] }); } } }