diff --git a/Documents/udmf10.txt b/Documents/udmf10.txt new file mode 100644 index 00000000..d9f0ff52 --- /dev/null +++ b/Documents/udmf10.txt @@ -0,0 +1,403 @@ +=============================================================================== +Universal Doom Map Format Specification v1.0 - 05/28/08 + +Written by James "Quasar" Haley - haleyjd@hotmail.com + +Defined with input from: + +CodeImp +esselfortium +Graf Zahl +Kaiser +SlayeR +SoM +et al. + + Copyright (c) 2008 James Haley. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.2 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + +=============================================================================== + +======================================= +I. Grammar / Syntax +======================================= + + translation_unit := global_expr_list + global_expr_list := global_expr global_expr_list + global_expr := block | assignment_expr + block := identifier '{' expr_list '}' + expr_list := assignment_expr expr_list + assignment_expr := identifier '=' value ';' | nil + identifier := [A-Za-z0-9_]+ + value := integer | float | quoted_string | keyword + integer := [+-]?[1-9]+[0-9]* | 0[0-9]+ | 0x[0-9A-Fa-f]+ + float := [+-]?[0-9]+'.'[0-9]*([eE][+-]?[0-9]+)? + quoted_string := "([^"\\]*(\\.[^"\\]*)*)" + keyword := [^{}();"'\n\t ]+ + + +Global assignments and named/indexed global blocks are the only top-level +entities supported. Whitespace is strictly ignored. + +Comments are supported as C-style single and multi-line comments: + + // single line comment + + /* + multi + line + comment + */ + +Multi-line comments may not be nested. + +Implementing editors are not required (but are allowed) to maintain syntactic +comments when rewriting UDMF map lumps. These comments are provided chiefly for +hand-writing and debugging purposes. + +Blocks begin with a keyword identifier. An example of a minimally-defined +entity follows: + + linedef { id = 1; } + +Compliant parsers will ignore all unknown keywords in global assignments, +block-level assignments, and block headers. Compliant parsers should attempt +to preserve as much of such information as is possible by using a flexible +mapping such as hashing. + +Identifiers and keywords are to be treated as case insensitive. + +A field which specifies "boolean" semantics shall accept keyword value +"true" to mean that the field is asserted, and keyword value "false" to +mean that the field is unasserted. Keyword values can only be defined in +this specification, and not by implementing ports. Use quoted strings +instead. + +Fields which do not appear in a block take on their default value. This +allows minimal specification. Note that the default values specified by +UDMF are not necessarily the default values which editors may wish to +apply to those fields during the creation of new entities during editing. +Such editing defaults are not part of this specification. + + +======================================= +II. Implementation Semantics +======================================= + +------------------------------------ +II.A : Storage and Retrieval of Data +------------------------------------ + +Block-defined entities are written and read in top-to-bottom order. For +example, the following linedefs can be assigned in order to a contiguous +block of memory serving as the implementing port's lines array: + + linedef { id = 1; } + linedef { id = 2; } + linedef { id = 3; } + linedef { id = 4; } + +Data types: + +For purposes of internal storage: +--------------------------------- +Integers should be considered signed with a range of at least 32 bits. +Floating-point numbers should be considered double precision. +Strings have no reasonable length limitations. + +Hard Data Type Limits +--------------------- +No limits on number of definitions are defined as part of this specification, +but implementors may face the need to impose such limitations due to +restrictions on the amount of memory available, or the amount that can be +allocated through a single pointer on the host machine or in a private heap +implementation. + +In the event that a map exceeds such an internal engine limitation, an +implementing port or editor should not continue to attempt loading the map, as +doing so could destabilize the program. + +----------------------------------- +II.B : Storage Within Archive Files +----------------------------------- + +UDMF maps shall be layed out within the archive directory as follows: + + (HEADER) + TEXTMAP + ... + ENDMAP + +(HEADER) = Any lump name from 1 to 8 characters. Serves as the name of the map. +TEXTMAP = Single UDMF lump containing all data for the map. +... = Blockmap, reject, BSP tree, and port-specific lumps, if any. The + format and presence of these resources are not defined by UDMF. +ENDMAP = Required closing lump. + +Implementing editors and source ports may distinguish a UDMF map from a +traditional binary map by testing the name of the first directory entry +following the map header. Implementing resource editors will be capable of +keeping all lumps for the map, even non-standard ones, together by properly +scanning for the ENDMAP entry. Non-implementing resource editors will not +recognize the sequence of lumps as a map, and may thus be less likely to +interfere with the order or presence of the lumps. + +Use of non-implementing resource editors to manipulate UDMF-map-containing WAD +files is not recommended, however. + + +-------------------------------- +II.C : Implementation Dependence +-------------------------------- + +A port's list of supported non-standard fields must be provided to implementing +editors, where they can be provided to the end user as controls, as options +in a dropbox, or through the ability to input any arbitrary +"identifier = value;" pair in a text box. + +Every UDMF map should contain as the first statement in the file the "namespace" +identifier statement, which declares the source port implementation relative to +which this map is to be interpreted. + +Example: + + namespace = "ZDoom"; + +Implementing source ports may ignore this information, or they may use it to +perform automatic runtime translation of maps they would otherwise be unable to +support. + +Implementing source ports should publicly document the value of the "namespace" +variable they intend to identify with when establishing support for UDMF, and +avoid conflicts with existing implementations at all costs. + +The following namespaces are considered reserved for compatibility purposes: + +Doom +Heretic +Hexen +Strife + +The use of one of these namespaces indicates that all line specials, sector +specials, thing types, and if applicable, thing specials contained in the UDMF +map conform to the "vanilla" types for the respective gamemode (with an +exception for Doom) and are therefore 100% compatible with all UDMF +implementors which support the specified gamemode. + +An exception is made for the "Doom" translation type. It is considered to +represent the final fork of the v1.9 Doom engine, and therefore it includes +all line types added in DOOM II. It is also additionally considered to +include all specials defined in the BOOM and MBF source ports. Implementors +who support BOOM linedef types can handle these in the normal manner; ports +which do not support them should zero or otherwise ignore the offending +specials. + +Documentation of the precise meanings of these standardized namespaces will +be provided in separate documents. + +This feature is provided in order to facilitate a universal and lossless +conversion of all existing Doom-engine-game maps to and from UDMF format, +independent of any implementing ports' specific namespaces. + + +======================================= +III. Standardized Fields +======================================= + +The UDMF v1.0 specification considers the following fields standard. They must +be recognized by all implementing ports and editors (support for the features +they signify is not necessarily required, such as for ports which do not +implement Hexen support - all fields unknown to a given port should be +ignored and not treated as an error). + + linedef + { + id = ; // ID of line. Interpreted as tag or scripting id. + // Default = -1. *** see below. + + v1 = ; // Index of first vertex. No valid default. + v2 = ; // Index of second vertex. No valid default. + + // All flags default to false. + + blocking = ; // true = line blocks things. + blockmonsters = ; // true = line blocks monsters. + twosided = ; // true = line is 2S. + dontpegtop = ; // true = upper texture unpegged. + dontpegbottom = ; // true = lower texture unpegged. + secret = ; // true = drawn as 1S on map. + blocksound = ; // true = blocks sound. + dontdraw = ; // true = line never drawn on map. + mapped = ; // true = always appears on map. + + // BOOM passuse flag not supported in Strife/Heretic/Hexen namespaces. + + passuse = ; // true = passes use action. + + // Strife specific flags. Support for other games is not defined by + // default and these flags should be ignored when reading maps not for + // the Strife namespace or maps for a port which supports these flags. + + translucent = ; // true = line is a Strife translucent line. + jumpover = ; // true = line is a Strife railing. + blockfloaters = ; // true = line is a Strife float-blocker. + + // Note: SPAC flags should be set false in Doom/Heretic/Strife + // namespace maps. Specials in those games do not support this + // mechanism and instead imply activation parameters through the + // special number. All flags default to false. + + playercross = ; // true = player can cross. + playeruse = ; // true = player can use. + monstercross = ; // true = monster can cross. + monsteruse = ; // true = monster can use. + impact = ; // true = projectile can activate. + playerpush = ; // true = player can push. + monsterpush = ; // true = monster can push. + missilecross = ; // true = projectile can cross. + repeatspecial = ; // true = repeatable special. + + special = ; // Special. Default = 0. + arg0 = ; // Argument 0. Default = 0. + arg1 = ; // Argument 1. Default = 0. + arg2 = ; // Argument 2. Default = 0. + arg3 = ; // Argument 3. Default = 0. + arg4 = ; // Argument 4. Default = 0. + + sidefront = ; // Sidedef 1 index. No valid default. + sideback = ; // Sidedef 2 index. Default = -1. + + comment = ; // A comment. Implementors should attach no special + // semantic meaning to this field. + } + + sidedef + { + offsetx = ; // X Offset. Default = 0. + offsety = ; // Y Offset. Default = 0. + + texturetop = ; // Upper texture. Default = "-". + texturebottom = ; // Lower texture. Default = "-". + texturemiddle = ; // Middle texture. Default = "-". + + sector = ; // Sector index. No valid default. + + comment = ; // A comment. Implementors should attach no special + // semantic meaning to this field. + } + + vertex + { + x = ; // X coordinate. No valid default. + y = ; // Y coordinate. No valid default. + } + + sector + { + heightfloor = ; // Floor height. Default = 0. + heightceiling = ; // Ceiling height. Default = 0. + + texturefloor = ; // Floor flat. No valid default. + textureceiling = ; // Ceiling flat. No valid default. + + lightlevel = ; // Light level. Default = 160. + + special = ; // Sector special. Default = 0. + id = ; // Sector tag/id. Default = 0. + + comment = ; // A comment. Implementors should attach no special + // semantic meaning to this field. + } + + thing + { + id = ; // Thing ID. Default = 0. + + x = ; // X coordinate. No valid default. + y = ; // Y coordinate. No valid default. + + height = ; // Z height relative to floor. Default = 0. + // (Relative to ceiling for SPAWNCEILING items). + + angle = ; // Map angle of thing in degrees. Default = 0 (East). + + type = ; // DoomedNum. No valid default. + + // All flags default to false. + + skill1 = ; // true = in skill 1. + skill2 = ; // true = in skill 2. + skill3 = ; // true = in skill 3. + skill4 = ; // true = in skill 4. + skill5 = ; // true = in skill 5. + ambush = ; // true = thing is deaf. + single = ; // true = in SP mode. + dm = ; // true = in DM mode. + coop = ; // true = in Coop. + + // MBF friend flag not supported in Strife/Heretic/Hexen namespaces. + + friend = ; // true = MBF friend. + + // Hexen flags; not supported in Doom/Strife/Heretic namespaces. + + dormant = ; // true = dormant thing. + class1 = ; // true = Present for pclass 1. + class2 = ; // true = Present for pclass 2. + class3 = ; // true = Present for pclass 3. + + + // Strife specific flags. Support for other games is not defined by + // default and these flags should be ignored when reading maps not for + // the Strife namespace or maps for a port which supports these flags. + standing = ; // true = Strife NPC flag. + strifeally = ; // true = Strife ally flag. + translucent = ; // true = Strife translucency flag. + invisible = ; // true = Strife invisibility flag. + + // Note: suggested editor defaults for all skill, gamemode, and player + // class flags is true rather than the UDMF default of false. + + // Thing special semantics are only defined for the Hexen namespace or + // ports which implement this feature in their own namespace. + + special = ; // Scripting special. Default = 0; + arg0 = ; // Argument 0. Default = 0. + arg1 = ; // Argument 1. Default = 0. + arg2 = ; // Argument 2. Default = 0. + arg3 = ; // Argument 3. Default = 0. + arg4 = ; // Argument 4. Default = 0. + + comment = ; // A comment. Implementors should attach no special + // semantic meaning to this field. + } + + +*** Tag / ID Behavior for Map Conversion: + + Unlike traditional Doom maps UDMF makes a clear distinction between a line's + ID and the parameter which identifies the object the line's special is + supposed to affect. + + The id will be used to identify this line, and arg0 will be used to identify + the line or sector that this line is to affect or otherwise reference, i.e. + it is effectively a parameter to the line's special. + + Boom used the linedef's tag for both due to lack of other options so in + order to ensure compatibility any map converter converting maps for the + Doom/Heretic/Strife namespaces must store the linedef's tag field as both + the id and as arg0 in each line. The default value of the id field under + these namespaces is defined as 0 rather than -1. + + Since UDMF provides a line id field, the Hexen line special #121 + (Line_SetIdentification) is obsolete. When converting maps to UDMF under + Hexen namespace, special 121 should be written as zero, and the arg0 of + the binary linedef should be written as the id field of the UDMF line. + The arg0 value of the UDMF line should also then be set to zero. + +=============================================================================== +EOF +=============================================================================== diff --git a/Source/Builder.csproj b/Source/Builder.csproj index 3925fae4..7964d85d 100644 --- a/Source/Builder.csproj +++ b/Source/Builder.csproj @@ -124,6 +124,9 @@ + + + diff --git a/Source/Editing/ThingsFilter.cs b/Source/Editing/ThingsFilter.cs index b9e21d6d..a51e8b31 100644 --- a/Source/Editing/ThingsFilter.cs +++ b/Source/Editing/ThingsFilter.cs @@ -211,7 +211,7 @@ namespace CodeImp.DoomBuilder.Editing { if(t.Fields[s] is bool) { - if((bool)t.Fields[s] == false) + if((bool)t.Fields[s].Value == false) { qualifies = false; break; @@ -236,7 +236,7 @@ namespace CodeImp.DoomBuilder.Editing { if(t.Fields[s] is bool) { - if((bool)t.Fields[s] == true) + if((bool)t.Fields[s].Value == true) { qualifies = false; break; diff --git a/Source/Map/Linedef.cs b/Source/Map/Linedef.cs index 384b080c..5f545ebd 100644 --- a/Source/Map/Linedef.cs +++ b/Source/Map/Linedef.cs @@ -30,7 +30,7 @@ using System.Drawing; namespace CodeImp.DoomBuilder.Map { - public sealed class Linedef + public sealed class Linedef : MapElement { #region ================== Constants @@ -73,15 +73,9 @@ namespace CodeImp.DoomBuilder.Map private int tag; private int[] args; - // Additional fields - private SortedList fields; - // Selections private bool selected; private bool marked; - - // Disposing - private bool isdisposed = false; #endregion @@ -92,7 +86,6 @@ namespace CodeImp.DoomBuilder.Map public Vertex End { get { return end; } } public Sidedef Front { get { return front; } } public Sidedef Back { get { return back; } } - public bool IsDisposed { get { return isdisposed; } } public Line2D Line { get { return new Line2D(start.Position, end.Position); } } public int Flags { get { return flags; } set { flags = value; } } public int Action { get { return action; } set { action = value; } } @@ -106,7 +99,6 @@ namespace CodeImp.DoomBuilder.Map public int AngleDeg { get { return (int)(angle * Angle2D.PIDEG); } } public RectangleF Rect { get { return rect; } } public int[] Args { get { return args; } } - public SortedList Fields { get { return fields; } } #endregion @@ -132,7 +124,7 @@ namespace CodeImp.DoomBuilder.Map } // Disposer - public void Dispose() + public override void Dispose() { // Not already disposed? if(!isdisposed) @@ -160,6 +152,9 @@ namespace CodeImp.DoomBuilder.Map front = null; back = null; map = null; + + // Clean up base + base.Dispose(); } } @@ -198,8 +193,8 @@ namespace CodeImp.DoomBuilder.Map l.flags = flags; l.tag = tag; l.updateneeded = true; - if(fields != null) l.MakeFields(fields); l.selected = selected; + CopyFieldsTo(l); } // This attaches a sidedef on the front @@ -288,23 +283,6 @@ namespace CodeImp.DoomBuilder.Map if(back != null) back.Sector.UpdateNeeded = true; } - #endregion - - #region ================== Fields - - // This makes new fields - public void MakeFields() - { - if(fields != null) fields = new SortedList(); - } - - // This makes fields from another list of fields - public void MakeFields(SortedList copyfrom) - { - if(fields != null) fields = new SortedList(); - foreach(KeyValuePair f in copyfrom) fields[f.Key] = f.Value; - } - #endregion #region ================== Methods diff --git a/Source/Map/MapElement.cs b/Source/Map/MapElement.cs new file mode 100644 index 00000000..9279898c --- /dev/null +++ b/Source/Map/MapElement.cs @@ -0,0 +1,90 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using CodeImp.DoomBuilder.Geometry; +using CodeImp.DoomBuilder.Rendering; +using SlimDX.Direct3D9; +using System.Drawing; + +#endregion + +namespace CodeImp.DoomBuilder.Map +{ + public abstract class MapElement : IDisposable + { + #region ================== Constants + + #endregion + + #region ================== Variables + + // Univeral fields + private UniFields fields; + + // Disposing + protected bool isdisposed = false; + + #endregion + + #region ================== Properties + + public UniFields Fields { get { return fields; } } + public bool IsDisposed { get { return isdisposed; } } + + #endregion + + #region ================== Constructor / Disposer + + // Constructor + internal MapElement() + { + // Initialize + fields = new UniFields(); + } + + // Disposer + public virtual void Dispose() + { + if(!isdisposed) + { + // Clean up + fields = null; + + // Done + isdisposed = true; + } + } + + #endregion + + #region ================== Fields + + // This copies fields to any other element + protected void CopyFieldsTo(MapElement element) + { + element.fields = new UniFields(this.fields); + } + + #endregion + } +} diff --git a/Source/Map/Sector.cs b/Source/Map/Sector.cs index 9d721a13..12237692 100644 --- a/Source/Map/Sector.cs +++ b/Source/Map/Sector.cs @@ -30,7 +30,7 @@ using CodeImp.DoomBuilder.Rendering; namespace CodeImp.DoomBuilder.Map { - public sealed class Sector + public sealed class Sector : MapElement { #region ================== Constants @@ -75,12 +75,6 @@ namespace CodeImp.DoomBuilder.Map private TriangleList triverts; private FlatVertex[] vertices; - // Additional fields - private SortedList fields; - - // Disposing - private bool isdisposed = false; - #endregion #region ================== Properties @@ -88,7 +82,6 @@ namespace CodeImp.DoomBuilder.Map public MapSet Map { get { return map; } } public ICollection Sidedefs { get { return sidedefs; } } public ICollection Things { get { return things; } } - public bool IsDisposed { get { return isdisposed; } } public int Index { get { return index; } } public int FloorHeight { get { return floorheight; } set { floorheight = value; } } public int CeilHeight { get { return ceilheight; } set { ceilheight = value; } } @@ -104,7 +97,6 @@ namespace CodeImp.DoomBuilder.Map public bool UpdateNeeded { get { return updateneeded; } set { updateneeded |= value; triangulationneeded |= value; } } public Sector Clone { get { return clone; } set { clone = value; } } public FlatVertex[] Vertices { get { return vertices; } } - public SortedList Fields { get { return fields; } } #endregion @@ -129,7 +121,7 @@ namespace CodeImp.DoomBuilder.Map } // Disposer - public void Dispose() + public override void Dispose() { // Not already disposed? if(!isdisposed) @@ -152,6 +144,9 @@ namespace CodeImp.DoomBuilder.Map sidedefs = null; things = null; map = null; + + // Dispose base + base.Dispose(); } } @@ -172,9 +167,9 @@ namespace CodeImp.DoomBuilder.Map s.effect = effect; s.tag = tag; s.brightness = brightness; - if(fields != null) s.MakeFields(fields); s.selected = selected; s.updateneeded = true; + CopyFieldsTo(s); } // This attaches a sidedef and returns the listitem @@ -250,23 +245,6 @@ namespace CodeImp.DoomBuilder.Map #endregion - #region ================== Fields - - // This makes new fields - public void MakeFields() - { - if(fields != null) fields = new SortedList(); - } - - // This makes fields from another list of fields - public void MakeFields(SortedList copyfrom) - { - if(fields != null) fields = new SortedList(); - foreach(KeyValuePair f in copyfrom) fields[f.Key] = f.Value; - } - - #endregion - #region ================== Methods // This joins the sector with another sector diff --git a/Source/Map/Sidedef.cs b/Source/Map/Sidedef.cs index 27ffbe3a..2b1cf773 100644 --- a/Source/Map/Sidedef.cs +++ b/Source/Map/Sidedef.cs @@ -28,7 +28,7 @@ using CodeImp.DoomBuilder.Geometry; namespace CodeImp.DoomBuilder.Map { - public sealed class Sidedef + public sealed class Sidedef : MapElement { #region ================== Constants @@ -59,14 +59,8 @@ namespace CodeImp.DoomBuilder.Map private long longtexnamemid; private long longtexnamelow; - // Additional fields - private SortedList fields; - // Selections private bool marked; - - // Disposing - private bool isdisposed = false; #endregion @@ -77,7 +71,6 @@ namespace CodeImp.DoomBuilder.Map public Linedef Line { get { return linedef; } } public Sidedef Other { get { if(this == linedef.Front) return linedef.Back; else return linedef.Front; } } public Sector Sector { get { return sector; } } - public bool IsDisposed { get { return isdisposed; } } public float Angle { get { if(IsFront) return linedef.Angle; else return Angle2D.Normalized(linedef.Angle + Angle2D.PI); } } public int OffsetX { get { return offsetx; } set { offsetx = value; } } public int OffsetY { get { return offsety; } set { offsety = value; } } @@ -88,7 +81,6 @@ namespace CodeImp.DoomBuilder.Map public long LongMiddleTexture { get { return longtexnamemid; } } public long LongLowTexture { get { return longtexnamelow; } } public bool Marked { get { return marked; } set { marked = value; } } - public SortedList Fields { get { return fields; } } #endregion @@ -120,7 +112,7 @@ namespace CodeImp.DoomBuilder.Map } // Disposer - public void Dispose() + public override void Dispose() { // Not already disposed? if(!isdisposed) @@ -143,6 +135,9 @@ namespace CodeImp.DoomBuilder.Map linedef = null; map = null; sector = null; + + // Dispose base + base.Dispose(); } } @@ -162,7 +157,7 @@ namespace CodeImp.DoomBuilder.Map s.longtexnamehigh = longtexnamehigh; s.longtexnamemid = longtexnamemid; s.longtexnamelow = longtexnamelow; - if(fields != null) s.MakeFields(fields); + CopyFieldsTo(s); } // This copies textures to another sidedef @@ -216,23 +211,6 @@ namespace CodeImp.DoomBuilder.Map } } - #endregion - - #region ================== Fields - - // This makes new fields - public void MakeFields() - { - if(fields != null) fields = new SortedList(); - } - - // This makes fields from another list of fields - public void MakeFields(SortedList copyfrom) - { - if(fields != null) fields = new SortedList(); - foreach(KeyValuePair f in copyfrom) fields[f.Key] = f.Value; - } - #endregion #region ================== Methods diff --git a/Source/Map/Thing.cs b/Source/Map/Thing.cs index 7ef289ff..b54cf91a 100644 --- a/Source/Map/Thing.cs +++ b/Source/Map/Thing.cs @@ -30,7 +30,7 @@ using System.Drawing; namespace CodeImp.DoomBuilder.Map { - public sealed class Thing + public sealed class Thing : MapElement { #region ================== Constants @@ -70,12 +70,6 @@ namespace CodeImp.DoomBuilder.Map private bool selected; private bool marked; - // Additional fields - private SortedList fields; - - // Disposing - private bool isdisposed = false; - #endregion #region ================== Properties @@ -83,7 +77,6 @@ namespace CodeImp.DoomBuilder.Map public MapSet Map { get { return map; } } public int Type { get { return type; } set { type = value; } } public Vector3D Position { get { return pos; } } - public bool IsDisposed { get { return isdisposed; } } public float Angle { get { return angle; } } public int AngleDeg { get { return (int)Angle2D.RadToDeg(angle); } } public int Flags { get { return flags; } set { flags = value; } } @@ -99,7 +92,6 @@ namespace CodeImp.DoomBuilder.Map public int ZOffset { get { return zoffset; } set { zoffset = value; } } public int Tag { get { return tag; } set { tag = value; if((tag < 0) || (tag > MapSet.HIGHEST_TAG)) throw new ArgumentOutOfRangeException("Tag", "Invalid tag number"); } } public Sector Sector { get { return sector; } } - public SortedList Fields { get { return fields; } } #endregion @@ -117,7 +109,7 @@ namespace CodeImp.DoomBuilder.Map } // Disposer - public void Dispose() + public override void Dispose() { // Not already disposed? if(!isdisposed) @@ -136,6 +128,9 @@ namespace CodeImp.DoomBuilder.Map sectorlistitem = null; map = null; sector = null; + + // Dispose base + base.Dispose(); } } @@ -161,8 +156,8 @@ namespace CodeImp.DoomBuilder.Map t.color = color; t.iconoffset = iconoffset; args.CopyTo(t.args, 0); - if(fields != null) t.MakeFields(fields); t.selected = selected; + CopyFieldsTo(t); } // This determines which sector the thing is in and links it @@ -206,23 +201,6 @@ namespace CodeImp.DoomBuilder.Map } } - #endregion - - #region ================== Fields - - // This makes new fields - public void MakeFields() - { - if(fields != null) fields = new SortedList(); - } - - // This makes fields from another list of fields - public void MakeFields(SortedList copyfrom) - { - if(fields != null) fields = new SortedList(); - foreach(KeyValuePair f in copyfrom) fields[f.Key] = f.Value; - } - #endregion #region ================== Changes diff --git a/Source/Map/UniFields.cs b/Source/Map/UniFields.cs new file mode 100644 index 00000000..b81c4669 --- /dev/null +++ b/Source/Map/UniFields.cs @@ -0,0 +1,25 @@ +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; + +#endregion + +namespace CodeImp.DoomBuilder.Map +{ + public class UniFields : SortedList + { + // New constructor + public UniFields() : base(2) + { + } + + // Copy constructor + public UniFields(UniFields copyfrom) : base(copyfrom) + { + } + } +} diff --git a/Source/Map/UniValue.cs b/Source/Map/UniValue.cs new file mode 100644 index 00000000..7791dd8a --- /dev/null +++ b/Source/Map/UniValue.cs @@ -0,0 +1,85 @@ + +#region ================== Copyright (c) 2007 Pascal vd Heiden + +/* + * Copyright (c) 2007 Pascal vd Heiden, www.codeimp.com + * This program is released under GNU General Public License + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#endregion + +#region ================== Namespaces + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using System.Text; +using CodeImp.DoomBuilder.Geometry; +using CodeImp.DoomBuilder.Rendering; +using SlimDX.Direct3D9; +using System.Drawing; +using CodeImp.DoomBuilder.Types; + +#endregion + +namespace CodeImp.DoomBuilder.Map +{ + public class UniValue + { + #region ================== Constants + + #endregion + + #region ================== Variables + + private object value; + private int type; + + #endregion + + #region ================== Properties + + public object Value + { + get + { + return this.value; + } + + set + { + // Value may only be a primitive type + if(!(value is int) || !(value is float) || !(value is string) || !(value is bool)) + throw new ArgumentException("Universal field values can only be of type int, float, string or bool."); + + this.value = value; + } + } + + public int Type { get { return this.type; } set { this.type = value; } } + + #endregion + + #region ================== Constructor + + // Constructor + public UniValue() + { + // We have no destructor + GC.SuppressFinalize(this); + } + + #endregion + + #region ================== Methods + + #endregion + } +} diff --git a/Source/Map/Vertex.cs b/Source/Map/Vertex.cs index bf9bcc9d..6d9f8b21 100644 --- a/Source/Map/Vertex.cs +++ b/Source/Map/Vertex.cs @@ -30,7 +30,7 @@ using System.Drawing; namespace CodeImp.DoomBuilder.Map { - public sealed class Vertex + public sealed class Vertex : MapElement { #region ================== Constants @@ -60,12 +60,6 @@ namespace CodeImp.DoomBuilder.Map // Cloning private Vertex clone; - // Additional fields - private SortedList fields; - - // Disposing - private bool isdisposed = false; - #endregion #region ================== Properties @@ -73,11 +67,9 @@ namespace CodeImp.DoomBuilder.Map public MapSet Map { get { return map; } } public ICollection Linedefs { get { return linedefs; } } public Vector2D Position { get { return pos; } } - public bool IsDisposed { get { return isdisposed; } } public bool Selected { get { return selected; } set { selected = value; } } public bool Marked { get { return marked; } set { marked = value; } } public Vertex Clone { get { return clone; } set { clone = value; } } - public SortedList Fields { get { return fields; } } #endregion @@ -97,7 +89,7 @@ namespace CodeImp.DoomBuilder.Map } // Disposer - public void Dispose() + public override void Dispose() { // Not already disposed? if(!isdisposed) @@ -116,6 +108,9 @@ namespace CodeImp.DoomBuilder.Map linedefs = null; mainlistitem = null; map = null; + + // Dispose base + base.Dispose(); } } @@ -144,23 +139,6 @@ namespace CodeImp.DoomBuilder.Map } } - #endregion - - #region ================== Fields - - // This makes new fields - public void MakeFields() - { - if(fields != null) fields = new SortedList(); - } - - // This makes fields from another list of fields - public void MakeFields(SortedList copyfrom) - { - if(fields != null) fields = new SortedList(); - foreach(KeyValuePair f in copyfrom) fields[f.Key] = f.Value; - } - #endregion #region ================== Methods @@ -170,8 +148,8 @@ namespace CodeImp.DoomBuilder.Map { // Copy properties v.pos = pos; - if(fields != null) v.MakeFields(fields); v.selected = selected; + CopyFieldsTo(v); } // This returns the distance from given coordinates