diff --git a/Build/Configurations/Doom2.cfg b/Build/Configurations/Doom2.cfg
index a951b5ac..1f20e04d 100644
--- a/Build/Configurations/Doom2.cfg
+++ b/Build/Configurations/Doom2.cfg
@@ -205,6 +205,74 @@ maplumpnames
}
+/*
+ADDITIONAL UNIVERSAL DOOM MAP FORMAT FIELD DEFINITIONS
+Only add fields here that Doom Builder does not edit with its own user-interface!
+
+Field types:
+0 = integer
+1 = float
+2 = string
+3 = linedef action
+4 = sector effect
+5 = texture
+6 = flat
+*/
+universalfields
+{
+ linedefs
+ {
+ texture_scale_x
+ {
+ type = 1;
+ default = 1.0f;
+ }
+
+ texture_scale_y
+ {
+ type = 1;
+ default = 1.0f;
+ }
+
+ texture_offset_x
+ {
+ type = 1;
+ default = 0.0f;
+ }
+
+ texture_offset_y
+ {
+ type = 1;
+ default = 0.0f;
+ }
+
+ brightness
+ {
+ type = 0;
+ default = -1;
+ }
+
+ colormap
+ {
+ type = 2;
+ default = "";
+ }
+
+ normalmap
+ {
+ type = 5;
+ default = "STARTAN3";
+ }
+
+ second_action
+ {
+ type = 3;
+ default = 0;
+ }
+ }
+}
+
+
// DEFAULT SECTOR BRIGHTNESS LEVELS
sectorbrightness
{
diff --git a/Build/Configurations/Eternity_DoomUDMF.cfg b/Build/Configurations/Eternity_DoomUDMF.cfg
new file mode 100644
index 00000000..1306e0b1
--- /dev/null
+++ b/Build/Configurations/Eternity_DoomUDMF.cfg
@@ -0,0 +1,2102 @@
+/*************************************************************\
+ Doom Builder Game Configuration for Eternity
+\*************************************************************/
+
+// This is required to prevent accedential use of a different configuration
+type = "Doom Builder 2 Game Configuration";
+
+// This is the title to show for this game
+game = "Eternity (Doom in UDMF format)";
+
+// The format interface handles the map data format
+formatinterface = "UniversalMapSetIO";
+
+// Special linedefs
+soundlinedefflags = 64; // See linedefflags
+singlesidedflags = 1; // See linedefflags
+doublesidedflags = 4; // See linedefflags
+impassableflags = 1;
+
+// Generalized actions
+generalizedlinedefs = true;
+generalizedsectors = true;
+
+// Texture loading options
+mixtexturesflats = false;
+defaulttexturescale = 1.0f;
+defaultflatscale = 1.0f;
+
+// Thing number for start position in 3D Mode
+start3dmode = 32000;
+
+// Default flags for first new thing
+defaulthingflags = 7; //1 + 2 + 4
+
+
+/*
+TEXTURES AND FLAT SOURCES
+This tells Doom Builder where to find the information for textures
+and flats in the IWAD file, Addition WAD file and Map WAD file.
+
+Start and end lumps must be given in a structure (of which the
+key name doesnt matter) and any textures or flats in between them
+are loaded in either the textures category or flats category.
+
+For textures: PNAMES, TEXTURE1 and TEXTURE2 are loaded by default.
+*/
+
+// Texture sources
+textures
+{
+}
+
+// Flat sources
+flats
+{
+ standard1
+ {
+ start = "F_START";
+ end = "F_END";
+ }
+
+ standard2
+ {
+ start = "FF_START";
+ end = "FF_END";
+ }
+
+ standard3
+ {
+ start = "FF_START";
+ end = "F_END";
+ }
+
+ standard4
+ {
+ start = "F_START";
+ end = "FF_END";
+ }
+}
+
+
+/*
+GAME DETECT PATTERN
+Used to guess the game for which a WAD file is made.
+
+1 = One of these lumps must exist
+2 = None of these lumps must exist
+3 = All of these lumps must exist
+*/
+
+gamedetect
+{
+ EXTENDED = 2;
+ BEHAVIOR = 2;
+ E1M1 = 2; E1M2 = 2; E1M3 = 2; E1M4 = 2; E1M5 = 2; E1M6 = 2; E1M7 = 2; E1M8 = 2; E1M9 = 2;
+ E2M1 = 2; E2M2 = 2; E2M3 = 2; E2M4 = 2; E2M5 = 2; E2M6 = 2; E2M7 = 2; E2M8 = 2; E2M9 = 2;
+ E3M1 = 2; E3M2 = 2; E3M3 = 2; E3M4 = 2; E3M5 = 2; E3M6 = 2; E3M7 = 2; E3M8 = 2; E3M9 = 2;
+ E4M1 = 2; E4M2 = 2; E4M3 = 2; E4M4 = 2; E4M5 = 2; E4M6 = 2; E4M7 = 2; E4M8 = 2; E4M9 = 2;
+ MAP01 = 1; MAP02 = 1; MAP03 = 1; MAP04 = 1; MAP05 = 1; MAP06 = 1; MAP07 = 1; MAP08 = 1; MAP09 = 1; MAP10 = 1;
+ MAP11 = 1; MAP12 = 1; MAP13 = 1; MAP14 = 1; MAP15 = 1; MAP16 = 1; MAP17 = 1; MAP18 = 1; MAP19 = 1; MAP20 = 1;
+ MAP21 = 1; MAP22 = 1; MAP23 = 1; MAP24 = 1; MAP25 = 1; MAP26 = 1; MAP27 = 1; MAP28 = 1; MAP29 = 1; MAP30 = 1;
+ MAP31 = 1; MAP32 = 1; MAP33 = 2; MAP34 = 2; MAP35 = 2; MAP36 = 2; MAP37 = 2; MAP38 = 2; MAP39 = 2; MAP40 = 2;
+ MAP41 = 2;
+}
+
+
+/*
+MAP LUMP NAMES
+Map lumps are loaded with the map as long as they are right after each other. When the editor
+meets a lump which is not defined in this list it will ignore the map if not satisfied.
+The order of items defines the order in which lumps will be written to WAD file on save.
+To indicate the map header lump, use ~MAP
+
+Legenda:
+required = Lump is required to exist.
+blindcopy = Lump will be copied along with the map blindly. (usefull for lumps Doom Builder doesn't use)
+nodebuild = The nodebuilder generates this lump.
+allowempty = The nodebuilder is allowed to leave this lump empty.
+script = This lump is a text-based script. Specify the filename of the script configuration to use.
+*/
+
+maplumpnames
+{
+ ~MAP
+ {
+ required = true;
+ blindcopy = true;
+ nodebuild = false;
+ }
+
+ TEXTMAP
+ {
+ required = true;
+ nodebuild = true;
+ allowempty = true;
+ }
+
+ SEGS
+ {
+ required = false;
+ nodebuild = true;
+ allowempty = false;
+ }
+
+ SSECTORS
+ {
+ required = false;
+ nodebuild = true;
+ allowempty = false;
+ }
+
+ NODES
+ {
+ required = false;
+ nodebuild = true;
+ allowempty = false;
+ }
+
+ SECTORS
+ {
+ required = true;
+ nodebuild = true;
+ allowempty = false;
+ }
+
+ REJECT
+ {
+ required = false;
+ nodebuild = true;
+ allowempty = false;
+ }
+
+ BLOCKMAP
+ {
+ required = false;
+ nodebuild = true;
+ allowempty = false;
+ }
+
+ ENDMAP
+ {
+ required = true;
+ nodebuild = false;
+ allowempty = true;
+ blindcopy = true;
+ }
+}
+
+
+/*
+ADDITIONAL UNIVERSAL DOOM MAP FORMAT FIELD DEFINITIONS
+Only add fields here that Doom Builder does not edit with its own user-interface!
+
+Field types:
+0 = integer
+1 = float
+2 = string
+3 = action (linedeftype)
+4 = sectoreffect
+5 = texture
+6 = flat
+*/
+universalfields
+{
+ linedefs
+ {
+ texture_scale_x
+ {
+ type = 1;
+ default = 1.0f;
+ }
+
+ texture_scale_y
+ {
+ type = 1;
+ default = 1.0f;
+ }
+
+ texture_offset_x
+ {
+ type = 1;
+ default = 0.0f;
+ }
+
+ texture_offset_y
+ {
+ type = 1;
+ default = 0.0f;
+ }
+
+ brightness
+ {
+ type = 0;
+ default = -1;
+ }
+
+ colormap
+ {
+ type = 2;
+ default = "";
+ }
+
+ normalmap
+ {
+ type = 5;
+ default = "";
+ }
+
+ second_action
+ {
+ type = 3;
+ default = 0;
+ }
+ }
+}
+
+
+// DEFAULT SECTOR BRIGHTNESS LEVELS
+sectorbrightness
+{
+ 255;
+ 240;
+ 224;
+ 208;
+ 192;
+ 176;
+ 160;
+ 144;
+ 128;
+ 112;
+ 96;
+ 80;
+ 64;
+ 48;
+ 32;
+ 16;
+ 0;
+}
+
+// SECTOR TYPES
+sectortypes
+{
+ 0 = "Normal";
+ 1 = "Light Blinks (randomly)";
+ 2 = "Light Blinks (0.5 sec)";
+ 3 = "Light Blinks (1 sec)";
+ 4 = "Damage -10 or 20% health and Light Blinks (0.5 sec)";
+ 5 = "Damage -5 or 10% health";
+ 7 = "Damage -2 or 5% health";
+ 8 = "Light Glows (1+ sec)";
+ 9 = "Secret";
+ 10 = "Door Close Stay (after 30 sec)";
+ 11 = "Damage -10 or 20% health and End level";
+ 12 = "Light Blinks (0.5 sec sync)";
+ 13 = "Light Blinks (1 sec sync)";
+ 14 = "Door Open Stay (after 300 sec)";
+ 16 = "Damage -10 or 20% health";
+ 17 = "Light Flickers (randomly)";
+}
+
+// GENERALIZED SECTOR TYPES
+gen_sectortypes
+{
+ lighting
+ {
+ 0 = "Normal";
+ 1 = "Light Blinks (randomly)";
+ 2 = "Light Blinks (0.5 sec)";
+ 3 = "Light Blinks (1 sec)";
+ 4 = "Light Blinks (0.5 sec) and Damage 10 or 20";
+ 8 = "Light Glows (1+ sec)";
+ 12 = "Light Blinks (0.5 sec sync)";
+ 13 = "Light Blinks (1 sec sync)";
+ 17 = "Light Flickers (randomly)";
+ }
+
+ damage
+ {
+ 0 = "None";
+ 32 = "Damage 5 per second";
+ 64 = "Damage 10 per second";
+ 96 = "Damage 20 per second";
+ }
+
+ secret
+ {
+ 0 = "No";
+ 128 = "Yes";
+ }
+
+ friction
+ {
+ 0 = "Disabled";
+ 256 = "Enabled";
+ }
+
+ wind
+ {
+ 0 = "Disabled";
+ 512 = "Enabled";
+ }
+
+ sounds
+ {
+ 0 = "Normal";
+ 1024 = "Suppressed";
+ }
+
+ noise
+ {
+ 0 = "Normal";
+ 2048 = "Silent";
+ }
+}
+
+// LINEDEF FLAGS
+linedefflags
+{
+ 1 = "Impassable";
+ 2 = "Block Monster";
+ 4 = "Double Sided";
+ 8 = "Upper Unpegged";
+ 16 = "Lower Unpegged";
+ 32 = "Secret";
+ 64 = "Block Sound";
+ 128 = "Hidden";
+ 256 = "Shown";
+ 512 = "PassThru";
+ 1024 = "3dMidTex";
+}
+
+// LINEDEF ACTIVATIONS
+linedefactivations
+{
+}
+
+// LINEDEF TYPES
+// [type] [category] [description]
+// i know this should be done the same way as the things types,
+// but hey, are you willing to reformat the linedef types for each config?
+linedeftypes
+{
+ 0 = " None";
+ 1 = "DR Door Open Wait Close (also monsters)";
+ 2 = "W1 Door Open Stay";
+ 3 = "W1 Door Close Stay";
+ 4 = "W1 Door Open Wait Close";
+ 5 = "W1 Floor Raise to Lowest Ceiling";
+ 6 = "W1 Crusher Start with Fast Damage";
+ 7 = "S1 Stairs Raise by 8";
+ 8 = "W1 Stairs Raise by 8";
+ 9 = "S1 Floor Raise Donut (changes texture)";
+ 10 = "W1 Lift Lower Wait Raise";
+ 11 = "S1 Exit Level";
+ 12 = "W1 Light Change to Brightest Adjacent";
+ 13 = "W1 Light Change to 255";
+ 14 = "S1 Floor Raise by 32 (changes texture)";
+ 15 = "S1 Floor Raise by 24 (changes texture)";
+ 16 = "W1 Door Close Wait Open";
+ 17 = "W1 Light Start Blinking";
+ 18 = "S1 Floor Raise to Next Higher Floor";
+ 19 = "W1 Floor Lower to Highest Floor";
+ 20 = "S1 Floor Raise to Next Higher Floor (changes texture)";
+ 21 = "S1 Lift Lower Wait Raise";
+ 22 = "W1 Floor Raise to Next Higher Floor (changes texture)";
+ 23 = "S1 Floor Lower to Lowest Floor";
+ 24 = "G1 Floor Raise to Lowest Ceiling";
+ 25 = "W1 Crusher Start with Slow Damage";
+ 26 = "DR Door (Blue) Open Wait Close";
+ 27 = "DR Door (Yellow) Open Wait Close";
+ 28 = "DR Door (Red) Open Wait Close";
+ 29 = "S1 Door Open Wait Close";
+ 30 = "W1 Floor Raise by Shortest Lower Texture";
+ 31 = "D1 Door Open Stay";
+ 32 = "D1 Door (Blue) Open Stay";
+ 33 = "D1 Door (Red) Open Stay";
+ 34 = "D1 Door (Yellow) Open Stay";
+ 35 = "W1 Light Change to 35";
+ 36 = "W1 Floor Lower to 8 above Highest Floor";
+ 37 = "W1 Floor Lower to Lowest Floor (changes texture)";
+ 38 = "W1 Floor Lower to Lowest Floor";
+ 39 = "W1 Teleport";
+ 40 = "W1 Ceiling Raise to Highest Ceiling";
+ 41 = "S1 Ceiling Lower to Floor";
+ 42 = "SR Door Close Stay";
+ 43 = "SR Ceiling Lower to Floor";
+ 44 = "W1 Ceiling Lower to 8 above Floor";
+ 45 = "SR Floor Lower to Highest Floor";
+ 46 = "GR Door Open Stay";
+ 47 = "G1 Floor Raise to Next Higher Floor (changes texture)";
+ 48 = " Scroll Texture Left";
+ 49 = "S1 Ceiling Lower to 8 above Floor (perpetual slow crusher damage)";
+ 50 = "S1 Door Close Stay";
+ 51 = "S1 Exit Level (goes to secret level)";
+ 52 = "W1 Exit Level";
+ 53 = "W1 Floor Start Moving Up and Down";
+ 54 = "W1 Floor Stop Moving";
+ 55 = "S1 Floor Raise to 8 below Lowest Ceiling (crushes)";
+ 56 = "W1 Floor Raise to 8 below Lowest Ceiling (crushes)";
+ 57 = "W1 Crusher Stop";
+ 58 = "W1 Floor Raise by 24";
+ 59 = "W1 Floor Raise by 24 (changes texture)";
+ 60 = "SR Floor Lower to Lowest Floor";
+ 61 = "SR Door Open Stay";
+ 62 = "SR Lift Lower Wait Raise";
+ 63 = "SR Door Open Wait Close";
+ 64 = "SR Floor Raise to Lowest Ceiling";
+ 65 = "SR Floor Raise to 8 below Lowest Ceiling (crushes)";
+ 66 = "SR Floor Raise by 24 (changes texture)";
+ 67 = "SR Floor Raise by 32 (changes texture)";
+ 68 = "SR Floor Raise to Next Higher Floor (changes texture)";
+ 69 = "SR Floor Raise to Next Higher Floor";
+ 70 = "SR Floor Lower to 8 above Highest Floor";
+ 71 = "S1 Floor Lower to 8 above Highest Floor";
+ 72 = "WR Ceiling Lower to 8 above Floor";
+ 73 = "WR Crusher Start with Slow Damage";
+ 74 = "WR Crusher Stop";
+ 75 = "WR Door Close Stay";
+ 76 = "WR Door Close Stay Open";
+ 77 = "WR Crusher Start with Fast Damage";
+ 78 = "SR Change Texture and Effect to Nearest";
+ 79 = "WR Light Change to 35";
+ 80 = "WR Light Change to Brightest Adjacent";
+ 81 = "WR Light Change to 255";
+ 82 = "WR Floor Lower to Lowest Floor";
+ 83 = "WR Floor Lower to Highest Floor";
+ 84 = "WR Floor Lower to Lowest Floor (changes texture)";
+ 85 = " Scroll Texture Right";
+ 86 = "WR Door Open Stay";
+ 87 = "WR Floor Start Moving Up and Down";
+ 88 = "WR Lift Lower Wait Raise";
+ 89 = "WR Floor Stop Moving";
+ 90 = "WR Door Open Wait Close";
+ 91 = "WR Floor Raise to Lowest Ceiling";
+ 92 = "WR Floor Raise by 24";
+ 93 = "WR Floor Raise by 24 (changes texture)";
+ 94 = "WR Floor Raise to 8 below Lowest Ceiling (crushes)";
+ 95 = "WR Floor Raise to Next Higher Floor (changes texture)";
+ 96 = "WR Floor Raise by Shortest Lower Texture";
+ 97 = "WR Teleport";
+ 98 = "WR Floor Lower to 8 above Highest Floor";
+ 99 = "SR Door (Blue) Open Stay (fast)";
+ 100 = "W1 Stairs Raise by 16 (fast)";
+ 101 = "S1 Floor Raise to Lowest Ceiling";
+ 102 = "S1 Floor Lower to Highest Floor";
+ 103 = "S1 Door Open Stay";
+ 104 = "W1 Light Change to Darkest Adjacent";
+ 105 = "WR Door Open Wait Close (fast)";
+ 106 = "WR Door Open Stay (fast)";
+ 107 = "WR Door Close Stay (fast)";
+ 108 = "W1 Door Open Wait Close (fast)";
+ 109 = "W1 Door Open Stay (fast)";
+ 110 = "W1 Door Close (fast)";
+ 111 = "S1 Door Open Wait Close (fast)";
+ 112 = "S1 Door Open Stay (fast)";
+ 113 = "S1 Door Close Stay (fast)";
+ 114 = "SR Door Open Wait Close (fast)";
+ 115 = "SR Door Open Stay (fast)";
+ 116 = "SR Door Close Stay (fast)";
+ 117 = "DR Door Open Wait Close (fast)";
+ 118 = "D1 Door Open Stay (fast)";
+ 119 = "W1 Floor Raise to Next Higher Floor";
+ 120 = "WR Lift Lower Wait Raise (fast)";
+ 121 = "W1 Lift Lower Wait Raise (fast)";
+ 122 = "S1 Lift Lower Wait Raise (fast)";
+ 123 = "SR Lift Lower Wait Raise (fast)";
+ 124 = "W1 Exit Level (goes to secret level)";
+ 125 = "W1 Teleport (monsters only)";
+ 126 = "WR Teleport (monsters only)";
+ 127 = "S1 Stairs Raise by 16 (fast)";
+ 128 = "WR Floor Raise to Next Higher Floor";
+ 129 = "WR Floor Raise to Next Higher Floor (fast)";
+ 130 = "W1 Floor Raise to Next Higher Floor (fast)";
+ 131 = "S1 Floor Raise to Next Higher Floor (fast)";
+ 132 = "SR Floor Raise to Next Higher Floor (fast)";
+ 133 = "S1 Door (Blue) Open Stay (fast)";
+ 134 = "SR Door (Red) Open Stay (fast)";
+ 135 = "S1 Door (Red) Open Stay (fast)";
+ 136 = "SR Door (Yellow) Open Stay (fast)";
+ 137 = "S1 Door (Yellow) Open Stay (fast)";
+ 138 = "SR Light Change to 255";
+ 139 = "SR Light Change to 35";
+ 140 = "S1 Floor Raise by 512";
+ 141 = "W1 Crusher Start with Slow Damage (silent)";
+ 142 = "W1 Floor Raise by 512";
+ 143 = "W1 Lift Raise by 24 (changes texture)";
+ 144 = "W1 Lift Raise by 24 (remove effect)";
+ 145 = "W1 Ceiling Lower to Floor (fast)";
+ 146 = "W1 Donut Raise";
+ 147 = "WR Floor Raise by 512";
+ 148 = "WR Lift Raise by 24 (changes texture)";
+ 149 = "WR Lift Raise by 24 (remove effect)";
+ 150 = "WR Crusher Start (silent)";
+ 151 = "WR Ceiling Raise to Highest Ceiling";
+ 152 = "WR Ceiling Lower to Floor (fast)";
+ 153 = "W1 Change Texture And Effect";
+ 154 = "WR Change Texture And Effect";
+ 155 = "WR Donut Raise";
+ 156 = "WR Light Start Blinking";
+ 157 = "WR Light Change to Darkest Adjacent";
+ 158 = "S1 Floor Raise by Shortest Lower Texture";
+ 159 = "S1 Floor Lower to Lowest Floor (changes texture)";
+ 160 = "S1 Floor Raise by 24 (changes texture and effect)";
+ 161 = "S1 Floor Raise by 24";
+ 162 = "S1 Lift Perpetual Lowest and Highest Floors";
+ 163 = "S1 Lift Stop";
+ 164 = "S1 Crusher Start (fast)";
+ 165 = "S1 Crusher Start (silent)";
+ 166 = "S1 Ceiling Raise to Highest Ceiling";
+ 167 = "S1 Ceiling Lower to 8 Above Floor";
+ 168 = "S1 Crusher Stop";
+ 169 = "S1 Light Change to Brightest Adjacent";
+ 170 = "S1 Light Change to 35";
+ 171 = "S1 Light Change to 255";
+ 172 = "S1 Light Start Blinking";
+ 173 = "S1 Light Change to Darkest Adjacent";
+ 174 = "S1 Teleport (also monsters)";
+ 175 = "S1 Door Close Wait Open (30 seconds)";
+ 176 = "SR Floor Raise by Shortest Lower Texture";
+ 177 = "SR Floor Lower to Lowest Floor (changes texture)";
+ 178 = "SR Floor Raise by 512";
+ 179 = "SR Floor Raise by 24 (changes texture and effect)";
+ 180 = "SR Floor Raise by 24";
+ 181 = "SR Lift Perpetual Lowest and Highest Floors";
+ 182 = "SR Lift Stop";
+ 183 = "SR Crusher Start (fast)";
+ 184 = "SR Crusher Start";
+ 185 = "SR Crusher Start (silent)";
+ 186 = "SR Ceiling Raise to Highest Ceiling";
+ 187 = "SR Ceiling Lower to 8 Above Floor";
+ 188 = "SR Crusher Stop";
+ 189 = "S1 Change Texture And Effect";
+ 190 = "SR Change Texture And Effect";
+ 191 = "SR Donut Raise";
+ 192 = "SR Light Change to Brightest Adjacent";
+ 193 = "SR Light Start Blinking";
+ 194 = "SR Light Change to Darkest Adjacent";
+ 195 = "SR Teleport (also monsters)";
+ 196 = "SR Door Close Wait Open (30 seconds)";
+ 197 = "G1 Exit Level";
+ 198 = "G1 Exit Level (goes to secret level)";
+ 199 = "W1 Ceiling Lower to Lowest Ceiling";
+ 200 = "W1 Ceiling Lower to Highest Floor";
+ 201 = "WR Ceiling Lower to Lowest Ceiling";
+ 202 = "WR Ceiling Lower to Highest Floor";
+ 203 = "S1 Ceiling Lower to Lowest Ceiling";
+ 204 = "S1 Ceiling Lower to Highest Floor";
+ 205 = "SR Ceiling Lower to Lowest Ceiling";
+ 206 = "SR Ceiling Lower to Highest Floor";
+ 207 = "W1 Teleport (also monsters, silent, same angle)";
+ 208 = "WR Teleport (also monsters, silent, same angle)";
+ 209 = "S1 Teleport (also monsters, silent, same angle)";
+ 210 = "SR Teleport (also monsters, silent, same angle)";
+ 211 = "SR Lift Raise to Ceiling (instantly)";
+ 212 = "WR Lift Raise to Ceiling (instantly)";
+ 213 = " Floor Change Brightness to this Brightness";
+ 214 = " Scroll Ceiling Accelerates when Sector Changes Height";
+ 215 = " Scroll Floor Accelerates when Sector Changes Height";
+ 216 = " Scroll Things Accelerates when Sector Changes Height";
+ 217 = " Scroll Floor/Things Accelerates when Sector Changes Height";
+ 218 = " Scroll Wall Accelerates when Sector Changes Height";
+ 219 = "W1 Floor Lower to Nearest Floor";
+ 220 = "WR Floor Lower to Nearest Floor";
+ 221 = "S1 Floor Lower to Nearest Floor";
+ 222 = "SR Floor Lower to Nearest Floor";
+ 223 = " Friction Tagged Sector: Drag < 100, Slide > 100";
+ 224 = " Wind according to Line Vector";
+ 225 = " Current according to Line Vector";
+ 226 = " Wind/Current by Push/Pull Thing In Sector";
+ 227 = "W1 Lift Raise to Next Highest Floor (fast)";
+ 228 = "WR Lift Raise to Next Highest Floor (fast)";
+ 229 = "S1 Lift Raise to Next Highest Floor (fast)";
+ 230 = "SR Lift Raise to Next Highest Floor (fast)";
+ 231 = "W1 Lift Lower to Next Lowest Floor (fast)";
+ 232 = "WR Lift Lower to Next Lowest Floor (fast)";
+ 233 = "S1 Lift Lower to Next Lowest Floor (fast)";
+ 234 = "SR Lift Lower to Next Lowest Floor (fast)";
+ 235 = "W1 Lift Move to Same Floor Height (fast)";
+ 236 = "WR Lift Move to Same Floor Height (fast)";
+ 237 = "S1 Lift Move to Same Floor Height (fast)";
+ 238 = "SR Lift Move to Same Floor Height (fast)";
+ 239 = "W1 Change Texture and Effect to Nearest";
+ 240 = "WR Change Texture and Effect to Nearest";
+ 241 = "S1 Change Texture and Effect to Nearest";
+ 242 = " Create Fake Ceiling and Floor";
+ 243 = "W1 Teleport to Line With Same Tag (silent, same angle)";
+ 244 = "WR Teleport to Line With Same Tag (silent, same angle)";
+ 245 = " Scroll Ceiling when Sector Changes Height";
+ 246 = " Scroll Floor when Sector Changes Height";
+ 247 = " Scroll Move Things when Sector Changes Height";
+ 248 = " Scroll Floor/Move Things when Sector Changes Height";
+ 249 = " Scroll Wall when Sector Changes Height";
+ 250 = " Scroll Ceiling according to Line Vector";
+ 251 = " Scroll Floor according to Line Vector";
+ 252 = " Scroll Move Things according to Line Vector";
+ 253 = " Scroll Floor, Move Things";
+ 254 = " Scroll Wall according to Line Vector";
+ 255 = " Scroll Wall using Sidedef Offsets";
+ 256 = "WR Stairs Raise by 8";
+ 257 = "WR Stairs Raise by 16 (fast)";
+ 258 = "SR Stairs Raise by 8";
+ 259 = "SR Stairs Raise by 16 (fast)";
+ 260 = " Translucent";
+ 261 = " Ceiling Brightness to this Brightness";
+ 262 = "W1 Teleport to Line With Same Tag (silent, reversed angle)";
+ 263 = "WR Teleport to Line With Same Tag (silent, reversed angle)";
+ 264 = "W1 Teleport to Line With Same Tag (also monsters, silent, reversed angle)";
+ 265 = "WR Teleport to Line With Same Tag (also monsters, reversed angle)";
+ 266 = "W1 Teleport to Line With Same Tag (monsters only, silent)";
+ 267 = "WR Teleport to Line With Same Tag (monsters only, silent)";
+ 268 = "W1 Teleport (monsters only, silent)";
+ 269 = "WR Teleport (monsters only, silent)";
+ 271 = " Transfer Sky Texture to Tagged Sectors";
+ 272 = " Transfer Sky Texture to Tagged Sectors (flipped)";
+ 273 = "WR Start Script, 1-way Trigger";
+ 274 = "W1 Start Script With Tag Number";
+ 275 = "W1 Start Script, 1-way Trigger";
+ 276 = "SR Start Script With Tag Number";
+ 277 = "S1 Start Script With Tag Number";
+ 278 = "GR Start Script With Tag Number";
+ 279 = "G1 Start Script With Tag Number";
+ 280 = "WR Start Script With Tag Number";
+ 281 = " Sector Floor movement to 3DMidTex as Vertical Scroll";
+ 282 = " Sector Ceiling movement to 3DMidTex as Vertical Scroll";
+ 283 = " Apply Plane Portal to Ceilings of Tagged Sectors";
+ 284 = " Apply Plane Portal to Floors of Tagged Sectors";
+ 285 = " Apply Plane Portal to Floors and Ceilings of Tagged Sectors";
+ 286 = " Apply Horizon Portal to Ceilings of Tagged Sectors";
+ 287 = " Apply Horizon Portal to Floors of Tagged Sectors";
+ 288 = " Apply Horizon Portal to Floors and Ceilings of Tagged Sectors";
+ 289 = " Transfer a Tagged Portal to the First Side of Linedef";
+ 290 = " Apply Skybox Portal to Ceilings of Tagged Sectors";
+ 291 = " Apply Skybox Portal to Floors of Tagged Sectors";
+ 292 = " Apply Skybox Portal to Floors and Ceilings of Tagged Sectors";
+ 293 = " Wind according to Line Vector";
+ 294 = " Current according to Line Vector";
+ 295 = " Apply Anchored Portal to Ceilings of Tagged Sectors";
+ 296 = " Apply Anchored Portal to Floors of Tagged Sectors";
+ 297 = " Apply Anchored Portal to Floors and Ceilings of Tagged Sectors";
+ 298 = " Anchor Line (for Specials 295 & 297)";
+ 299 = " Anchor Line (for Special 296)";
+ 358 = " Apply Linked Portal to Ceilings of Tagged Sectors";
+ 359 = " Apply Linked Portal to Floors of Tagged Sectors";
+ 360 = " Anchor Line (for Special 358)";
+ 361 = " Anchor Line (for Special 359)";
+ 376 = " Apply Linked Portal to Tagged Line";
+ 377 = " Anchor Line (for Special 376)";
+ 379 = " Attach Set Front Sector Ceiling as Control";
+ 380 = " Attach Set Front Sector Floor as Control";
+ 381 = " Attach Front Sector Floor to Tagged Controls";
+ 382 = " Attach Front Sector Ceiling to Tagged Controls";
+ 383 = " Attach Front Sector Floor Mirrored to Tagged Controls";
+ 384 = " Attach Front Sector Ceiling Mirrored To Tagged Controls";
+}
+
+// GENERALIZED LINEDEF TYPES
+gen_linedeftypes
+{
+ normal
+ {
+ title = "None";
+ offset = 0;
+ length = 0;
+ }
+
+ floors
+ {
+ title = "Floor";
+ offset = 24576;
+ length = 8192;
+
+ trigger
+ {
+ 0 = "Walk Over Once";
+ 1 = "Walk Over Repeatable";
+ 2 = "Switch Once";
+ 3 = "Switch Repeatable";
+ 4 = "Gunfire Once";
+ 5 = "Gunfire Repeatable";
+ 6 = "Door Once";
+ 7 = "Door Repeatable";
+ }
+
+ direction
+ {
+ 0 = "Down";
+ 64 = "Up";
+ }
+
+ target
+ {
+ 0 = "Highest Adjacent Floor";
+ 128 = "Lowest Adjacent Floor";
+ 256 = "Next Adjacent Floor";
+ 384 = "Lowest Adjacent Ceiling";
+ 512 = "Ceiling";
+ 640 = "Shortest Lower Texture";
+ 768 = "24 Map Pixels (relative)";
+ 896 = "32 Map Pixels (relative)";
+ }
+
+ speed
+ {
+ 0 = "Slow";
+ 8 = "Normal";
+ 16 = "Fast";
+ 24 = "Turbo";
+ }
+
+ model
+ {
+ 0 = "Trigger";
+ 32 = "Numeric";
+ }
+
+ change
+ {
+ 0 = "None";
+ 1024 = "Change Texture and Remove Effect";
+ 2048 = "Change Texture Only";
+ 3072 = "Change Texture and Effect";
+ }
+
+ crusher
+ {
+ 0 = "No";
+ 4096 = "Yes";
+ }
+ }
+
+ ceilings
+ {
+ title = "Ceiling";
+ offset = 16384;
+ length = 8192;
+
+ trigger
+ {
+ 0 = "Walk Over Once";
+ 1 = "Walk Over Repeatable";
+ 2 = "Switch Once";
+ 3 = "Switch Repeatable";
+ 4 = "Gunfire Once";
+ 5 = "Gunfire Repeatable";
+ 6 = "Door Once";
+ 7 = "Door Repeatable";
+ }
+
+ direction
+ {
+ 0 = "Down";
+ 64 = "Up";
+ }
+
+ target
+ {
+ 0 = "Highest Adjacent Ceiling";
+ 128 = "Lowest Adjacent Ceiling";
+ 256 = "Next Adjacent Ceiling";
+ 384 = "Highest Adjacent Floor";
+ 512 = "Floor";
+ 640 = "Shortest Lower Texture";
+ 768 = "24 Map Pixels (relative)";
+ 896 = "32 Map Pixels (relative)";
+ }
+
+ speed
+ {
+ 0 = "Slow";
+ 8 = "Normal";
+ 16 = "Fast";
+ 24 = "Turbo";
+ }
+
+ model
+ {
+ 0 = "Trigger";
+ 32 = "Numeric";
+ }
+
+ change
+ {
+ 0 = "None";
+ 1024 = "Change Texture and Remove Effect";
+ 2048 = "Change Texture Only";
+ 3072 = "Change Texture and Effect";
+ }
+
+ crusher
+ {
+ 0 = "No";
+ 4096 = "Yes";
+ }
+ }
+
+ doors
+ {
+ title = "Door";
+ offset = 15360;
+ length = 1024;
+
+ trigger
+ {
+ 0 = "Walk Over Once";
+ 1 = "Walk Over Repeatable";
+ 2 = "Switch Once";
+ 3 = "Switch Repeatable";
+ 4 = "Gunfire Once";
+ 5 = "Gunfire Repeatable";
+ 6 = "Door Once";
+ 7 = "Door Repeatable";
+ }
+
+ action
+ {
+ 0 = "Open Wait Close";
+ 32 = "Open Only";
+ 64 = "Close Wait Open";
+ 96 = "Close Only";
+ }
+
+ speed
+ {
+ 0 = "Slow";
+ 8 = "Normal";
+ 16 = "Fast";
+ 24 = "Turbo";
+ }
+
+ wait
+ {
+ 0 = "1 Second";
+ 256 = "4 Seconds";
+ 512 = "9 Seconds";
+ 768 = "30 Seconds";
+ }
+
+ monsters
+ {
+ 0 = "No";
+ 128 = "Yes";
+ }
+ }
+
+ lockeddoors
+ {
+ title = "Locked Door";
+ offset = 14336;
+ length = 1024;
+
+ trigger
+ {
+ 0 = "Walk Over Once";
+ 1 = "Walk Over Repeatable";
+ 2 = "Switch Once";
+ 3 = "Switch Repeatable";
+ 4 = "Gunfire Once";
+ 5 = "Gunfire Repeatable";
+ 6 = "Door Once";
+ 7 = "Door Repeatable";
+ }
+
+ action
+ {
+ 0 = "Open Wait Close";
+ 32 = "Open Only";
+ }
+
+ speed
+ {
+ 0 = "Slow";
+ 8 = "Normal";
+ 16 = "Fast";
+ 24 = "Turbo";
+ }
+
+ lock
+ {
+ 0 = "Any";
+ 64 = "Red Keycard";
+ 128 = "Blue Keycard";
+ 192 = "Yellow Keycard";
+ 256 = "Red Skullkey";
+ 320 = "Blue Skullkey";
+ 384 = "Yellow Skullkey";
+ 448 = "All";
+ }
+
+ combination
+ {
+ 0 = "No (each is a different key)";
+ 512 = "Keycard and Skullkey are same";
+ }
+ }
+
+ lifts
+ {
+ title = "Lift";
+ offset = 13312;
+ length = 1024;
+
+ trigger
+ {
+ 0 = "Walk Over Once";
+ 1 = "Walk Over Repeatable";
+ 2 = "Switch Once";
+ 3 = "Switch Repeatable";
+ 4 = "Gunfire Once";
+ 5 = "Gunfire Repeatable";
+ 6 = "Door Once";
+ 7 = "Door Repeatable";
+ }
+
+ target
+ {
+ 0 = "Lowest adjacent Floor";
+ 256 = "Next adjacent Floor";
+ 512 = "Lowest adjacent Ceiling";
+ 768 = "Perpetual Lowest and Highest Floors";
+ }
+
+ speed
+ {
+ 0 = "Slow";
+ 8 = "Normal";
+ 16 = "Fast";
+ 24 = "Turbo";
+ }
+
+ delay
+ {
+ 0 = "1 Second";
+ 64 = "3 Seconds";
+ 128 = "5 Seconds";
+ 192 = "10 Seconds";
+ }
+
+ monsters
+ {
+ 0 = "No";
+ 32 = "Yes";
+ }
+ }
+
+ stairs
+ {
+ title = "Stairs";
+ offset = 12288;
+ length = 1024;
+
+ trigger
+ {
+ 0 = "Walk Over Once";
+ 1 = "Walk Over Repeatable";
+ 2 = "Switch Once";
+ 3 = "Switch Repeatable";
+ 4 = "Gunfire Once";
+ 5 = "Gunfire Repeatable";
+ 6 = "Door Once";
+ 7 = "Door Repeatable";
+ }
+
+ direction
+ {
+ 0 = "Down";
+ 256 = "Up";
+ }
+
+ step
+ {
+ 0 = "4 Map Pixels";
+ 64 = "8 Map Pixels";
+ 128 = "16 Map Pixels";
+ 192 = "24 Map Pixels";
+ }
+
+ speed
+ {
+ 0 = "Slow";
+ 8 = "Normal";
+ 16 = "Fast";
+ 24 = "Turbo";
+ }
+
+ break
+ {
+ 0 = "At different texture";
+ 512 = "No";
+ }
+
+ monsters
+ {
+ 0 = "No";
+ 32 = "Yes";
+ }
+ }
+
+ crushers
+ {
+ title = "Crusher";
+ offset = 12160;
+ length = 128;
+
+ trigger
+ {
+ 0 = "Walk Over Once";
+ 1 = "Walk Over Repeatable";
+ 2 = "Switch Once";
+ 3 = "Switch Repeatable";
+ 4 = "Gunfire Once";
+ 5 = "Gunfire Repeatable";
+ 6 = "Door Once";
+ 7 = "Door Repeatable";
+ }
+
+ speed
+ {
+ 0 = "Slow";
+ 8 = "Normal";
+ 16 = "Fast";
+ 24 = "Turbo";
+ }
+
+ silent
+ {
+ 0 = "No";
+ 64 = "Yes";
+ }
+
+ monsters
+ {
+ 0 = "No";
+ 32 = "Yes";
+ }
+ }
+}
+
+// THING FLAGS
+thingflags
+{
+ 1 = "Easy";
+ 2 = "Medium";
+ 4 = "Hard";
+ 8 = "Deaf";
+ 16 = "Multiplayer";
+ 32 = "Not In DM";
+ 64 = "Not In Coop";
+ 128 = "Friendly";
+ 512 = "Dormant";
+}
+
+// THING FLAGS ERROR MASK
+// Mask for the thing flags which indicates the options
+// that make the same thing appear in the same modes
+thingflagsmask1 = 7; // 1 + 2 + 4
+thingflagsmask2 = 0;
+
+
+// THING TYPES
+thingtypes
+{
+ editor
+ {
+ color = 15; // White
+ arrow = 1;
+ title = "Editor Things";
+ width = 16;
+ sort = 1;
+ height = 0;
+ hangs = 0;
+ blocking = 0;
+ error = 0;
+
+ 32000 = "3D Mode start";
+ }
+
+ players
+ {
+ color = 10; // Light Green
+ arrow = 1;
+ title = "Player Starts";
+ width = 16;
+ sort = 1;
+ height = 56;
+ hangs = 0;
+ blocking = 1;
+ error = 2;
+
+ 1
+ {
+ title = "Player 1 start";
+ sprite = "PLAYA2A8";
+ }
+ 2
+ {
+ title = "Player 2 start";
+ sprite = "PLAYA2A8";
+ }
+ 3
+ {
+ title = "Player 3 start";
+ sprite = "PLAYA2A8";
+ }
+ 4
+ {
+ title = "Player 4 start";
+ sprite = "PLAYA2A8";
+ }
+ 11
+ {
+ title = "Player Deathmatch start";
+ sprite = "PLAYF1";
+ }
+ }
+
+ teleports
+ {
+ color = 2; // Green
+ arrow = 1;
+ title = "Teleports";
+ width = 16;
+ sort = 1;
+ height = 56;
+ hangs = 0;
+ blocking = 0;
+ error = 0;
+
+ 14
+ {
+ title = "Teleport Destination";
+ sprite = "TFOGB0";
+ }
+ }
+
+ monsters
+ {
+ color = 12; // Light Red
+ arrow = 1;
+ title = "Monsters";
+ width = 20;
+ sort = 1;
+ height = 56;
+ hangs = 0;
+ blocking = 1;
+ error = 2;
+
+ 3004
+ {
+ title = "Former Human";
+ sprite = "POSSA2A8";
+ }
+
+
+ 9
+ {
+ title = "Former Sergeant";
+ sprite = "SPOSA2A8";
+ }
+
+
+ 3001
+ {
+ title = "Imp";
+ sprite = "TROOA2A8";
+ }
+
+
+ 65
+ {
+ title = "Chaingunner";
+ sprite = "CPOSA2";
+ }
+
+
+ 3002
+ {
+ title = "Demon";
+ width = 30;
+ sprite = "SARGA2A8";
+ }
+
+
+ 58
+ {
+ title = "Spectre";
+ width = 30;
+ sprite = "SARGA2A8";
+ }
+
+
+ 3006
+ {
+ title = "Lost Soul";
+ width = 16;
+ sprite = "SKULA8A2";
+ }
+
+
+ 3005
+ {
+ title = "Cacodemon";
+ width = 31;
+ sprite = "HEADA2A8";
+ }
+
+
+ 69
+ {
+ title = "Hell Knight";
+ width = 24;
+ sprite = "BOS2A2C8";
+ height = 64;
+ }
+
+
+ 3003
+ {
+ title = "Baron of Hell";
+ width = 24;
+ sprite = "BOSSA2A8";
+ height = 64;
+ }
+
+
+ 68
+ {
+ title = "Arachnotron";
+ width = 64;
+ sprite = "BSPIA2A8";
+ height = 64;
+ }
+
+
+ 71
+ {
+ title = "Pain Elemental";
+ width = 31;
+ sprite = "PAINA2A8";
+ }
+
+
+ 66
+ {
+ title = "Revenant";
+ sprite = "SKELA2D8";
+ }
+
+
+ 67
+ {
+ title = "Mancubus";
+ width = 48;
+ sprite = "FATTC2C8";
+ height = 64;
+ }
+
+
+ 64
+ {
+ title = "Archvile";
+ sprite = "VILEA2D8";
+ }
+
+
+ 16
+ {
+ title = "Cyberdemon";
+ width = 40;
+ sprite = "CYBRA2";
+ height = 110;
+ }
+
+
+ 7
+ {
+ title = "Spider Mastermind";
+ width = 128;
+ sprite = "SPIDA2A8";
+ height = 100;
+ }
+
+
+ 84
+ {
+ title = "Wolfenstein SS";
+ sprite = "SSWVA2";
+ }
+
+
+ 72
+ {
+ title = "Commander Keen";
+ width = 16;
+ sprite = "KEENA0";
+ height = 72;
+ hangs = 1;
+ }
+
+
+ 88
+ {
+ title = "Icon of Sin";
+ width = 16;
+ sprite = "BBRNA0";
+ height = 16;
+ }
+
+
+ 89
+ {
+ title = "Monsters Spawner";
+ sprite = "BOSFB0";
+ height = 32;
+ }
+
+
+ 87
+ {
+ title = "Monsters Target";
+ height = 32;
+ }
+ }
+
+ weapons
+ {
+ color = 14; // Yellow
+ arrow = 0;
+ title = "Weapons";
+ width = 20;
+ sort = 1;
+ height = 25;
+ hangs = 0;
+ blocking = 0;
+
+ 2005
+ {
+ title = "Chainsaw";
+ sprite = "CSAWA0";
+ }
+ 2001
+ {
+ title = "Shotgun";
+ sprite = "SHOTA0";
+ }
+ 82
+ {
+ title = "Super Shotgun";
+ sprite = "SGN2A0";
+ }
+ 2002
+ {
+ title = "Chaingun";
+ sprite = "MGUNA0";
+ }
+ 2003
+ {
+ title = "Rocket launcher";
+ sprite = "LAUNA0";
+ }
+ 2004
+ {
+ title = "Plasma gun";
+ sprite = "PLASA0";
+ }
+ 2006
+ {
+ title = "BFG9000";
+ sprite = "BFUGA0";
+ height = 30;
+ }
+ }
+
+ ammunition
+ {
+ color = 6; // Brown
+ arrow = 0;
+ title = "Ammunition";
+ width = 16;
+ sort = 1;
+ height = 20;
+ blocking = 0;
+ hangs = 0;
+
+ 2007
+ {
+ title = "Ammo clip";
+ sprite = "CLIPA0";
+ }
+ 2008
+ {
+ title = "Shotgun shells";
+ sprite = "SHELA0";
+ }
+ 2010
+ {
+ title = "Rocket";
+ sprite = "ROCKA0";
+ height = 25;
+ }
+ 2047
+ {
+ title = "Cell charge";
+ sprite = "CELLA0";
+ }
+ 2048
+ {
+ title = "Box of Ammo";
+ sprite = "AMMOA0";
+ }
+ 2049
+ {
+ title = "Box of Shells";
+ sprite = "SBOXA0";
+ }
+ 2046
+ {
+ title = "Box of Rockets";
+ sprite = "BROKA0";
+ width = 30;
+ height = 25;
+ }
+ 17
+ {
+ title = "Cell charge pack";
+ sprite = "CELPA0";
+ height = 25;
+ }
+ 8
+ {
+ title = "Backpack";
+ sprite = "BPAKA0";
+ }
+ }
+
+ health
+ {
+ color = 1; // Blue
+ arrow = 0;
+ title = "Health and Armor";
+ width = 16;
+ sort = 1;
+ height = 20;
+ hangs = 0;
+ blocking = 0;
+
+ 2011
+ {
+ title = "Stimpack";
+ sprite = "STIMA0";
+ }
+ 2012
+ {
+ title = "Medikit";
+ sprite = "MEDIA0";
+ height = 25;
+ }
+ 2014
+ {
+ title = "Health bonus";
+ sprite = "BON1A0";
+ }
+ 2015
+ {
+ title = "Armor bonus";
+ sprite = "BON2A0";
+ }
+ 2018
+ {
+ title = "Green armor";
+ sprite = "ARM1A0";
+ }
+ 2019
+ {
+ title = "Blue armor";
+ sprite = "ARM2A0";
+ }
+ }
+
+ powerups
+ {
+ color = 9; // Light Blue
+ arrow = 0;
+ title = "Powerups";
+ width = 20;
+ sort = 1;
+ height = 20;
+ hangs = 0;
+ blocking = 0;
+
+ 83
+ {
+ title = "Megasphere";
+ sprite = "MEGAA0";
+ height = 40;
+ }
+ 2013
+ {
+ title = "Soulsphere";
+ sprite = "SOULA0";
+ height = 45;
+ }
+ 2022
+ {
+ title = "Invulnerability";
+ sprite = "PINVA0";
+ height = 30;
+ }
+ 2023
+ {
+ title = "Berserk";
+ sprite = "PSTRA0";
+ }
+ 2024
+ {
+ title = "Invisibility";
+ sprite = "PINSA0";
+ height = 45;
+ }
+ 2025
+ {
+ title = "Radiation suit";
+ sprite = "SUITA0";
+ height = 60;
+ }
+ 2026
+ {
+ title = "Computer map";
+ sprite = "PMAPA0";
+ height = 35;
+ }
+ 2045
+ {
+ title = "Lite Amplification goggles";
+ sprite = "PVISA0";
+ }
+ }
+
+ keys
+ {
+ color = 13; // Light Magenta
+ arrow = 0;
+ title = "Keys";
+ width = 16;
+ sort = 1;
+ height = 20;
+ hangs = 0;
+ blocking = 0;
+
+ 5
+ {
+ title = "Blue keycard";
+ sprite = "BKEYA0";
+ }
+ 40
+ {
+ title = "Blue skullkey";
+ sprite = "BSKUB0";
+ }
+ 13
+ {
+ title = "Red keycard";
+ sprite = "RKEYA0";
+ }
+ 38
+ {
+ title = "Red skullkey";
+ sprite = "RSKUB0";
+ }
+ 6
+ {
+ title = "Yellow keycard";
+ sprite = "YKEYA0";
+ }
+ 39
+ {
+ title = "Yellow skullkey";
+ sprite = "YSKUB0";
+ }
+ }
+
+ obstacles
+ {
+ color = 3; // Cyan
+ arrow = 0;
+ title = "Obstacles";
+ width = 20;
+ sort = 1;
+ height = 20;
+ hangs = 0;
+ blocking = 1;
+
+ 2035
+ {
+ title = "Barrel";
+ width = 10;
+ sprite = "BAR1A0";
+ height = 32;
+ }
+ 70
+ {
+ title = "Burning barrel";
+ width = 10;
+ sprite = "FCANA0";
+ height = 32;
+ }
+ 48
+ {
+ title = "Tall techno pillar";
+ sprite = "ELECA0";
+ }
+ 30
+ {
+ title = "Tall green pillar";
+ sprite = "COL1A0";
+ }
+ 32
+ {
+ title = "Tall red pillar";
+ sprite = "COL3A0";
+ }
+ 31
+ {
+ title = "Short green pillar";
+ sprite = "COL2A0";
+ }
+ 36
+ {
+ title = "Short green pillar (beating heart)";
+ sprite = "COL5A0";
+ }
+ 33
+ {
+ title = "Short red pillar";
+ sprite = "COL4A0";
+ }
+ 37
+ {
+ title = "Short red pillar (skull)";
+ sprite = "COL6A0";
+ }
+ 47
+ {
+ title = "Stalagmite";
+ sprite = "SMITA0";
+ }
+ 43
+ {
+ title = "Gray tree";
+ sprite = "TRE1A0";
+ }
+ 54
+ {
+ title = "Large brown tree";
+ width = 32;
+ sprite = "TRE2A0";
+ }
+ 41
+ {
+ title = "Evil Eye";
+ sprite = "CEYEA0";
+ }
+ 42
+ {
+ title = "Floating skull rock";
+ sprite = "FSKUA0";
+ }
+ }
+
+ lights
+ {
+ color = 11; // Light Cyan
+ arrow = 0;
+ title = "Light sources";
+ width = 16;
+ sort = 1;
+ height = 16;
+ hangs = 0;
+ blocking = 1;
+
+ 85
+ {
+ title = "Tall techno floor lamp";
+ sprite = "TLMPA0";
+ }
+ 86
+ {
+ title = "Short techno floor lamp";
+ sprite = "TLP2A0";
+ }
+ 2028
+ {
+ title = "Floor lamp";
+ sprite = "COLUA0";
+ }
+ 34
+ {
+ title = "Candle";
+ sprite = "CANDA0";
+ blocking = 0;
+ }
+ 35
+ {
+ title = "Candelabra";
+ sprite = "CBRAA0";
+ }
+ 44
+ {
+ title = "Tall blue firestick";
+ sprite = "TBLUA0";
+ }
+ 45
+ {
+ title = "Tall green firestick";
+ sprite = "TGRNA0";
+ }
+ 46
+ {
+ title = "Tall red firestick";
+ sprite = "TREDA0";
+ }
+ 55
+ {
+ title = "Short blue firestick";
+ sprite = "SMBTA0";
+ }
+ 56
+ {
+ title = "Short green firestick";
+ sprite = "SMGTA0";
+ }
+ 57
+ {
+ title = "Short red firestick";
+ sprite = "SMRTA0";
+ }
+ }
+
+ decoration
+ {
+ color = 4; // Red
+ arrow = 0;
+ title = "Decoration";
+ width = 16;
+ sort = 1;
+ height = 16;
+ hangs = 0;
+ blocking = 0;
+
+ 79
+ {
+ title = "Pool of blood and guts";
+ sprite = "POB2A0";
+ }
+
+
+ 80
+ {
+ title = "Pool of blood";
+ sprite = "POL5A0";
+ }
+
+
+ 81
+ {
+ title = "Pool of brains";
+ sprite = "BRS1A0";
+ }
+
+
+ 49
+ {
+ title = "Hanging victim, twitching (blocking)";
+ sprite = "GOR1A0";
+ height = 68;
+ hangs = 1;
+ blocking = 1;
+ }
+
+
+ 63
+ {
+ title = "Hanging victim, twitching";
+ sprite = "GOR1A0";
+ height = 68;
+ hangs = 1;
+ }
+
+
+ 50
+ {
+ title = "Hanging victim, arms out (blocking)";
+ sprite = "GOR2A0";
+ height = 84;
+ hangs = 1;
+ blocking = 1;
+ }
+
+
+ 59
+ {
+ title = "Hanging victim, arms out";
+ sprite = "GOR2A0";
+ height = 84;
+ hangs = 1;
+ }
+
+
+ 52
+ {
+ title = "Hanging pair of legs (blocking)";
+ sprite = "GOR4A0";
+ height = 68;
+ hangs = 1;
+ blocking = 1;
+ }
+
+
+ 60
+ {
+ title = "Hanging pair of legs";
+ sprite = "GOR4A0";
+ height = 68;
+ hangs = 1;
+ }
+
+
+ 51
+ {
+ title = "Hanging victim, 1-legged (blocking)";
+ sprite = "GOR3A0";
+ height = 84;
+ hangs = 1;
+ blocking = 1;
+ }
+
+
+ 61
+ {
+ title = "Hanging victim, 1-legged";
+ sprite = "GOR3A0";
+ height = 52;
+ hangs = 1;
+ }
+
+
+ 53
+ {
+ title = "Hanging leg (blocking)";
+ sprite = "GOR5A0";
+ height = 52;
+ hangs = 1;
+ blocking = 1;
+ }
+
+
+ 62
+ {
+ title = "Hanging leg";
+ sprite = "GOR5A0";
+ height = 52;
+ hangs = 1;
+ }
+
+
+ 25
+ {
+ title = "Impaled human";
+ sprite = "POL1A0";
+ blocking = 1;
+ }
+
+
+ 26
+ {
+ title = "Twitching impaled human";
+ sprite = "POL6A0";
+ blocking = 1;
+ }
+
+
+ 27
+ {
+ title = "Skull on a pole";
+ sprite = "POL4A0";
+ blocking = 1;
+ }
+
+
+ 28
+ {
+ title = "5 skulls shish kebob";
+ sprite = "POL2A0";
+ blocking = 1;
+ }
+
+
+ 29
+ {
+ title = "Pile of skulls and candles";
+ sprite = "POL3A0";
+ blocking = 1;
+ }
+
+
+ 10
+ {
+ title = "Bloody mess 1";
+ sprite = "PLAYW0";
+ }
+
+
+ 12
+ {
+ title = "Bloody mess 2";
+ sprite = "PLAYW0";
+ }
+
+
+ 24
+ {
+ title = "Pool of blood and bones";
+ sprite = "POL5A0";
+ }
+
+
+ 15
+ {
+ title = "Dead player";
+ sprite = "PLAYN0";
+ }
+
+
+ 18
+ {
+ title = "Dead former human";
+ sprite = "POSSL0";
+ width = 20;
+ }
+
+
+ 19
+ {
+ title = "Dead former sergeant";
+ sprite = "SPOSL0";
+ width = 20;
+ }
+
+
+ 20
+ {
+ title = "Dead imp";
+ sprite = "TROOM0";
+ width = 20;
+ }
+
+
+ 21
+ {
+ title = "Dead demon";
+ sprite = "SARGN0";
+ width = 30;
+ }
+
+
+ 22
+ {
+ title = "Dead cacodemon";
+ sprite = "HEADL0";
+ width = 31;
+ }
+
+
+ 23
+ {
+ title = "Dead lost soul";
+ }
+
+
+ 73
+ {
+ title = "Hanging victim, guts removed";
+ sprite = "HDB1A0";
+ height = 88;
+ hangs = 1;
+ blocking = 1;
+ }
+
+
+ 74
+ {
+ title = "Hanging victim, guts and brain removed";
+ sprite = "HDB2A0";
+ height = 88;
+ hangs = 1;
+ blocking = 1;
+ }
+
+
+ 75
+ {
+ title = "Hanging torso, looking down";
+ sprite = "HDB3A0";
+ height = 64;
+ hangs = 1;
+ blocking = 1;
+ }
+
+
+ 76
+ {
+ title = "Hanging torso, open skull";
+ sprite = "HDB4A0";
+ height = 64;
+ hangs = 1;
+ blocking = 1;
+ }
+
+
+ 77
+ {
+ title = "Hanging torso, looking down";
+ sprite = "HDB5A0";
+ height = 64;
+ hangs = 1;
+ blocking = 1;
+ }
+
+
+ 78
+ {
+ title = "Hanging torso, brain removed";
+ sprite = "HDB6A0";
+ height = 64;
+ hangs = 1;
+ blocking = 1;
+ }
+
+ 9027 = "Red Particle Fountain";
+ 9028 = "Green Particle Fountain";
+ 9029 = "Blue Particle Fountain";
+ 9030 = "Yellow Particle Fountain";
+ 9031 = "Purple Particle Fountain";
+ 9032 = "Black Particle Fountain";
+ 9033 = "White Particle Fountain";
+ }
+
+ eternity
+ {
+ color = 8; // Grey
+ arrow = 1;
+ title = "Eternity Items";
+ width = 0;
+ sort = 1;
+
+ 5001 = "Pusher";
+ 5002 = "Puller";
+ 888 = "Helper Dog";
+ 5003 = "Camera Spot for Demo Playback";
+ 5005 = "Placeholder Thing";
+ 5006 = "Skybox Camera";
+ }
+}
diff --git a/Resources/Icons/Property.png b/Resources/Icons/Property.png
new file mode 100644
index 00000000..7a424bf3
Binary files /dev/null and b/Resources/Icons/Property.png differ
diff --git a/Resources/Icons/PropertyUnknown.png b/Resources/Icons/PropertyUnknown.png
new file mode 100644
index 00000000..8ce7d39a
Binary files /dev/null and b/Resources/Icons/PropertyUnknown.png differ
diff --git a/Source/Builder.csproj b/Source/Builder.csproj
index a0499cd4..b12be0c4 100644
--- a/Source/Builder.csproj
+++ b/Source/Builder.csproj
@@ -53,6 +53,8 @@
+
+
@@ -143,6 +145,13 @@
ConfigForm.cs
+
+
+ UserControl
+
+
+ FieldsEditorControl.cs
+
Form
@@ -273,6 +282,7 @@
+
@@ -409,6 +419,10 @@
Designer
ConfigForm.cs
+
+ Designer
+ FieldsEditorControl.cs
+
FlatBrowserForm.cs
Designer
diff --git a/Source/Config/GameConfiguration.cs b/Source/Config/GameConfiguration.cs
index 2c717c35..9ac24559 100644
--- a/Source/Config/GameConfiguration.cs
+++ b/Source/Config/GameConfiguration.cs
@@ -74,6 +74,9 @@ namespace CodeImp.DoomBuilder.Config
private List linedefactivates;
private List genactioncategories;
+ // Universal fields
+ private List linedeffields;
+
#endregion
#region ================== Properties
@@ -110,6 +113,9 @@ namespace CodeImp.DoomBuilder.Config
public List LinedefActivates { get { return linedefactivates; } }
public List GenActionCategories { get { return genactioncategories; } }
+ // Universal fields
+ public List LinedefFields { get { return linedeffields; } }
+
#endregion
#region ================== Constructor / Disposer
@@ -156,6 +162,9 @@ namespace CodeImp.DoomBuilder.Config
LoadLinedefActions();
LoadLinedefActivations();
LoadLinedefGeneralizedAction();
+
+ // Universal fields
+ linedeffields = LoadUniversalFields("linedefs");
}
// Destructor
@@ -169,6 +178,33 @@ namespace CodeImp.DoomBuilder.Config
#region ================== Loading
+ // This loads a universal fields list
+ private List LoadUniversalFields(string elementname)
+ {
+ List list = new List();
+ UniversalFieldInfo uf;
+ IDictionary dic;
+
+ // Get fields
+ dic = cfg.ReadSetting("universalfields." + elementname, new Hashtable());
+ foreach(DictionaryEntry de in dic)
+ {
+ try
+ {
+ // Read the field info and add to list
+ uf = new UniversalFieldInfo(elementname, de.Key.ToString(), cfg);
+ list.Add(uf);
+ }
+ catch(Exception e)
+ {
+ General.WriteLogLine("WARNING: Unable to read universal field definition 'universalfields." + elementname + "." + de.Key + "'!");
+ }
+ }
+
+ // Return result
+ return list;
+ }
+
// Things and thing categories
private void LoadThingCategories()
{
diff --git a/Source/Config/UniversalFieldInfo.cs b/Source/Config/UniversalFieldInfo.cs
new file mode 100644
index 00000000..f5ad4faa
--- /dev/null
+++ b/Source/Config/UniversalFieldInfo.cs
@@ -0,0 +1,125 @@
+
+#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.IO;
+using CodeImp.DoomBuilder.Data;
+using System.IO;
+using System.Diagnostics;
+using System.Windows.Forms;
+using CodeImp.DoomBuilder.Map;
+
+#endregion
+
+namespace CodeImp.DoomBuilder.Config
+{
+ public class UniversalFieldInfo : IComparable
+ {
+ #region ================== Constants
+
+ #endregion
+
+ #region ================== Variables
+
+ // Properties
+ private string name;
+ private UniversalFieldType type;
+ private string defstring;
+ private int defint;
+ private float deffloat;
+
+ #endregion
+
+ #region ================== Properties
+
+ public string Name { get { return name; } }
+ public UniversalFieldType Type { get { return type; } }
+ public string DefaultStr { get { return defstring; } }
+ public int DefaultInt { get { return defint; } }
+ public float DefaultFloat { get { return deffloat; } }
+
+ #endregion
+
+ #region ================== Constructor / Disposer
+
+ // Constructor
+ internal UniversalFieldInfo(string path, string name, Configuration cfg)
+ {
+ string setting = "universalfields." + path + "." + name;
+
+ // Initialize
+ this.name = name;
+
+ // Read type
+ this.type = (UniversalFieldType)cfg.ReadSetting(setting + ".type", 0);
+ switch(this.type)
+ {
+ case UniversalFieldType.Integer:
+ case UniversalFieldType.LinedefAction:
+ case UniversalFieldType.SectorEffect:
+ defint = cfg.ReadSetting(setting + ".default", 0);
+ deffloat = (float)defint;
+ defstring = DefaultInt.ToString(CultureInfo.InvariantCulture);
+ break;
+
+ case UniversalFieldType.Float:
+ deffloat = cfg.ReadSetting(setting + ".default", 0.0f);
+ defint = (int)Math.Round(deffloat);
+ defstring = DefaultFloat.ToString(CultureInfo.InvariantCulture);
+ break;
+
+ case UniversalFieldType.String:
+ case UniversalFieldType.Flat:
+ case UniversalFieldType.Texture:
+ defstring = cfg.ReadSetting(setting + ".default", "");
+ float.TryParse(DefaultStr, NumberStyles.Number, CultureInfo.InvariantCulture, out deffloat);
+ int.TryParse(DefaultStr, NumberStyles.Number, CultureInfo.InvariantCulture, out defint);
+ break;
+
+ default:
+ General.WriteLogLine("WARNING: Universal field '" + path + "." + name + "' is defined as unknown type " + (int)this.type + "!");
+ break;
+ }
+
+ // We have no destructor
+ GC.SuppressFinalize(this);
+ }
+
+ #endregion
+
+ #region ================== Methods
+
+ // This presents the item as string
+ public override string ToString()
+ {
+ return name;
+ }
+
+ // This compares against another field
+ public int CompareTo(UniversalFieldInfo other)
+ {
+ return string.Compare(this.name, other.name);
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/Config/UniversalFieldType.cs b/Source/Config/UniversalFieldType.cs
new file mode 100644
index 00000000..b0597040
--- /dev/null
+++ b/Source/Config/UniversalFieldType.cs
@@ -0,0 +1,44 @@
+
+#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.IO;
+using CodeImp.DoomBuilder.Data;
+using System.IO;
+using System.Diagnostics;
+using System.Windows.Forms;
+
+#endregion
+
+namespace CodeImp.DoomBuilder.Config
+{
+ public enum UniversalFieldType
+ {
+ Integer = 0,
+ Float = 1,
+ String = 2,
+ LinedefAction = 3,
+ SectorEffect = 4,
+ Texture = 5,
+ Flat = 6
+ }
+}
diff --git a/Source/IO/Configuration.cs b/Source/IO/Configuration.cs
index 3b61fe78..fd6db960 100644
--- a/Source/IO/Configuration.cs
+++ b/Source/IO/Configuration.cs
@@ -709,8 +709,8 @@ namespace CodeImp.DoomBuilder.IO
key = "";
val = "";
}
- // Otherwise (if not a space) it will be a keyword
- else if(c != ' ')
+ // Otherwise (if not whitespace) it will be a keyword
+ else if((c != ' ') && (c != '\t'))
{
// Now parsing a keyword
pm = PM_KEYWORD;
diff --git a/Source/IO/UniversalMapSetIO.cs b/Source/IO/UniversalMapSetIO.cs
new file mode 100644
index 00000000..72f3493d
--- /dev/null
+++ b/Source/IO/UniversalMapSetIO.cs
@@ -0,0 +1,79 @@
+
+#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 System.IO;
+using CodeImp.DoomBuilder.Map;
+using CodeImp.DoomBuilder.Geometry;
+
+#endregion
+
+namespace CodeImp.DoomBuilder.IO
+{
+ internal class UniversalMapSetIO : MapSetIO
+ {
+ #region ================== Constants
+
+ #endregion
+
+ #region ================== Constructor / Disposer
+
+ // Constructor
+ public UniversalMapSetIO(WAD wad, MapManager manager)
+ : base(wad, manager)
+ {
+ }
+
+ #endregion
+
+ #region ================== Properties
+
+ public override int MaxSidedefs { get { return int.MaxValue; } }
+
+ #endregion
+
+ #region ================== Parsing
+
+ #endregion
+
+ #region ================== Reading
+
+ // This reads a map from the file and returns a MapSet
+ public override MapSet Read(MapSet map, string mapname)
+ {
+ // Return result
+ return map;
+ }
+
+ #endregion
+
+ #region ================== Writing
+
+ // This writes a MapSet to the file
+ public override void Write(MapSet map, string mapname, int position)
+ {
+
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/Interface/FieldsEditorControl.Designer.cs b/Source/Interface/FieldsEditorControl.Designer.cs
new file mode 100644
index 00000000..83a39685
--- /dev/null
+++ b/Source/Interface/FieldsEditorControl.Designer.cs
@@ -0,0 +1,164 @@
+namespace CodeImp.DoomBuilder.Interface
+{
+ partial class FieldsEditorControl
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if(disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.components = new System.ComponentModel.Container();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle16 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle13 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle14 = new System.Windows.Forms.DataGridViewCellStyle();
+ System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle15 = new System.Windows.Forms.DataGridViewCellStyle();
+ this.fieldslist = new System.Windows.Forms.DataGridView();
+ this.deleterowstimer = new System.Windows.Forms.Timer(this.components);
+ this.browsebutton = new System.Windows.Forms.Button();
+ this.fieldname = new System.Windows.Forms.DataGridViewTextBoxColumn();
+ this.fieldtype = new System.Windows.Forms.DataGridViewComboBoxColumn();
+ this.fieldvalue = new System.Windows.Forms.DataGridViewTextBoxColumn();
+ ((System.ComponentModel.ISupportInitialize)(this.fieldslist)).BeginInit();
+ this.SuspendLayout();
+ //
+ // fieldslist
+ //
+ this.fieldslist.AllowUserToResizeColumns = false;
+ this.fieldslist.AllowUserToResizeRows = false;
+ this.fieldslist.BackgroundColor = System.Drawing.SystemColors.Window;
+ this.fieldslist.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
+ this.fieldslist.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None;
+ this.fieldslist.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.Disable;
+ this.fieldslist.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
+ this.fieldslist.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+ this.fieldslist.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
+ this.fieldname,
+ this.fieldtype,
+ this.fieldvalue});
+ dataGridViewCellStyle16.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
+ dataGridViewCellStyle16.BackColor = System.Drawing.SystemColors.Window;
+ dataGridViewCellStyle16.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ dataGridViewCellStyle16.ForeColor = System.Drawing.SystemColors.WindowText;
+ dataGridViewCellStyle16.SelectionBackColor = System.Drawing.SystemColors.Highlight;
+ dataGridViewCellStyle16.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
+ dataGridViewCellStyle16.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
+ this.fieldslist.DefaultCellStyle = dataGridViewCellStyle16;
+ this.fieldslist.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
+ this.fieldslist.Location = new System.Drawing.Point(0, 0);
+ this.fieldslist.MultiSelect = false;
+ this.fieldslist.Name = "fieldslist";
+ this.fieldslist.RowHeadersVisible = false;
+ this.fieldslist.RowTemplate.DefaultCellStyle.BackColor = System.Drawing.SystemColors.Window;
+ this.fieldslist.RowTemplate.DefaultCellStyle.ForeColor = System.Drawing.SystemColors.WindowText;
+ this.fieldslist.RowTemplate.DefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
+ this.fieldslist.RowTemplate.DefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
+ this.fieldslist.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+ this.fieldslist.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
+ this.fieldslist.Size = new System.Drawing.Size(444, 244);
+ this.fieldslist.TabIndex = 1;
+ this.fieldslist.UserDeletingRow += new System.Windows.Forms.DataGridViewRowCancelEventHandler(this.fieldslist_UserDeletingRow);
+ this.fieldslist.CellBeginEdit += new System.Windows.Forms.DataGridViewCellCancelEventHandler(this.fieldslist_CellBeginEdit);
+ this.fieldslist.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.fieldslist_CellClick);
+ this.fieldslist.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.fieldslist_CellEndEdit);
+ this.fieldslist.SelectionChanged += new System.EventHandler(this.fieldslist_SelectionChanged);
+ //
+ // deleterowstimer
+ //
+ this.deleterowstimer.Interval = 1;
+ this.deleterowstimer.Tick += new System.EventHandler(this.deleterowstimer_Tick);
+ //
+ // browsebutton
+ //
+ this.browsebutton.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.browsebutton.Image = global::CodeImp.DoomBuilder.Properties.Resources.treeview;
+ this.browsebutton.ImageAlign = System.Drawing.ContentAlignment.BottomCenter;
+ this.browsebutton.Location = new System.Drawing.Point(370, 43);
+ this.browsebutton.Name = "browsebutton";
+ this.browsebutton.Size = new System.Drawing.Size(30, 24);
+ this.browsebutton.TabIndex = 2;
+ this.browsebutton.UseVisualStyleBackColor = true;
+ this.browsebutton.Visible = false;
+ //
+ // fieldname
+ //
+ dataGridViewCellStyle13.BackColor = System.Drawing.SystemColors.Window;
+ dataGridViewCellStyle13.ForeColor = System.Drawing.SystemColors.WindowText;
+ dataGridViewCellStyle13.NullValue = null;
+ dataGridViewCellStyle13.SelectionBackColor = System.Drawing.SystemColors.Highlight;
+ dataGridViewCellStyle13.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
+ this.fieldname.DefaultCellStyle = dataGridViewCellStyle13;
+ this.fieldname.Frozen = true;
+ this.fieldname.HeaderText = "Property";
+ this.fieldname.Name = "fieldname";
+ this.fieldname.Width = 180;
+ //
+ // fieldtype
+ //
+ dataGridViewCellStyle14.BackColor = System.Drawing.SystemColors.Window;
+ dataGridViewCellStyle14.ForeColor = System.Drawing.SystemColors.WindowText;
+ dataGridViewCellStyle14.SelectionBackColor = System.Drawing.SystemColors.Highlight;
+ dataGridViewCellStyle14.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
+ this.fieldtype.DefaultCellStyle = dataGridViewCellStyle14;
+ this.fieldtype.DisplayStyle = System.Windows.Forms.DataGridViewComboBoxDisplayStyle.Nothing;
+ this.fieldtype.HeaderText = "Type";
+ this.fieldtype.Name = "fieldtype";
+ this.fieldtype.Resizable = System.Windows.Forms.DataGridViewTriState.True;
+ //
+ // fieldvalue
+ //
+ dataGridViewCellStyle15.BackColor = System.Drawing.SystemColors.Window;
+ dataGridViewCellStyle15.ForeColor = System.Drawing.SystemColors.WindowText;
+ dataGridViewCellStyle15.SelectionBackColor = System.Drawing.SystemColors.Highlight;
+ dataGridViewCellStyle15.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
+ this.fieldvalue.DefaultCellStyle = dataGridViewCellStyle15;
+ this.fieldvalue.HeaderText = "Value";
+ this.fieldvalue.Name = "fieldvalue";
+ this.fieldvalue.Resizable = System.Windows.Forms.DataGridViewTriState.True;
+ this.fieldvalue.Width = 120;
+ //
+ // FieldsEditorControl
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.browsebutton);
+ this.Controls.Add(this.fieldslist);
+ this.Name = "FieldsEditorControl";
+ this.Size = new System.Drawing.Size(474, 266);
+ this.Layout += new System.Windows.Forms.LayoutEventHandler(this.FieldsEditorControl_Layout);
+ this.Resize += new System.EventHandler(this.FieldsEditorControl_Resize);
+ ((System.ComponentModel.ISupportInitialize)(this.fieldslist)).EndInit();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.DataGridView fieldslist;
+ private System.Windows.Forms.Timer deleterowstimer;
+ private System.Windows.Forms.Button browsebutton;
+ private System.Windows.Forms.DataGridViewTextBoxColumn fieldname;
+ private System.Windows.Forms.DataGridViewComboBoxColumn fieldtype;
+ private System.Windows.Forms.DataGridViewTextBoxColumn fieldvalue;
+ }
+}
diff --git a/Source/Interface/FieldsEditorControl.cs b/Source/Interface/FieldsEditorControl.cs
new file mode 100644
index 00000000..262b7aaf
--- /dev/null
+++ b/Source/Interface/FieldsEditorControl.cs
@@ -0,0 +1,266 @@
+
+#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.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using Microsoft.Win32;
+using System.Diagnostics;
+using CodeImp.DoomBuilder.Controls;
+using CodeImp.DoomBuilder.Data;
+using CodeImp.DoomBuilder.Config;
+using CodeImp.DoomBuilder.Rendering;
+using SlimDX.Direct3D9;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using CodeImp.DoomBuilder.Map;
+using System.Globalization;
+
+#endregion
+
+namespace CodeImp.DoomBuilder.Interface
+{
+ public partial class FieldsEditorControl : UserControl
+ {
+ // Constants
+ private const string ADD_FIELD_TEXT = " (click to add custom field)";
+
+ // Constructor
+ public FieldsEditorControl()
+ {
+ InitializeComponent();
+
+ // Make types list
+ fieldtype.Items.Clear();
+ fieldtype.Items.AddRange(Enum.GetNames(typeof(UniversalFieldType)));
+ }
+
+ // This adds a list of fixed fields (in undefined state)
+ public void ListFixedFields(List list)
+ {
+ // Add all fields
+ foreach(UniversalFieldInfo uf in list)
+ fieldslist.Rows.Add(new FieldsEditorRow(fieldslist, uf));
+
+ // Update new row
+ SetupNewRowStyle();
+ }
+
+ // This sets up the new row
+ private void SetupNewRowStyle()
+ {
+ // Show text for new row
+ fieldslist.Rows[fieldslist.NewRowIndex].Cells[0].Value = ADD_FIELD_TEXT;
+ fieldslist.Rows[fieldslist.NewRowIndex].Cells[0].Style.ForeColor = SystemColors.GrayText;
+ fieldslist.Rows[fieldslist.NewRowIndex].Cells[0].ReadOnly = false;
+
+ // Make sure user can only enter property name in a new row
+ fieldslist.Rows[fieldslist.NewRowIndex].Cells[1].ReadOnly = true;
+ fieldslist.Rows[fieldslist.NewRowIndex].Cells[2].ReadOnly = true;
+ }
+
+ // Resized
+ private void FieldsEditorControl_Resize(object sender, EventArgs e)
+ {
+ // Rearrange controls
+ fieldslist.Size = this.ClientSize;
+ fieldvalue.Width = fieldslist.ClientRectangle.Width - fieldname.Width - fieldtype.Width - SystemInformation.VerticalScrollBarWidth - 10;
+ }
+
+ // Layout change
+ private void FieldsEditorControl_Layout(object sender, LayoutEventArgs e)
+ {
+ FieldsEditorControl_Resize(sender, EventArgs.Empty);
+ }
+
+ // Cell clicked
+ private void fieldslist_CellClick(object sender, DataGridViewCellEventArgs e)
+ {
+ // Edit immediately
+ if(fieldslist.SelectedCells.Count > 0) fieldslist.BeginEdit(true);
+ }
+
+ // User deletes a row
+ private void fieldslist_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
+ {
+ // Get the row
+ FieldsEditorRow row = e.Row as FieldsEditorRow;
+
+ // Fixed field?
+ if(row.IsFixed)
+ {
+ // Just undefine the field
+ row.Undefine();
+ e.Cancel = true;
+ }
+ }
+
+ // User selects a cell for editing
+ private void fieldslist_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
+ {
+ // Property cell?
+ if(e.ColumnIndex == 0)
+ {
+ // New row index?
+ if(e.RowIndex == fieldslist.NewRowIndex)
+ {
+ // Remove all text
+ fieldslist.Rows[e.RowIndex].Cells[0].Style.ForeColor = SystemColors.WindowText;
+ fieldslist.Rows[e.RowIndex].Cells[0].Value = "";
+ }
+ }
+ }
+
+ // Done editing cell contents
+ private void fieldslist_CellEndEdit(object sender, DataGridViewCellEventArgs e)
+ {
+ FieldsEditorRow frow = null;
+ DataGridViewRow row = null;
+
+ // Get the row
+ row = fieldslist.Rows[e.RowIndex];
+ if(row is FieldsEditorRow) frow = row as FieldsEditorRow;
+
+ // Renaming a field?
+ if(e.ColumnIndex == 0)
+ {
+ // Row is a new row?
+ if(frow == null)
+ {
+ // Valid property name given?
+ if((row.Cells[0].Value != null) && (row.Cells[0].Value.ToString().Trim().Length > 0))
+ {
+ // Make new row
+ frow = new FieldsEditorRow(fieldslist, row.Cells[0].Value.ToString().Trim(), UniversalFieldType.Integer, 0);
+ frow.Visible = false;
+ fieldslist.Rows.Insert(e.RowIndex + 1, frow);
+ }
+
+ // Mark the row for delete
+ row.ReadOnly = true;
+ deleterowstimer.Start();
+ }
+ }
+ // Changing field value?
+ if((e.ColumnIndex == 2) && (frow != null))
+ {
+ // Defined?
+ if((row.Cells[2].Value != null) && (!frow.IsFixed || (frow.Info.DefaultStr != row.Cells[2].Value.ToString())))
+ frow.Define(row.Cells[2].Value);
+ else if(frow.IsFixed)
+ frow.Undefine();
+ }
+
+ // Updated
+ if(frow != null) frow.CellChanged();
+
+ // Update button
+ UpdateBrowseButton();
+ }
+
+ // Time to delete rows
+ private void deleterowstimer_Tick(object sender, EventArgs e)
+ {
+ // Stop timer
+ deleterowstimer.Stop();
+
+ // Delete all rows that must be deleted
+ for(int i = fieldslist.Rows.Count - 1; i >= 0; i--)
+ {
+ if(fieldslist.Rows[i].ReadOnly)
+ try { fieldslist.Rows.RemoveAt(i); } catch(Exception) { }
+ else
+ fieldslist.Rows[i].Visible = true;
+ }
+
+ // Update new row
+ SetupNewRowStyle();
+
+ // Update button
+ UpdateBrowseButton();
+ }
+
+ // Selection changes
+ private void fieldslist_SelectionChanged(object sender, EventArgs e)
+ {
+ // Update button
+ UpdateBrowseButton();
+ }
+
+ // This updates the button
+ private void UpdateBrowseButton()
+ {
+ FieldsEditorRow frow = null;
+ DataGridViewRow row = null;
+
+ // Any row selected?
+ if(fieldslist.SelectedRows.Count > 0)
+ {
+ // Get selected row
+ row = fieldslist.SelectedRows[0];
+ if(row is FieldsEditorRow) frow = row as FieldsEditorRow;
+
+ // Not the new row and FieldsEditorRow available?
+ if((row.Index < fieldslist.NewRowIndex) && (frow != null))
+ {
+ // Browse button available for this type?
+ if((frow.Type == UniversalFieldType.Flat) ||
+ (frow.Type == UniversalFieldType.LinedefAction) ||
+ (frow.Type == UniversalFieldType.SectorEffect) ||
+ (frow.Type == UniversalFieldType.Texture))
+ {
+ Rectangle cellrect = fieldslist.GetCellDisplayRectangle(2, row.Index, false);
+
+ // Show button
+ browsebutton.Location = new Point(cellrect.Right - browsebutton.Width, cellrect.Top);
+ browsebutton.Height = cellrect.Height;
+ browsebutton.Visible = true;
+
+ // Determine image/text
+ if((frow.Type == UniversalFieldType.SectorEffect) ||
+ (frow.Type == UniversalFieldType.LinedefAction))
+ {
+ browsebutton.Image = CodeImp.DoomBuilder.Properties.Resources.treeview;
+ browsebutton.Text = "";
+ }
+ else
+ {
+ browsebutton.Image = null;
+ browsebutton.Text = "...";
+ }
+ }
+ else
+ {
+ browsebutton.Visible = false;
+ }
+ }
+ else
+ {
+ browsebutton.Visible = false;
+ }
+ }
+ else
+ {
+ browsebutton.Visible = false;
+ }
+ }
+ }
+}
diff --git a/Source/Interface/FieldsEditorControl.resx b/Source/Interface/FieldsEditorControl.resx
new file mode 100644
index 00000000..16e40157
--- /dev/null
+++ b/Source/Interface/FieldsEditorControl.resx
@@ -0,0 +1,132 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ True
+
+
+ True
+
+
+ True
+
+
+ 17, 17
+
+
\ No newline at end of file
diff --git a/Source/Interface/FieldsEditorRow.cs b/Source/Interface/FieldsEditorRow.cs
new file mode 100644
index 00000000..321b1b87
--- /dev/null
+++ b/Source/Interface/FieldsEditorRow.cs
@@ -0,0 +1,176 @@
+
+#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.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using Microsoft.Win32;
+using System.Diagnostics;
+using CodeImp.DoomBuilder.Controls;
+using CodeImp.DoomBuilder.Data;
+using CodeImp.DoomBuilder.Config;
+using CodeImp.DoomBuilder.Rendering;
+using SlimDX.Direct3D9;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using CodeImp.DoomBuilder.Map;
+
+#endregion
+
+namespace CodeImp.DoomBuilder.Interface
+{
+ internal class FieldsEditorRow : DataGridViewRow
+ {
+ #region ================== Constants
+
+ #endregion
+
+ #region ================== Variables
+
+ // This is true when for a fixed field as defined in the game configuration
+ // This means that the field cannot be deleted (delete will result in a reset)
+ // and cannot change type.
+ private bool isfixed;
+
+ // Field information (only for fixed fields)
+ private UniversalFieldInfo fieldinfo;
+
+ // This is true when the field is defined. Cannot be false when this field
+ // is not fixed, because non-fixed fields are deleted from the list when undefined.
+ private bool isdefined;
+
+ // Type
+ private UniversalFieldType fieldtype;
+
+ #endregion
+
+ #region ================== Properties
+
+ public bool IsFixed { get { return isfixed; } }
+ public bool IsDefined { get { return isdefined; } }
+ public UniversalFieldType Type { get { return fieldtype; } }
+ public UniversalFieldInfo Info { get { return fieldinfo; } }
+
+ #endregion
+
+ #region ================== Constructor / Disposer
+
+ // Constructor for a fixed, undefined field
+ public FieldsEditorRow(DataGridView view, UniversalFieldInfo fixedfield)
+ {
+ // Undefined
+ this.DefaultCellStyle.ForeColor = SystemColors.GrayText;
+ isdefined = false;
+
+ // Fixed
+ this.fieldinfo = fixedfield;
+ isfixed = true;
+
+ // Type
+ this.fieldtype = fixedfield.Type;
+
+ // Make all cells
+ base.CreateCells(view);
+
+ // Setup property cell
+ this.Cells[0].Value = fixedfield.Name;
+ this.Cells[0].ReadOnly = true;
+
+ // Setup type cell
+ this.Cells[1].Value = fixedfield.Type.ToString();
+ this.Cells[1].ReadOnly = true;
+
+ // Setup value cell
+ this.Cells[2].Value = fixedfield.DefaultStr;
+
+ // We have no destructor
+ GC.SuppressFinalize(this);
+ }
+
+ // Constructor for a non-fixed, defined field
+ public FieldsEditorRow(DataGridView view, string name, UniversalFieldType type, object value)
+ {
+ // Defined
+ this.DefaultCellStyle.ForeColor = SystemColors.WindowText;
+ isdefined = true;
+
+ // Non-fixed
+ isfixed = false;
+
+ // Type
+ this.fieldtype = type;
+
+ // Make all cells
+ base.CreateCells(view);
+
+ // Setup property cell
+ this.Cells[0].Value = name;
+ this.Cells[0].ReadOnly = true;
+
+ // Setup type cell
+ this.Cells[1].Value = type.ToString();
+ this.Cells[1].ReadOnly = false;
+
+ // Setup value cell
+ this.Cells[2].Value = value;
+
+ // We have no destructor
+ GC.SuppressFinalize(this);
+ }
+
+ #endregion
+
+ #region ================== Methods
+
+ // This is called when a cell is edited
+ public void CellChanged()
+ {
+ // Update type from cell
+ try { fieldtype = (UniversalFieldType)Enum.Parse(typeof(UniversalFieldType), this.Cells[1].Value.ToString(), true); }
+ catch(Exception e) { this.Cells[1].Value = fieldtype.ToString(); }
+ }
+
+ // This undefines the field
+ // ONLY VALID FOR FIXED FIELDS
+ // You should just delete non-fixed fields
+ public void Undefine()
+ {
+ // Must be fixed!
+ if(!isfixed) throw new InvalidOperationException();
+
+ // Now undefined
+ this.Cells[2].Value = fieldinfo.DefaultStr;
+ this.DefaultCellStyle.ForeColor = SystemColors.GrayText;
+ isdefined = false;
+ }
+
+ // This defines the field
+ public void Define(object value)
+ {
+ // Now defined
+ this.Cells[2].Value = value;
+ this.DefaultCellStyle.ForeColor = SystemColors.WindowText;
+ isdefined = true;
+ }
+
+ #endregion
+ }
+}
diff --git a/Source/Interface/LinedefEditForm.Designer.cs b/Source/Interface/LinedefEditForm.Designer.cs
index dce7a483..ac115ac5 100644
--- a/Source/Interface/LinedefEditForm.Designer.cs
+++ b/Source/Interface/LinedefEditForm.Designer.cs
@@ -83,6 +83,8 @@ namespace CodeImp.DoomBuilder.Interface
this.fronthigh = new CodeImp.DoomBuilder.Interface.TextureSelectorControl();
this.frontoffsety = new CodeImp.DoomBuilder.Interface.NumericTextbox();
this.frontoffsetx = new CodeImp.DoomBuilder.Interface.NumericTextbox();
+ this.tabPage3 = new System.Windows.Forms.TabPage();
+ this.fieldslist = new CodeImp.DoomBuilder.Interface.FieldsEditorControl();
label2 = new System.Windows.Forms.Label();
taglabel = new System.Windows.Forms.Label();
label3 = new System.Windows.Forms.Label();
@@ -105,6 +107,7 @@ namespace CodeImp.DoomBuilder.Interface
this.tabPage2.SuspendLayout();
this.backgroup.SuspendLayout();
this.frontgroup.SuspendLayout();
+ this.tabPage3.SuspendLayout();
this.SuspendLayout();
//
// label2
@@ -484,6 +487,7 @@ namespace CodeImp.DoomBuilder.Interface
| System.Windows.Forms.AnchorStyles.Right)));
this.tabs.Controls.Add(this.tabPage1);
this.tabs.Controls.Add(this.tabPage2);
+ this.tabs.Controls.Add(this.tabPage3);
this.tabs.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.tabs.Location = new System.Drawing.Point(10, 10);
this.tabs.Margin = new System.Windows.Forms.Padding(1);
@@ -516,7 +520,7 @@ namespace CodeImp.DoomBuilder.Interface
this.tabPage2.Location = new System.Drawing.Point(4, 23);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(5);
- this.tabPage2.Size = new System.Drawing.Size(533, 374);
+ this.tabPage2.Size = new System.Drawing.Size(533, 381);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Sidedefs";
this.tabPage2.UseVisualStyleBackColor = true;
@@ -699,6 +703,24 @@ namespace CodeImp.DoomBuilder.Interface
this.frontoffsetx.TabIndex = 8;
this.frontoffsetx.Enter += new System.EventHandler(this.SelectAllText);
//
+ // tabPage3
+ //
+ this.tabPage3.Controls.Add(this.fieldslist);
+ this.tabPage3.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.tabPage3.Location = new System.Drawing.Point(4, 23);
+ this.tabPage3.Name = "tabPage3";
+ this.tabPage3.Size = new System.Drawing.Size(533, 381);
+ this.tabPage3.TabIndex = 2;
+ this.tabPage3.Text = "Custom";
+ this.tabPage3.UseVisualStyleBackColor = true;
+ //
+ // fieldslist
+ //
+ this.fieldslist.Location = new System.Drawing.Point(12, 12);
+ this.fieldslist.Name = "fieldslist";
+ this.fieldslist.Size = new System.Drawing.Size(508, 357);
+ this.fieldslist.TabIndex = 0;
+ //
// LinedefEditForm
//
this.AcceptButton = this.apply;
@@ -732,6 +754,7 @@ namespace CodeImp.DoomBuilder.Interface
this.backgroup.PerformLayout();
this.frontgroup.ResumeLayout(false);
this.frontgroup.PerformLayout();
+ this.tabPage3.ResumeLayout(false);
this.ResumeLayout(false);
}
@@ -780,5 +803,7 @@ namespace CodeImp.DoomBuilder.Interface
private System.Windows.Forms.Label arg4label;
private System.Windows.Forms.Label arg2label;
private System.Windows.Forms.Label arg3label;
+ private System.Windows.Forms.TabPage tabPage3;
+ private FieldsEditorControl fieldslist;
}
}
\ No newline at end of file
diff --git a/Source/Interface/LinedefEditForm.cs b/Source/Interface/LinedefEditForm.cs
index 5268c2eb..842affe2 100644
--- a/Source/Interface/LinedefEditForm.cs
+++ b/Source/Interface/LinedefEditForm.cs
@@ -53,6 +53,9 @@ namespace CodeImp.DoomBuilder.Interface
// Fill activations list
activation.Items.AddRange(General.Map.Config.LinedefActivates.ToArray());
+ // Fill universal fields list
+ fieldslist.ListFixedFields(General.Map.Config.LinedefFields);
+
// Initialize image selectors
fronthigh.Initialize();
frontmid.Initialize();
diff --git a/Source/Map/Linedef.cs b/Source/Map/Linedef.cs
index 05331519..3d4a4dba 100644
--- a/Source/Map/Linedef.cs
+++ b/Source/Map/Linedef.cs
@@ -72,6 +72,9 @@ namespace CodeImp.DoomBuilder.Map
private int tag;
private byte[] args;
+ // Additional fields
+ private SortedList fields;
+
// Selections
private bool selected;
@@ -99,6 +102,7 @@ namespace CodeImp.DoomBuilder.Map
public int AngleDeg { get { return (int)(angle * Angle2D.PIDEG); } }
public Rectangle Rect { get { return rect; } }
public byte[] Args { get { return args; } }
+ public SortedList Fields { get { return fields; } }
#endregion
@@ -187,6 +191,7 @@ namespace CodeImp.DoomBuilder.Map
l.flags = flags;
l.tag = tag;
l.updateneeded = true;
+ if(fields != null) l.MakeFields(fields);
}
// This attaches a sidedef on the front
@@ -275,6 +280,23 @@ 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/Sector.cs b/Source/Map/Sector.cs
index c1fcc287..a64d9000 100644
--- a/Source/Map/Sector.cs
+++ b/Source/Map/Sector.cs
@@ -69,6 +69,9 @@ namespace CodeImp.DoomBuilder.Map
// Triangulation
private bool updateneeded;
private TriangleList triangles;
+
+ // Additional fields
+ private SortedList fields;
// Disposing
private bool isdisposed = false;
@@ -95,6 +98,7 @@ namespace CodeImp.DoomBuilder.Map
public bool UpdateNeeded { get { return updateneeded; } set { updateneeded |= value; } }
public Sector Clone { get { return clone; } set { clone = value; } }
public TriangleList Triangles { get { return triangles; } set { triangles = value; } }
+ public SortedList Fields { get { return fields; } }
#endregion
@@ -160,6 +164,7 @@ namespace CodeImp.DoomBuilder.Map
s.effect = effect;
s.tag = tag;
s.brightness = brightness;
+ if(fields != null) s.MakeFields(fields);
}
// This attaches a sidedef and returns the listitem
@@ -210,6 +215,23 @@ 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
// This updates all properties
diff --git a/Source/Map/Sidedef.cs b/Source/Map/Sidedef.cs
index e485ac1c..b18a6c45 100644
--- a/Source/Map/Sidedef.cs
+++ b/Source/Map/Sidedef.cs
@@ -58,6 +58,9 @@ namespace CodeImp.DoomBuilder.Map
private long longtexnamehigh;
private long longtexnamemid;
private long longtexnamelow;
+
+ // Additional fields
+ private SortedList fields;
// Disposing
private bool isdisposed = false;
@@ -81,6 +84,7 @@ namespace CodeImp.DoomBuilder.Map
public long LongHighTexture { get { return longtexnamehigh; } }
public long LongMiddleTexture { get { return longtexnamemid; } }
public long LongLowTexture { get { return longtexnamelow; } }
+ public SortedList Fields { get { return fields; } }
#endregion
@@ -151,6 +155,7 @@ namespace CodeImp.DoomBuilder.Map
s.longtexnamehigh = longtexnamehigh;
s.longtexnamemid = longtexnamemid;
s.longtexnamelow = longtexnamelow;
+ if(fields != null) s.MakeFields(fields);
}
// This copies textures to another sidedef
@@ -204,6 +209,23 @@ 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 609ff855..c6076e4b 100644
--- a/Source/Map/Thing.cs
+++ b/Source/Map/Thing.cs
@@ -68,6 +68,9 @@ namespace CodeImp.DoomBuilder.Map
// Selections
private bool selected;
+
+ // Additional fields
+ private SortedList fields;
// Disposing
private bool isdisposed = false;
@@ -94,6 +97,7 @@ namespace CodeImp.DoomBuilder.Map
public int ZOffset { get { return zoffset; } }
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
@@ -155,6 +159,7 @@ namespace CodeImp.DoomBuilder.Map
t.color = color;
t.iconoffset = iconoffset;
args.CopyTo(t.args, 0);
+ if(fields != null) t.MakeFields(fields);
}
// This determines which sector the thing is in and links it
@@ -198,6 +203,23 @@ 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/Vertex.cs b/Source/Map/Vertex.cs
index 2dea7e3d..1a627c9f 100644
--- a/Source/Map/Vertex.cs
+++ b/Source/Map/Vertex.cs
@@ -59,6 +59,9 @@ namespace CodeImp.DoomBuilder.Map
// Cloning
private Vertex clone;
+
+ // Additional fields
+ private SortedList fields;
// Disposing
private bool isdisposed = false;
@@ -75,6 +78,7 @@ namespace CodeImp.DoomBuilder.Map
public bool IsDisposed { get { return isdisposed; } }
public bool Selected { get { return selected; } set { selected = value; } }
public Vertex Clone { get { return clone; } set { clone = value; } }
+ public SortedList Fields { get { return fields; } }
#endregion
@@ -145,8 +149,35 @@ 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 copies all properties to another thing
+ public void CopyPropertiesTo(Vertex v)
+ {
+ // Copy properties
+ v.x = x;
+ v.y = y;
+ v.pos = pos;
+ if(fields != null) v.MakeFields(fields);
+ }
+
// This returns the distance from given coordinates
public float DistanceToSq(Vector2D p)
{