mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-22 20:02:48 +00:00
UDMF reader/writer: fixed a bug where unknown top level fields and blocks were not preserved. Fixes #627
This commit is contained in:
parent
d8bd7165a7
commit
80e56310a3
3 changed files with 80 additions and 2 deletions
|
@ -163,6 +163,9 @@ namespace CodeImp.DoomBuilder.IO
|
|||
Dictionary<int, Sector> sectorlink = ReadSectors(map, textmap);
|
||||
ReadLinedefs(map, textmap, vertexlink, sectorlink);
|
||||
ReadThings(map, textmap);
|
||||
|
||||
// Read all the stuff we don't know, but have to preserve
|
||||
map.UnknownUDMFData = GetUnknownCollections(textmap.Root, new List<string>() { "namespace", "vertex", "sector", "linedef", "sidedef", "thing" });
|
||||
}
|
||||
|
||||
// This reads the things
|
||||
|
@ -629,6 +632,25 @@ namespace CodeImp.DoomBuilder.IO
|
|||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get unknown fields and blocks from an universal collection.
|
||||
/// </summary>
|
||||
/// <param name="collection">Universal collection to get the fields and blocks from</param>
|
||||
/// <param name="knowncollections">List of fields and block that are known and can be ignored</param>
|
||||
/// <returns></returns>
|
||||
private static List<UniversalEntry> GetUnknownCollections(UniversalCollection collection, List<string> knowncollections)
|
||||
{
|
||||
List<UniversalEntry> list = new List<UniversalEntry>();
|
||||
|
||||
// Make list
|
||||
foreach (UniversalEntry e in collection)
|
||||
{
|
||||
if (!knowncollections.Contains(e.Key)) list.Add(e);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
// writenamespace may be null to omit writing the namespace to the stream
|
||||
public void Write(MapSet map, Stream stream, string writenamespace)
|
||||
{
|
||||
Write(map.Vertices, map.Linedefs, map.Sidedefs, map.Sectors, map.Things, stream, writenamespace);
|
||||
Write(map.Vertices, map.Linedefs, map.Sidedefs, map.Sectors, map.Things, map.UnknownUDMFData, stream, writenamespace);
|
||||
}
|
||||
|
||||
// This writes the structures to a stream
|
||||
|
@ -123,13 +123,16 @@ namespace CodeImp.DoomBuilder.IO
|
|||
// If there are missing sidedefs, their reference will be removed from the linedefs.
|
||||
public void Write(ICollection<Vertex> vertices, ICollection<Linedef> linedefs,
|
||||
ICollection<Sidedef> sidedefs, ICollection<Sector> sectors,
|
||||
ICollection<Thing> things, Stream stream, string writenamespace)
|
||||
ICollection<Thing> things, ICollection<UniversalEntry> unknowndata, Stream stream, string writenamespace)
|
||||
{
|
||||
UniversalParser textmap = new UniversalParser();
|
||||
|
||||
// Begin with fields that must be at the top
|
||||
if(writenamespace != null) textmap.Root.Add("namespace", writenamespace);
|
||||
|
||||
// Dump unknown fields at the top
|
||||
WriteUnknownData(unknowndata, textmap);
|
||||
|
||||
Dictionary<Vertex, int> vertexids = new Dictionary<Vertex, int>(vertices.Count); //mxd
|
||||
Dictionary<Sidedef, int> sidedefids = new Dictionary<Sidedef, int>(sidedefs.Count); //mxd
|
||||
Dictionary<Sector, int> sectorids = new Dictionary<Sector, int>(sectors.Count); //mxd
|
||||
|
@ -362,6 +365,31 @@ namespace CodeImp.DoomBuilder.IO
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This writes UDMF data UDB doesn't know about to the map.
|
||||
/// </summary>
|
||||
/// <param name="data">Collection of universal entries.</param>
|
||||
/// <param name="textmap">The map</param>
|
||||
private void WriteUnknownData(ICollection<UniversalEntry> data, UniversalParser textmap)
|
||||
{
|
||||
foreach (UniversalEntry e in data)
|
||||
{
|
||||
if (e.Value is UniversalCollection)
|
||||
{
|
||||
UniversalCollection coll = new UniversalCollection();
|
||||
|
||||
foreach (UniversalEntry ie in (UniversalCollection)e.Value)
|
||||
coll.Add(ie.Key, ie.Value);
|
||||
|
||||
textmap.Root.Add(e.Key, coll);
|
||||
}
|
||||
else
|
||||
{
|
||||
textmap.Root.Add(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This adds custom fields from a map element to a collection
|
||||
private void AddCustomFields(MapElement element, string elementname, UniversalCollection collection)
|
||||
{
|
||||
|
|
|
@ -94,6 +94,9 @@ namespace CodeImp.DoomBuilder.Map
|
|||
private LinkedList<Sector> sel_sectors;
|
||||
private LinkedList<Thing> sel_things;
|
||||
private SelectionType sel_type;
|
||||
|
||||
// Unknown UDMF data that needs to be preserved
|
||||
private List<UniversalEntry> unknownudmfdata;
|
||||
|
||||
// Statics
|
||||
private static long emptylongname;
|
||||
|
@ -164,6 +167,8 @@ namespace CodeImp.DoomBuilder.Map
|
|||
|
||||
internal bool AutoRemove { get { return autoremove; } set { autoremove = value; } }
|
||||
|
||||
internal List<UniversalEntry> UnknownUDMFData { get { return unknownudmfdata; } set { unknownudmfdata = value; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Constructor / Disposer
|
||||
|
@ -184,6 +189,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
indexholes = new List<int>();
|
||||
lastsectorindex = 0;
|
||||
autoremove = true;
|
||||
unknownudmfdata = new List<UniversalEntry>();
|
||||
|
||||
// We have no destructor
|
||||
GC.SuppressFinalize(this);
|
||||
|
@ -205,6 +211,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
indexholes = new List<int>();
|
||||
lastsectorindex = 0;
|
||||
autoremove = true;
|
||||
unknownudmfdata = new List<UniversalEntry>();
|
||||
|
||||
// Deserialize
|
||||
Deserialize(stream);
|
||||
|
@ -387,6 +394,27 @@ namespace CodeImp.DoomBuilder.Map
|
|||
// Remove clone references
|
||||
foreach(Vertex v in vertices) v.Clone = null;
|
||||
foreach(Sector s in sectors) s.Clone = null;
|
||||
|
||||
// Copy unknown UDMF data
|
||||
newset.UnknownUDMFData = new List<UniversalEntry>();
|
||||
foreach(UniversalEntry e in unknownudmfdata)
|
||||
{
|
||||
if(e.Value is UniversalCollection)
|
||||
{
|
||||
// The UniversalEntry value is a collection, so we have to copy all sub-elements
|
||||
UniversalCollection uc = new UniversalCollection();
|
||||
|
||||
foreach(UniversalEntry ie in (UniversalCollection)e.Value)
|
||||
uc.Add(ie.Key, ie.Value);
|
||||
|
||||
newset.UnknownUDMFData.Add(new UniversalEntry(e.Key, uc));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just a normal UniversalEntry
|
||||
newset.UnknownUDMFData.Add(new UniversalEntry(e.Key, e.Value));
|
||||
}
|
||||
}
|
||||
|
||||
// Return the new set
|
||||
newset.EndAddRemove();
|
||||
|
|
Loading…
Reference in a new issue