GZDoom Builder 1.08:

Added Bridge mode.
Documented all GZDoom Builder specific features.
Crash fix in 1.07e was not implemented properly...
This commit is contained in:
MaxED 2012-06-19 13:12:28 +00:00
parent acb4daa3b1
commit 998d1d7dde
60 changed files with 2027 additions and 41 deletions

View file

@ -220,5 +220,69 @@
</OBJECT>
</UL>
</UL>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="GZDoom Builder manual">
<param name="Local" value="gz_introduction.html">
</OBJECT>
<UL>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Features">
<param name="Local" value="gz_features.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="New settings">
<param name="Local" value="gz_settings.html">
</OBJECT>
<UL>
</UL>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="New editing modes">
<param name="Local" value="gz_editmodes.html">
</OBJECT>
<UL>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Draw Rectangle mode">
<param name="Local" value="gz_drawrect.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Draw Ellipse mode">
<param name="Local" value="gz_drawellipse.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Bridge mode">
<param name="Local" value="gz_drawbridge.html">
</OBJECT>
</UL>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="New actions">
<param name="Local" value="gz_actions.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="GLDEFS and (Z)MAPINFO support">
<param name="Local" value="gz_gldefs.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="New settings in game configurations">
<param name="Local" value="gz_cfg_settings.html">
</OBJECT>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Plugins">
<param name="Local" value="gz_plugins.html">
</OBJECT>
<UL>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Color Picker plugin">
<param name="Local" value="gz_plug_colorpicker.html">
</OBJECT>
</UL>
<LI> <OBJECT type="text/sitemap">
<param name="Name" value="Frequently asked questions">
<param name="Local" value="gz_faq.html">
</OBJECT>
</UL>
</UL>
</UL>
</BODY></HTML>

View file

@ -19,6 +19,7 @@ default="Doom Builder Reference Manual","Contents.hhc","Index.hhk","introduction
[FILES]
introduction.html
header.gif
gz_header.gif
editingmodes.html
userinterface.html
configurations.html

View file

@ -7,7 +7,7 @@ body
padding: 0 0 0 0;
}
#title
#title, #gz_title
{
background: #f4f4f4 url(header.gif) bottom right no-repeat;
color: #515151;
@ -20,6 +20,12 @@ body
border-bottom-width: 2px;
}
#gz_title
{
background: #f4f4f4 url(gz_header.gif) bottom right no-repeat;
height: 52px;
}
#contents
{
background: #ffffff;

BIN
Help/gz_BridgeMode.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

136
Help/gz_actions.html Normal file
View file

@ -0,0 +1,136 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>GZDoom Builder features</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title">
<h1>Actions</h1>
</div>
<div id="contents">
<h2>List of new actions avaliable in GZDoom Builder:</h2>
<p> You can bind these actions to keyboard shortcuts in <strong>Preferences (F5) -> Controls</strong><br />
<h2><strong>Drawing:</strong></h2>
<table border="0" cellspacing="3" cellpadding="3">
<tr>
<td width="130"><strong>Name:</strong></td>
<td width="130"><div align="center"><strong>Default shortcut:</strong></div></td>
<td><strong>Description:</strong></td>
</tr>
<tr>
<td><a href="gz_drawrect.html">Start Rectangle Drawing</a></td>
<td><div align="center">Ctrl-Shift-D</div></td>
<td>Starts drawing rectangle. Increase / Decrease Sudivision Level and Increase / Decrease Corners Bevel actions are avaliable in this mode.</td>
</tr>
<tr>
<td><a href="gz_drawrect.html">Start Ellipse Drawing</a></td>
<td><div align="center">Ctrl-Alt-D</div></td>
<td>Starts drawing ellipse. Increase / Decrease Sudivision Level and Increase / Decrease Corners Bevel actions are avaliable in this mode.</td>
</tr>
<tr>
<td><a href="gz_drawrect.html">Bridge Mode</a></td>
<td><div align="center">Ctrl-B</div></td>
<td>Select two lines or two series of lines, then activate this tool to draw a bezier path between them. Increase / Decrease Sudivision Level actions are avaliable in this mode.</td>
</tr>
<tr>
<td>Increase Sudivision Level</td>
<td><div align="center">-</div></td>
<td>Increases subdivision level in Rectangle and Ellipse Drawing Modes.</td>
</tr>
<tr>
<td>Decrease Sudivision Level</td>
<td><div align="center">-</div></td>
<td>Decreases subdivision level in Rectangle and Ellipse Drawing Modes.</td>
</tr>
<tr>
<td>Increase Corners Bevel</td>
<td><div align="center">-</div></td>
<td>Increase corners bevel in Rectangle Drawing Modes. Bevel can be negative.</td>
</tr>
<tr>
<td>Decrease Corners Bevel</td>
<td><div align="center">-</div></td>
<td>Decreases corners bevel in Rectangle Drawing Modes. Bevel can be negative.</td>
</tr>
</table>
<br />
<h2><strong>GZDoom Builder:</strong></h2>
<table border="0" cellspacing="3" cellpadding="3">
<tr>
<td width="130"><strong>Name:</strong></td>
<td width="130"><div align="center"><strong>Default shortcut:</strong></div></td>
<td><strong>Description:</strong></td>
</tr>
<tr>
<td>Toggle models rendering</td>
<td><div align="center">-</div></td>
<td>Toggles models rendering.</td>
</tr>
<tr>
<td>Toggle dynamic lights rendering</td>
<td><div align="center">-</div></td>
<td>Toggles dynamic lights rendering.</td>
</tr>
<tr>
<td>Toggle dynamic lights animation</td>
<td><div align="center">-</div></td>
<td>Toggles dynamic lights animation.</td>
</tr>
<tr>
<td>Toggle fog rendering</td>
<td><div align="center">-</div></td>
<td>Toggles fog rendering.</td>
</tr>
<tr>
<td>Render selected/all models</td>
<td><div align="center">-</div></td>
<td>Render all models / render only models for selected things.</td>
</tr>
<tr>
<td>Toggle GZDoom effects</td>
<td><div align="center">-</div></td>
<td>Toggles models, dynamic lights and fog rendering.</td>
</tr>
</table>
<br />
<h2><strong>Tools:</strong></h2>
<table border="0" cellspacing="3" cellpadding="3">
<tr>
<td width="130"><strong>Name:</strong></td>
<td width="130"><div align="center"><strong>Default shortcut:</strong></div></td>
<td><strong>Description:</strong></td>
</tr>
<tr>
<td>Reload <a id="modeldef" href="gz_gldefs.html">MODELDEF</a></td>
<td><div align="center">-</div></td>
<td>Reloads MODELDEF. Useful when resource files have been changed outside of Doom Builder (this action can be also found in <strong>Tools</strong> menu).</td>
</tr>
<tr>
<td>Reload <a id="gldefs" href="gz_gldefs.html">GLDEFS</a></td>
<td><div align="center">-</div></td>
<td>Reloads GLDEFS. Useful when resource files have been changed outside of Doom Builder (this action can be also found in <strong>Tools</strong> menu).</td>
</tr>
<tr>
<td>Reload <a id="mapinfo" href="gz_mapinfo.html">(Z)MAPINFO</a></td>
<td><div align="center">-</div></td>
<td>Reloads (Z)MAPINFO. Useful when resource files have been changed outside of Doom Builder (this action can be also found in <strong>Tools</strong> menu).</td>
</tr>
<tr>
<td>Open <a href="gz_plug_colorpicker.html">Color picker</a></td>
<td><div align="center">K</div></td>
<td>Select dynamic light thing(s) or sector(s), then use this panel to set light properties quickly.</td>
</tr>
<tr>
<td><a id="newtestmap"></a>Test map from current position</td>
<td><div align="center">Ctrl-F9</div></td>
<td>Starts the game and loads this map for playing. Player start is placed either at cursor position (in 2D-modes) or at camera position (in Visual Modes).</td>
</tr>
</table>
</p>
</div>
</body>

BIN
Help/gz_bridge1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
Help/gz_bridge2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
Help/gz_bridge3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
Help/gz_bridge_copy.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

BIN
Help/gz_bridge_flip.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
Help/gz_bridge_mirror.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
Help/gz_bridge_settings.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

BIN
Help/gz_bridge_tex1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
Help/gz_bridge_tex1_3d.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 KiB

BIN
Help/gz_bridge_tex2_3d.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

BIN
Help/gz_bridge_tex3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
Help/gz_bridge_tex4_3d.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 KiB

25
Help/gz_cfg_settings.html Normal file
View file

@ -0,0 +1,25 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Template</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title">
<h1>GZDoom Builder-specific settings in game configurations</h1>
</div>
<div id="contents">
<p><b>basegame</b> - indicates on which game current configuration is based. Used to load game-specific GLDEFS lumps (DOOMDEFS, HTICDEFS, HEXNDEFS or STRFDEFS)</br>
<b>Possile values:</b> 0 (DOOM), 1 (HERETIC), 2 (HEXEN) or 3 (STRIFE).</br>
<b>Example:</b> <code>basegame = 0;</code></p>
</div>
</body>

BIN
Help/gz_colorpicker.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

107
Help/gz_drawbridge.html Normal file
View file

@ -0,0 +1,107 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Template</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title"><h1>Bridge Mode</h1></div>
<div id="contents">
<p>
This mode lets you connect parts of existing geometry using Bezier curves.<br>
<b>Found in:</b> Preferences -> Controls -> Drawing.<br>
<b>Default key:</b> Ctrl-B.<br>
<b>Additional actions:</b> Increase Sudivision Level, Decrease Sudivision Level. You can hold <strong>Shift</strong> while dragging a handle to turn grid snapping off.<br>
<table width="100%" border="0" cellspacing="3" cellpadding="3">
<tr>
<td width="33%"><b>Usage:</b> Select two linedefs or two groups of linedefs: </td>
<td width="33%">Then activate Bridge mode using keyboard shortcut or tool button (<img align="texttop" src="gz_BridgeMode.png" />):</td>
<td>Make some changes, then press OK button or Enter to accept, or Cancel/Esc to cancel:</td>
</tr>
<tr>
<td align="center"><img src="gz_bridge1.jpg" /></td>
<td align="center"><img src="gz_bridge2.jpg" /></td>
<td align="center"><img src="gz_bridge3.jpg" /></td>
</tr>
</table>
<h2>Options window</h2>
<table width="100%" border="0" cellspacing="3" cellpadding="3">
<tr>
<td valign="top"><img src="gz_bridge_settings.jpg" /></td>
<td><b>Align floor / Align ceiling dropdowns</b> let you choose how the heights of created sectors are <a href="#interp_modes">interpolated</a>.<br>
<b>Brightness dropdown</b> let you choose how the brightness of created sectors is interpolated.<br>
<b>Subdivisions</b> control how many subdivisions bridge has. You can also use "Increase Subdivisions" and "Decrease Subdivisions" actions to control this using keyboard shortcuts.<br>
<br>
Activate <b>Mirror mode</b> to mirror paired handle movement:<br>
<img style="display:block" src="gz_bridge_mirror.jpg" /><br>
Activate <b>Copy mode</b> to copy paired handle movement:<br>
<img style="display:block" src="gz_bridge_copy.jpg" /><br>
If a shape crosses itself, you can press <b>"Flip Lines"</b> button to fix this:
<img style="display:block" src="gz_bridge_flip.jpg" /><br>
<br></td>
</tr>
</table>
<h2>Interpolation modes:<a id="interp_modes"></a></h2>
<table width="100%" border="0" cellspacing="3" cellpadding="3">
<tr>
<td width="200px">&nbsp;</td>
<td><strong>Highest ceiling</strong></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><strong>Lowest floor</strong></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><strong>Linear interpolation</strong></td>
</tr>
<tr>
<td><img align="middle" src="gz_bridge_easeInSine.jpg" /></td>
<td><b>EaseInSine interpolation</b> - interpolates heights using sinusoidal (sin(t)) easing in.</td>
</tr>
<tr>
<td><img align="middle" src="gz_bridge_easeOutSine.jpg" /></td>
<td><b>EaseOutSine interpolation</b> - interpolates heights using sinusoidal (sin(t)) easing out.</td>
</tr>
<tr>
<td><img align="middle" src="gz_bridge_easeInOutSine.jpg" /></td>
<td><b>EaseInOutSine interpolation</b> - interpolates heights using sinusoidal (sin(t)) easing in/out.</td>
</tr>
</table>
<h2>Setting lower/upper textures:</h2>
If you are going to connect sectors with different ceiling and/or floor heights, you'll generally want to set upper and/or lower textures. To do this, set upper or lower textures to linedefs, which will be used to define bridge shape. <br>Let's say we want to make a stairway out of these lines:
<table border="0" cellspacing="3" cellpadding="3">
<tr>
<td><b>2D-view:</b></td>
<td><b>3D-view:</b></td>
</tr>
<tr>
<td valign="top"><img src="gz_bridge_tex1.jpg" /></td>
<td><img src="gz_bridge_tex1_3d.jpg" /></td>
</tr>
</table>
<br>
If you bridge these linedefs right now, you'll have lots of unset textures:
<br>
<img src="gz_bridge_tex2_3d.jpg" />
<br><br>
Instead of setting them all by hand, set upper and lower textures of lines, which will be used to create this shape (you need to set them only to one linedef out of pair):
<br>
<img src="gz_bridge_tex3.jpg" />
<br><br>
If you bridge linedefs now, all upper/lower textures will be set:
<br>
<img src="gz_bridge_tex4_3d.jpg" />
</p>
</div>
</body>

37
Help/gz_drawellipse.html Normal file
View file

@ -0,0 +1,37 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Draw Ellipse mode</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title"><h1>Draw Ellipse mode</h1></div>
<div id="contents">
<p>
This mode lets you draw various ellipsoid shapes.<br>
<b>Found in:</b> Preferences -> Controls -> Drawing.<br>
<b>Default key:</b> Ctrl-Alt-D.<br>
<b>Additional actions:</b> Increase Sudivision Level, Decrease Sudivision Level.<br><br>
You can activate this mode by pressing Alt-Shift-D (default key).<br>
If you bind keys to "Increase / Decrease Sudivision Level" actions in Preferences -> Controls -> Drawing, you can use them to control the number of sides ellipse has:
<br>
<img src="gz_ell1.jpg" />
<br>
Negative bevel values are also supported:
<br>
<img src="gz_ell2.jpg" />
<br>
Bevel ammount is based on current grid size.<br><br>
<b>NOTE:</b> I suggest you bind these actions to Ctrl+ScrollUp/ScrollDown, Shift+ScrollUp/ScrollDown or something similar. I can't bind default shortcuts for these actions to these keys, because they are already used in Visual Modes.
</p>
</div>
</body>

37
Help/gz_drawrect.html Normal file
View file

@ -0,0 +1,37 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Draw Rectangle mode</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title"><h1>Draw Rectangle mode</h1></div>
<div id="contents">
<p>
This mode lets you draw various rectangle shapes.<br>
<b>Found in:</b> Preferences -> Controls -> Drawing.<br>
<b>Default key:</b> Ctrl-Shift-D.<br>
<b>Additional actions:</b> Increase Sudivision Level, Decrease Sudivision Level.<br><br>
You can activate this mode by pressing Ctrl-Shift-D (default key).<br>
If you bind keys to "Increase / Decrease Sudivision Level" and "Increase / Decrease Corners Bevel" actions in Preferences -> Controls -> Drawing, you can use them to draw rectangles with beveled corners:
<br>
<img src="gz_rect1.jpg" />
<br>
Negative bevel values are also supported:
<br>
<img src="gz_rect2.jpg" />
<br>
Bevel ammount is based on current grid size.<br><br>
<b>NOTE:</b> I suggest you bind these actions to Ctrl+ScrollUp/ScrollDown, Shift+ScrollUp/ScrollDown or something similar. I can't bind default shortcuts for these actions to these keys, because they are already used in Visual Modes.
</p>
</div>
</body>

25
Help/gz_editmodes.html Normal file
View file

@ -0,0 +1,25 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>New editing modes</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title"><h1>New editing modes</h1></div>
<div id="contents">
<p>To help you create things faster, GZDoom Builder adds several new editing modes:</br></br>
<a href="gz_drawrect.html">Draw Rectangle Mode</a></br>
<a href="gz_drawellipse.html">Draw Ellipse Mode</a></br>
<a href="gz_drawbridge.html">Bridge Mode</a>
</p>
</div>
</body>

BIN
Help/gz_ell1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

BIN
Help/gz_ell2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

22
Help/gz_faq.html Normal file
View file

@ -0,0 +1,22 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>GZDoom Builder features</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title"><h1>Frequently asked questions</h1></div>
<div id="contents">
<p><strong>Q:</strong> When I create a new map, I see only Doom-related game configuratopns. Where are configurations for other games?<br />
<strong>A:</strong> Copy &quot;&lt;EngineName&gt;_&lt;Game&gt;&lt;MapType&gt;.cfg&quot; from &quot;&lt;GZDoom Builder&gt;\Configurations\Configs for other games\&quot; to &quot;&lt;GZDoom Builder&gt;\Configurations\&quot;.</p>
</div>
</body>

36
Help/gz_features.html Normal file
View file

@ -0,0 +1,36 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>GZDoom Builder features</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title"><h1>GZDoom Builder features</h1></div>
<div id="contents">
<p>
<h2>List of new features avaliable in GZDoom Builder:</h2>
<ul>
<li>Dynamic lights (all types) are rendered in Visual modes.</li>
<li>Dynamic lights defined in GLDEFS are rendered in Visual modes.</li>
<li>Animated lights.</li>
<li>Partial <a href="gz_gldefs.html">GLDEFS</a> and <a href="gz_mapinfo.html">(Z)MAPINFO support.</a></li>
<li>Fog rendering (including colored fog in maps in UDMF format).</li>
<li><a href="gz_gldefs.html">MD2 and MD3 models</a> rendering in 2D and 3D modes.</li>
<li><a href="gz_drawrect.html">Draw Rectangle</a>, <a href="gz_drawellipse.html">Draw Ellipse</a> and <a href="gz_drawbridge.html">Bridge</a> modes.</li>
<li><a href="gz_actions.html#newtestmap">"Test Map from current position" feature.</a></li>
<li><a href="gz_settings.html">"Sync camera position between 2D and 3D modes" feature.</a></li>
<li>PNG image format support.</li>
<li><a href="gz_plug_colorpicker.html">Color Picker plugin.</a></li>
</ul>
</p>
</div>
</body>

30
Help/gz_gldefs.html Normal file
View file

@ -0,0 +1,30 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>GZDoom Builder features</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title">
<h1>GLDEFS and MODELDEF support</h1>
</div>
<div id="contents">
<p><b>If you are creating maps for Doom or Doom 2, you probably don't need to read this, since required information is already added for those games.</b><br /><br />
<b>To load models or dynamic lights defined in GLDEFS for things defined in configuration files:</b><br />
To display a model instead of thing sprite, or to attach a light defined in GLDEFS, my code needs to know a thing's class name (because that's how overrides are defined in MODELDEF and GLDEFS). Things defined in Doom Builder configuration files don't have this value. So, if you aren't using configs, which came with GZDoom Builder, or you are creating maps for games other than Doom and Doom 2, you need to add a new value named "class" to thing definition in config:<br />
<code style="color:#006600">3001<br />{<br />&nbsp; &nbsp;title = &quot;Imp&quot;;<br />&nbsp; &nbsp;sprite = &quot;TROOA2A8&quot;;<br />&nbsp; &nbsp;class = &quot;DoomImp&quot;; // &lt;- you need to add this value<br />}</code><br />
You can find class names for things on <a href="http://www.zdoom.org/wiki/Classes">ZDoom wiki</a><br /><br />
You can reload GLDEFS and MODELDEF by using "<a href="gz_actions.html#gldefs">Reload GLDEFS</a>" and "<a href="gz_actions.html#modeldef">Reload MODELDEF</a>" actions.
</p>
</div>
</body>

BIN
Help/gz_gzpanel.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

BIN
Help/gz_header.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

40
Help/gz_introduction.html Normal file
View file

@ -0,0 +1,40 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>GZDoom Builder introduction</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Introduction">
</object>
<div id="gz_title"><h1>Introduction</h1></div>
<div id="contents">
<p>
GZDoom Builder is a Doom Builder 2 fork, which aims to incorporate as many GZDoom features as possible. Currently it's the only map editor for Doom and games based on Doom engine, which supports 3d-models and dynamic lights.
<h2>Reference Manual</h2>
This is the Reference Manual for GZDoom Builder. You can use this manual to look up how the specific GZDoom Builder features work and what the specific modes and actions do. This manual is not a beginners tutorial that teaches you how to make maps.
<h2>Table of contents</h2>
<ul>
<li><a href="gz_features.html">Features</a></li>
<li><a href="gz_settings.html">New settings</a></li>
<li><a href="gz_editmodes.html">New editing modes</a></li>
<li><a href="gz_actions.html">New actions</a></li>
<li><a href="gz_gldefs.html">MODELDEF, GLDEFS</a> and <a href="gz_mapinfo.html">(Z)MAPINFO</a> support</li>
<li><a href="gz_cfg_settings.html">New settings in game configurations</a></li>
<li><a href="gz_plugins.html">Plugins</a></li>
<li><a href="gz_faq.html">Frequently asked questions</a></li>
</ul>
<h2>Notice from author:</h2>
English is not my first language, so there most likely are things which are explained in a strange or grammatically incorrect way. If you notice such things, please write me a <a href="http://forum.zdoom.org/ucp.php?i=pm&mode=compose&u=7012">personal message</a>, or leave a comment in the <a href="http://forum.zdoom.org/viewtopic.php?f=3&t=32392">Official GZDoom Builder thread</a> at zdoom.org.
</p>
</div>
</body>

31
Help/gz_mapinfo.html Normal file
View file

@ -0,0 +1,31 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>GZDoom Builder features</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title"><h1>(Z)MAPINFO support</h1></div>
<div id="contents">
<p>Several values from (Z)MAPINFO are used in Visual modes. List of supported properties:
<ul>
<li>fade</li>
<li>outsidefog</li>
<li> vertwallshade</li>
<li> horizwallshade</li>
<li> evenlighting</li>
<li> smoothlighting</li>
</ul>
You can reload (Z)MAPINFO by using "<a href="gz_actions.html#mapinfo">Reload (Z)MAPINFO</a>" action.
</p>
</div>
</body>

View file

@ -0,0 +1,32 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>GZDoom Builder features</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title"><h1>Color Picker plugin</h1></div>
<div id="contents">
<p>Color Picker plugin lets you edit Dynamic Lights properties and sector "lightcolor" and "fadecolor" properties quickly.<br />
<strong>Default key:</strong> K.<br />
<strong>Found in:</strong> Preferences -> Controls -> Tools -&gt; Open Color Picker.<br /><br />
<img style="float:left; margin-right:10px" src="gz_colorpicker.jpg"/><strong>To edit light properties:</strong><br />
Select some lights in 2D mode or (GZDoom) Visual Mode and click Color Picker button / press a shortcut key to open Color Picker window.<br />
You can enable <strong>Relative mode</strong> if you have several lights with different settings selected and want to scale them all up/down a bit.<br />
If nothing is selected in (GZDoom) Visual Mode, you can hilight a Light Thing and then open Color Picker window to edit it's properties.<br /><br />
<strong>To edit sector colors (UDMF only):</strong><br />
Select some sectors in 2D mode, or some surfaces in (GZDoom) Visual Mode, then open Color Picker window.
Sector color ("lightcolor" property) and Fade color ("fadecolor" property) can be set in this mode.
If nothing is selected in (GZDoom) Visual Mode, you can hilight a surface and then open Color Picker window to edit sector colors of sector, to which hilighted surface belongs.</p>
</div>
</body>

24
Help/gz_plugins.html Normal file
View file

@ -0,0 +1,24 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>GZDoom Builder features</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title"><h1>GZDoom Builder plugins</h1></div>
<div id="contents">
<p>
<h2>List of plugins made for GZDoom Builder:</h2>
</br><a href="gz_plug_colorpicker.html">Color Picker plugin.</a></br>
</p>
</div>
</body>

BIN
Help/gz_prefs1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

BIN
Help/gz_prefs2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

BIN
Help/gz_rect1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
Help/gz_rect2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

38
Help/gz_settings.html Normal file
View file

@ -0,0 +1,38 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>Template</title>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<link rel="stylesheet" type="text/css" href="default.css" media="screen" title="Default" />
</head>
<body>
<object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e">
<param name="keyword" value="Template">
</object>
<div id="gz_title"><h1>Settings</h1></div>
<div id="contents">
<p>There are several new options avaliable in GZDoom Builder's <strong>Preferences window</strong> (F5):</p>
<table valign="top" width="100%" border="0" cellspacing="3" cellpadding="3">
<tr valign="top">
<td width="477px"><img src="gz_prefs1.jpg" /></td>
<td><p><strong>1. Sync camera position between 2D and 3D modes:</strong> when enabled, GZDoom Builder will center 2D-mode on Visual Camera position when you leave Visual Mode, and will place Visual Camera at cursor position when you toggle from 2D-mode to Visual Mode (unless you have Visual Mode camera thing in your map).</p>
<p><strong>2. GZDoom toolbar:</strong> when enabled, GZDoom toolbar (<img align="baseline" src="gz_gzpanel.jpg" />) will be shown in main editing window.</p>
<p>&nbsp;</p></td>
</tr>
<tr valign="top">
<td><img src="gz_prefs2.jpg" /></td>
<td><p><strong>1. Model wireframe color:</strong> lets you choose a color, which is used to render model wireframe in 2D-mode.</p>
<p><strong>2. Maximum dynamic lights to render:</strong> lets you choose how many dynamic lights to render in visual mode. Decrease this to improve performance when Dynamic Lights Rendering is on. Possible values are [1..32].</p>
<p><strong>3. Dynamic light size:</strong> this option mimics GZDoom's &quot;light size&quot; option.</p>
<p><strong>4. Dynamic light intensity:</strong> this option mimics GZDoom's &quot;light intensity&quot; option.</p></td>
</tr>
</table>
</div>
</body>

View file

@ -5,6 +5,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Builder", "Builder.csproj",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BuilderModes", "..\Plugins\BuilderModes\BuilderModes.csproj", "{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColorPicker", "..\Plugins\ColorPicker\ColorPicker.csproj", "{A4761900-0EA3-4FE4-A919-847FD5080EFC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -35,6 +37,16 @@ Global
{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}.Release|Mixed Platforms.Build.0 = Release|x86
{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}.Release|x86.ActiveCfg = Release|x86
{B42D5AA0-F9A6-4234-9C4B-A05B11A64851}.Release|x86.Build.0 = Release|x86
{A4761900-0EA3-4FE4-A919-847FD5080EFC}.Debug|Any CPU.ActiveCfg = Debug|x86
{A4761900-0EA3-4FE4-A919-847FD5080EFC}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
{A4761900-0EA3-4FE4-A919-847FD5080EFC}.Debug|Mixed Platforms.Build.0 = Debug|x86
{A4761900-0EA3-4FE4-A919-847FD5080EFC}.Debug|x86.ActiveCfg = Debug|x86
{A4761900-0EA3-4FE4-A919-847FD5080EFC}.Debug|x86.Build.0 = Debug|x86
{A4761900-0EA3-4FE4-A919-847FD5080EFC}.Release|Any CPU.ActiveCfg = Release|x86
{A4761900-0EA3-4FE4-A919-847FD5080EFC}.Release|Mixed Platforms.ActiveCfg = Release|x86
{A4761900-0EA3-4FE4-A919-847FD5080EFC}.Release|Mixed Platforms.Build.0 = Release|x86
{A4761900-0EA3-4FE4-A919-847FD5080EFC}.Release|x86.ActiveCfg = Release|x86
{A4761900-0EA3-4FE4-A919-847FD5080EFC}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View file

@ -271,7 +271,7 @@ namespace CodeImp.DoomBuilder.Config
//mxd
int gt = (cfg.ReadSetting("basegame", (int)GameType.UNKNOWN));
gameType = ( (gt > 0 && gt < Gldefs.GLDEFS_LUMPS_PER_GAME.Length) ? (GameType)gt : GameType.UNKNOWN);
gameType = ( (gt > -1 && gt < Gldefs.GLDEFS_LUMPS_PER_GAME.Length) ? (GameType)gt : GameType.UNKNOWN);
enginename = cfg.ReadSetting("engine", "");
defaultsavecompiler = cfg.ReadSetting("defaultsavecompiler", "");

View file

@ -29,10 +29,8 @@ namespace CodeImp.DoomBuilder.GZBuilder
public static bool UDMF;
//public static float[] FogTable; // light to fog conversion table for black fog
//version
public const float Version = 1.07f;
public const float Version = 1.08f;
//debug console
#if DEBUG
@ -44,27 +42,7 @@ namespace CodeImp.DoomBuilder.GZBuilder
//bind actions
General.Actions.BindMethods(typeof(GZGeneral));
General.MainWindow.UpdateGZDoomPannel();
//create fog table
/*FogTable = new float[256];
byte gl_distfog = 255;
for (int i = 0; i < 256; i++) {
if (i < 164) {
FogTable[i] = (gl_distfog >> 1) + (gl_distfog) * (164 - i) / 164;
} else if (i < 230) {
FogTable[i] = (gl_distfog >> 1) - (gl_distfog >> 1) * (i - 164) / (230 - 164);
} else FogTable[i] = 0;
//if (i < 128) {
//distfogtable[1][i] = 6.f + (gl_distfog >> 1) + (gl_distfog) * (128 - i) / 48;
//} else if (i < 216) {
//distfogtable[1][i] = (216.f - i) / ((216.f - 128.f)) * gl_distfog / 10;
//} else distfogtable[1][i] = 0;
}*/
//float[] ft = FogTable;
//create console
#if DEBUG
ConsoleDocker cd = new ConsoleDocker();

View file

@ -1173,7 +1173,7 @@ namespace CodeImp.DoomBuilder.Rendering
//t.CameraDistance3D is actually squared distance, hence (t.LightRadius * t.LightRadius)
if (t.CameraDistance3D < (t.LightRadius * t.LightRadius) || isThingOnScreen(t.BoundingBox)) { //always render light if camera is within it's radius
if (Array.IndexOf(GZBuilder.GZGeneral.GZ_ANIMATED_LIGHT_TYPES, t.LightType) != -1)
t.UpdateBoundingBox(t.LightRadius, t.LightRadius * 2);
t.UpdateBoundingBox();//t.UpdateBoundingBox(t.LightRadius, t.LightRadius * 2);
thingsWithLight.Add(t);
}
}

View file

@ -14,7 +14,7 @@ categories
classic = "Classic Modes";
visual = "Visual Modes";
selecting = "Selecting";
gzdoombuilder = "GZDoomBuilder";
gzdoombuilder = "GZDoom Builder";
}
// This just defines which actions there are, what description they have and
@ -457,7 +457,7 @@ testmap
//mxd
testmapfromview
{
title = "Test Map from current position";
title = "Test map from current position";
category = "tools";
description = "Starts the game and loads this map for playing. Player start is placed either at cursor position (in 2D-Modes) or at camera position (in Visual Modes).";
allowkeys = true;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 KiB

After

Width:  |  Height:  |  Size: 221 KiB

View file

@ -274,9 +274,9 @@ namespace CodeImp.DoomBuilder.VisualModes
if (thing.IsModel) {
updateBoundingBoxForModel();
} else if (lightType != -1 && lightRadius > thing.Size) {
UpdateBoundingBox(lightRadius, lightRadius * 2);
updateBoundingBox(lightRadius, lightRadius * 2);
} else {
UpdateBoundingBox((int)thing.Size, thingHeight);
updateBoundingBox((int)thing.Size, thingHeight);
}
}
@ -352,18 +352,18 @@ namespace CodeImp.DoomBuilder.VisualModes
isGldefsLight = false;
lightInterval = -1;
updateLight(light_id);
UpdateBoundingBox(lightRadius, lightRadius * 2);
updateBoundingBox(lightRadius, lightRadius * 2);
//check if we have light from GLDEFS
} else if (General.Map.Data.GldefsEntries.ContainsKey(thing.Type)) {
isGldefsLight = true;
updateGldefsLight();
UpdateBoundingBox(lightRadius, lightRadius * 2);
updateBoundingBox(lightRadius, lightRadius * 2);
} else {
if (thing.IsModel) {
updateBoundingBoxForModel();
} else {
UpdateBoundingBox((int)thing.Size, thingHeight);
updateBoundingBox((int)thing.Size, thingHeight);
}
lightType = -1;
lightRadius = -1;
@ -380,7 +380,7 @@ namespace CodeImp.DoomBuilder.VisualModes
int light_id = Array.IndexOf(GZBuilder.GZGeneral.GZ_LIGHTS, thing.Type);
if (light_id != -1) {
updateLight(light_id);
UpdateBoundingBox(lightRadius, lightRadius * 2);
updateBoundingBox(lightRadius, lightRadius * 2);
}
}
@ -471,15 +471,16 @@ namespace CodeImp.DoomBuilder.VisualModes
double time = General.Clock.GetCurrentTime();
float rMin, rMax;
/*float rMin, rMax;
if (lightPrimaryRadius > lightSecondaryRadius) {
rMax = lightPrimaryRadius;
rMin = lightSecondaryRadius;
} else {
rMin = lightPrimaryRadius;
rMax = lightSecondaryRadius;
}
}*/
float rMin = Math.Min(lightPrimaryRadius, lightSecondaryRadius);
float rMax = Math.Max(lightPrimaryRadius, lightSecondaryRadius);
float diff = rMax - rMin;
//pulse
@ -508,7 +509,11 @@ namespace CodeImp.DoomBuilder.VisualModes
}
//mxd. update bounding box
public void UpdateBoundingBox(float width, float height) {
public void UpdateBoundingBox() {
updateBoundingBox(lightRadius, lightRadius * 2f);
}
private void updateBoundingBox(float width, float height) {
boundingBox = new Vector3[9];
boundingBox[0] = Center;
float h2 = height / 2.0f;

View file

@ -238,6 +238,7 @@
<EmbeddedResource Include="Resources\HeightsMode.png" />
</ItemGroup>
<ItemGroup>
<Compile Include="ClassicModes\BridgeMode.cs" />
<Compile Include="ClassicModes\DrawEllipseMode.cs" />
<Compile Include="ClassicModes\DrawRectangleMode.cs" />
<Compile Include="ErrorChecks\CheckMissingTextures.cs" />
@ -268,6 +269,12 @@
<Compile Include="FindReplace\FindVertexNumber.cs" />
<Compile Include="General\HintLabel.cs" />
<Compile Include="General\UndoGroup.cs" />
<Compile Include="Interface\BridgeModeForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Interface\BridgeModeForm.Designer.cs">
<DependentUpon>BridgeModeForm.cs</DependentUpon>
</Compile>
<Compile Include="Interface\EditSelectionPanel.cs">
<SubType>UserControl</SubType>
</Compile>
@ -317,8 +324,14 @@
<None Include="Resources\Text.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Interface\BridgeModeForm.resx">
<DependentUpon>BridgeModeForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Resources\Selection3.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources\BridgeMode.png" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View file

@ -0,0 +1,817 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Editing;
using CodeImp.DoomBuilder.Rendering;
using CodeImp.DoomBuilder.Geometry;
using CodeImp.DoomBuilder.Actions;
using CodeImp.DoomBuilder.Windows;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Plugins;
using CodeImp.DoomBuilder.BuilderModes.Interface;
namespace CodeImp.DoomBuilder.BuilderModes.ClassicModes {
[EditMode(DisplayName = "Bridge Mode",
SwitchAction = "bridgemode",
ButtonImage = "BridgeMode.png",
ButtonOrder = 51,
ButtonGroup = "002_tools",
AllowCopyPaste = false,
Volatile = true,
Optional = false)]
public class BridgeMode : BaseClassicMode {
private const float GRIP_SIZE = 9.0f;
private const float LINE_THICKNESS = 0.8f;
internal static int MAX_SUBDIVISIONS = 32;
internal static int MIN_SUBDIVISIONS = 0;
protected string undoName = "Bridge draw";
protected string shapeName = "mesh";
private Vector2D[] pointGroup1;
private Vector2D[] pointGroup2;
private SectorProperties[] sectorProps1;
private SectorProperties[] sectorProps2;
private float[] relLenGroup1;
private float[] relLenGroup2;
private ControlHandle[] controlHandles;
private int curControlHandle = -1;
private PixelColor handleColor;
private List<Vector2D[]> curves;
private int segmentsCount;
// Options
protected bool snaptogrid; // SHIFT to toggle
//tools form
private BridgeModeForm form;
public BridgeMode() {
// We have no destructor
GC.SuppressFinalize(this);
}
// Engaging
public override void OnEngage() {
base.OnEngage();
renderer.SetPresentation(Presentation.Standard);
//check selection
ICollection<Linedef> selection = General.Map.Map.GetSelectedLinedefs(true);
List<Line> lines = new List<Line>();
foreach (Linedef ld in selection) {
Line l = new Line(ld);
lines.Add(l);
}
//do we have valid selection?
if (!setup(lines)) {
FinishDraw();
return;
}
//show form
form = new BridgeModeForm();
form.OnCancelClick += new EventHandler(form_OnCancelClick);
form.OnOkClick += new EventHandler(form_OnOkClick);
form.OnFlipClick += new EventHandler(form_OnFlipClick);
form.OnSubdivisionChanged += new EventHandler(form_OnSubdivisionChanged);
form.Show(Form.ActiveForm);
General.Interface.FocusDisplay();
handleColor = General.Colors.BrightColors[new Random().Next(General.Colors.BrightColors.Length - 1)];
update();
}
// When select button is pressed
protected override void OnSelectBegin() {
base.OnSelectBegin();
//check if control handle is selected
for (int i = 0; i < 4; i++) {
if (mousemappos.x <= controlHandles[i].Position.x + GRIP_SIZE && mousemappos.x >= controlHandles[i].Position.x - GRIP_SIZE && mousemappos.y <= controlHandles[i].Position.y + GRIP_SIZE && mousemappos.y >= controlHandles[i].Position.y - GRIP_SIZE) {
curControlHandle = i;
General.Interface.SetCursor(Cursors.Cross);
return;
}
}
curControlHandle = -1;
}
// When select button is released
protected override void OnSelectEnd() {
base.OnSelectEnd();
General.Interface.SetCursor(Cursors.Default);
curControlHandle = -1;
}
// Mouse moves
public override void OnMouseMove(MouseEventArgs e) {
base.OnMouseMove(e);
if (curControlHandle != -1) {
ControlHandle handle = controlHandles[curControlHandle];
if (snaptogrid) {
handle.Position = DrawGeometryMode.GetCurrentPosition(mousemappos, false, true, renderer, new List<DrawnVertex>()).pos;
} else {
handle.Position = mousemappos;
}
if (form.MirrorMode) {
Vector2D pos = handle.RelativePosition;
//handle angle
float angle = (float)Math.Atan2(-pos.y, -pos.x) + (float)Math.PI / 2f;
//angle of line, connecting handles ControlledPoints
float dirAngle = -(float)Math.Atan2(handle.Pair.ControlledPoint.y - handle.ControlledPoint.y, handle.Pair.ControlledPoint.x - handle.ControlledPoint.x);
float length = (float)Math.Sqrt(Math.Pow(Math.Abs(pos.x), 2.0) + Math.Pow(Math.Abs(pos.y), 2.0));
float mirroredAngle = angle + dirAngle * 2.0f;
handle.Pair.RelativePosition = new Vector2D((float)Math.Sin(mirroredAngle) * length, (float)Math.Cos(mirroredAngle) * length);
} else if (form.CopyMode) {
handle.Pair.RelativePosition = handle.RelativePosition;
}
update();
}
}
// Accepted
public override void OnAccept() {
Cursor.Current = Cursors.AppStarting;
General.Settings.FindDefaultDrawSettings();
//get vertices
List<List<Vector2D[]>> shapes = getShapes();
List<List<List<DrawnVertex>>> drawShapes = new List<List<List<DrawnVertex>>>();
List<List<DrawnVertex>> shapesRow;
List<DrawnVertex> points;
//set stitch range
float stitchrange = BuilderPlug.Me.StitchRange;
BuilderPlug.Me.StitchRange = 0.1f;
for (int i = 0; i < shapes.Count; i++) {
shapesRow = new List<List<DrawnVertex>>();
for (int c = 0; c < shapes[i].Count; c++) {
points = new List<DrawnVertex>();
for (int p = 0; p < shapes[i][c].Length; p++)
points.Add(DrawGeometryMode.GetCurrentPosition(shapes[i][c][p], true, false, renderer, points));
shapesRow.Add(points);
}
drawShapes.Add(shapesRow);
}
//restore stitch range
BuilderPlug.Me.StitchRange = stitchrange;
//draw lines
if (drawShapes.Count > 0) {
// Make undo for the draw
General.Map.UndoRedo.CreateUndo("Bridge ("+form.Subdivisions+" subdivisions)");
string lowTexture = "-";
string highTexture = "-";
// Make the drawing
//sector row
for (int i = 0; i < drawShapes.Count; i++) {
//textures
lowTexture = sectorProps1[i].LowTexture != "-" ? sectorProps1[i].LowTexture : sectorProps2[i].LowTexture;
highTexture = sectorProps1[i].HighTexture != "-" ? sectorProps1[i].HighTexture : sectorProps2[i].HighTexture;
//sector in row
for (int c = 0; c < drawShapes[i].Count; c++) {
if (!Tools.DrawLines(drawShapes[i][c])) {
// Drawing failed
// NOTE: I have to call this twice, because the first time only cancels this volatile mode
General.Interface.DisplayStatus(StatusType.Warning, "Failed to create a Bezier Path...");
General.Map.UndoRedo.WithdrawUndo();
General.Map.UndoRedo.WithdrawUndo();
return;
}
List<Sector> newsectors = General.Map.Map.GetMarkedSectors(true);
//set floor/ceiling heights, lower/upper textures and brightness
foreach (Sector s in newsectors) {
SectorProperties sp = getSectorProperties(i, c);
s.Brightness = sp.Brightness;
s.FloorHeight = sp.FloorHeight;
s.CeilHeight = (sp.CeilingHeight < sp.FloorHeight ? sp.FloorHeight + 8 : sp.CeilingHeight);
foreach(Sidedef sd in s.Sidedefs){
if (sd.Line.Back != null && sd.Line.Front != null) {
sd.Line.Back.SetTextureLow(lowTexture);
sd.Line.Back.SetTextureHigh(highTexture);
sd.Line.Front.SetTextureLow(lowTexture);
sd.Line.Front.SetTextureHigh(highTexture);
}
}
}
}
}
General.Interface.DisplayStatus(StatusType.Action, "Created a Bridge with " + form.Subdivisions + " subdivisions.");
// Snap to map format accuracy
General.Map.Map.SnapAllToAccuracy();
// Clear selection
General.Map.Map.ClearAllSelected();
// Update cached values
General.Map.Map.Update();
// Update the used textures
General.Map.Data.UpdateUsedTextures();
// Map is changed
General.Map.IsChanged = true;
}
//close form
if (form != null)
form.Close();
// Done
Cursor.Current = Cursors.Default;
// Return to original mode
General.Editing.ChangeMode(General.Editing.PreviousStableMode.Name);
}
// Cancelled
public override void OnCancel() {
// Cancel base class
base.OnCancel();
//close form
if (form != null)
form.Dispose();
// Return to original mode
General.Editing.ChangeMode(General.Editing.PreviousStableMode.Name);
}
// When a key is released
public override void OnKeyUp(KeyEventArgs e) {
base.OnKeyUp(e);
if (snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) update();
}
// When a key is pressed
public override void OnKeyDown(KeyEventArgs e) {
base.OnKeyDown(e);
if (snaptogrid != (General.Interface.ShiftState ^ General.Interface.SnapToGrid)) update();
}
// This redraws the display
public override void OnRedrawDisplay() {
renderer.RedrawSurface();
// Render lines
if (renderer.StartPlotter(true)) {
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
renderer.PlotVerticesSet(General.Map.Map.Vertices);
renderer.Finish();
}
// Render things
if (renderer.StartThings(true)) {
renderer.RenderThingSet(General.Map.Map.Things, 1.0f);
renderer.Finish();
}
// Normal update
update();
}
//this checks if initial data is valid
private bool setup(List<Line> lines) {
if (!setupPointGroups(lines))
return false;
//setup control handles
Vector2D center1 = getPointOnLine(pointGroup1[0], pointGroup1[segmentsCount - 1], 0.5f);
Vector2D center2 = getPointOnLine(pointGroup2[0], pointGroup2[segmentsCount - 1], 0.5f);
Vector2D loc1 = getHandleLocation(pointGroup1[0], pointGroup1[segmentsCount - 1], center2);
Vector2D loc2 = getHandleLocation(pointGroup2[0], pointGroup2[segmentsCount - 1], center1);
ControlHandle ch1 = new ControlHandle();
ch1.ControlledPoint = pointGroup1[0];
ch1.RelativePosition = loc1;
ControlHandle ch2 = new ControlHandle();
ch2.ControlledPoint = pointGroup2[0];
ch2.RelativePosition = loc2;
ControlHandle ch3 = new ControlHandle();
ch3.ControlledPoint = pointGroup1[segmentsCount - 1];
ch3.RelativePosition = loc1;
ControlHandle ch4 = new ControlHandle();
ch4.ControlledPoint = pointGroup2[segmentsCount - 1];
ch4.RelativePosition = loc2;
ch1.Pair = ch3;
ch2.Pair = ch4;
ch3.Pair = ch1;
ch4.Pair = ch2;
controlHandles = new ControlHandle[] {ch1, ch2, ch3, ch4};
//setup relative segments lengths
relLenGroup1 = getRelativeLengths(pointGroup1);
relLenGroup2 = getRelativeLengths(pointGroup2);
return true;
}
private void update() {
if (renderer.StartOverlay(true)) {
snaptogrid = General.Interface.ShiftState ^ General.Interface.SnapToGrid;
PixelColor linesColor = snaptogrid ? General.Colors.Selection : General.Colors.Highlight;
//draw curves
Vector2D cp1, cp2;
curves = new List<Vector2D[]>();
for (int i = 0; i < segmentsCount; i++) {
cp1 = getPointOnLine(controlHandles[0].Position, controlHandles[2].Position, relLenGroup1[i]);
cp2 = getPointOnLine(controlHandles[1].Position, controlHandles[3].Position, relLenGroup2[i]);
curves.Add(getBezierCurve(pointGroup1[i], pointGroup2[i], cp1, cp2, form.Subdivisions));
for (int c = 1; c < curves[i].Length; c++ )
renderer.RenderLine(curves[i][c - 1], curves[i][c], LINE_THICKNESS, linesColor, true);
}
//draw connecting lines
if (form.Subdivisions > 1) {
for (int i = 1; i < segmentsCount; i++) {
for (int c = 1; c < form.Subdivisions; c++) {
renderer.RenderLine(curves[i-1][c], curves[i][c], LINE_THICKNESS, linesColor, true);
}
}
}
//draw vertices
float vsize = ((float)renderer.VertexSize + 1.0f) / renderer.Scale;
foreach(Vector2D[] points in curves){
for (int i = 1; i < points.Length - 1; i++ ) {
renderer.RenderRectangleFilled(new RectangleF(points[i].x - vsize, points[i].y - vsize, vsize * 2.0f, vsize * 2.0f), linesColor, true);
}
}
//draw handle lines
renderer.RenderLine(pointGroup1[0], controlHandles[0].Position, LINE_THICKNESS, handleColor, true);
renderer.RenderLine(pointGroup2[0], controlHandles[1].Position, LINE_THICKNESS, handleColor, true);
renderer.RenderLine(pointGroup1[segmentsCount - 1], controlHandles[2].Position, LINE_THICKNESS, handleColor, true);
renderer.RenderLine(pointGroup2[segmentsCount - 1], controlHandles[3].Position, LINE_THICKNESS, handleColor, true);
//draw handles
float gripsize = GRIP_SIZE / renderer.Scale;
for (int i = 0; i < 4; i++) {
RectangleF handleRect = new RectangleF(controlHandles[i].Position.x - gripsize * 0.5f, controlHandles[i].Position.y - gripsize * 0.5f, gripsize, gripsize);
renderer.RenderRectangleFilled(handleRect, General.Colors.Background, true);
renderer.RenderRectangle(handleRect, 2, General.Colors.Highlight, true);
}
renderer.Finish();
}
renderer.Present();
}
private SectorProperties getSectorProperties(int lineIndex, int sectorIndex) {
float delta = (float)sectorIndex / (float)form.Subdivisions;
delta += (1.0f - delta) / (float)form.Subdivisions;
SectorProperties sp = new SectorProperties();
sp.Brightness = intepolateValue(sectorProps1[lineIndex].Brightness, sectorProps2[lineIndex].Brightness, delta, form.BrightnessMode);
sp.FloorHeight = intepolateValue(sectorProps1[lineIndex].FloorHeight, sectorProps2[lineIndex].FloorHeight, delta, form.FloorAlignMode);
sp.CeilingHeight = intepolateValue(sectorProps1[lineIndex].CeilingHeight, sectorProps2[lineIndex].CeilingHeight, delta, form.CeilingAlignMode);
return sp;
}
//this returns a list of shapes to draw
private List<List<Vector2D[]>> getShapes() {
List<List<Vector2D[]>> shapes = new List<List<Vector2D[]>>();
for (int i = 1; i < segmentsCount; i++) {
List<Vector2D[]> segShapes = new List<Vector2D[]>();
for (int c = 1; c <= form.Subdivisions; c++) {
Vector2D p0 = curves[i - 1][c - 1];
Vector2D p1 = curves[i - 1][c];
Vector2D p2 = curves[i][c];
Vector2D p3 = curves[i][c - 1];
segShapes.Add(new Vector2D[] { p0, p1, p2, p3, p0 });
}
shapes.Add(segShapes);
}
return shapes;
}
//POINT OPS
//this returns an array of linedef lengths relative to total segment length
private float[] getRelativeLengths(Vector2D[] pointGroup) {
float[] relLenGroup = new float[pointGroup.Length];
relLenGroup[0] = 0.0f;
//get length and angle of line, which defines the shape
float length = getLineLength(pointGroup[0], pointGroup[segmentsCount - 1]);
float angle = (float)Math.Atan2(pointGroup[0].y - pointGroup[segmentsCount - 1].y, pointGroup[0].x - pointGroup[segmentsCount - 1].x);
float curAngle, diff, segLen;
Vector2D p0, p1;
//get relative length of every line
for (int i = 1; i < pointGroup.Length - 1; i++) {
p0 = pointGroup[i - 1];
p1 = pointGroup[i];
curAngle = (float)Math.Atan2(p0.y - p1.y, p0.x - p1.x);
diff = (angle + (float)Math.PI) - (curAngle + (float)Math.PI);
segLen = (int)(getLineLength(p0, p1) * Math.Cos(diff));
relLenGroup[i] = relLenGroup[i - 1] + segLen / length;
}
relLenGroup[pointGroup.Length - 1] = 1.0f;
return relLenGroup;
}
private float getLineLength(Vector2D p0, Vector2D p1) {
float vx = Math.Abs(p0.x - p1.x);
float vy = Math.Abs(p0.y - p1.y);
return (float)Math.Sqrt(vx * vx + vy * vy);
}
//this returns relative handle location
private Vector2D getHandleLocation(Vector2D start, Vector2D end, Vector2D direction) {
float angle = -(float)Math.Atan2(start.y - end.y, start.x - end.x);
float dirAngle = -(float)Math.Atan2(direction.y - start.y, direction.x - start.x);
float length = (float)Math.Sqrt(Math.Pow(Math.Abs(start.x - end.x), 2.0) + Math.Pow(Math.Abs(start.y - end.y), 2.0)) * 0.3f;
float diff = (angle + (float)Math.PI) - (dirAngle + (float)Math.PI);
if (diff > Math.PI || (diff < 0 && diff > -Math.PI))
angle += (float)Math.PI;
return new Vector2D((float)(Math.Sin(angle) * length), (float)(Math.Cos(angle) * length));
}
//LINE DRAWING
//this returns array of Vector2D to draw 4-point bezier curve
private Vector2D[] getBezierCurve(Vector2D p1, Vector2D p2, Vector2D cp1, Vector2D cp2, int steps) {
if (steps < 0) return null;
int totalSteps = steps + 1;
Vector2D[] points = new Vector2D[totalSteps];
float step = 1f / (float)steps;
float curStep = 0f;
float curStepInv, m1, m2, m3, m4;
for (int i = 0; i < totalSteps; i++) {
curStepInv = 1f - curStep;
m1 = curStepInv * curStepInv * curStepInv;
m2 = 3 * curStep * curStepInv * curStepInv;
m3 = 3 * curStep * curStep * curStepInv;
m4 = curStep * curStep * curStep;
int px = (int)(m1 * p1.x + m2 * cp1.x + m3 * cp2.x + m4 * p2.x);
int py = (int)(m1 * p1.y + m2 * cp1.y + m3 * cp2.y + m4 * p2.y);
points[i] = new Vector2D(px, py);
curStep += step;
}
return points;
}
//returns true if 2 lines intersect
private bool linesIntersect(Line line1, Line line2) {
float zn = (line2.End.y - line2.Start.y) * (line1.End.x - line1.Start.x) - (line2.End.x - line2.Start.x) * (line1.End.y - line1.Start.y);
float ch1 = (line2.End.x - line2.Start.x) * (line1.Start.y - line2.Start.y) - (line2.End.y - line2.Start.y) * (line1.Start.x - line2.Start.x);
float ch2 = (line1.End.x - line1.Start.x) * (line1.Start.y - line2.Start.y) - (line1.End.y - line1.Start.y) * (line1.Start.x - line2.Start.x);
if (zn == 0) return false;
if ((ch1 / zn <= 1 && ch1 / zn >= 0) && (ch2 / zn <= 1 && ch2 / zn >= 0))
return true;
return false;
}
//it's basically 2-point bezier curve
private Vector2D getPointOnLine(Vector2D p1, Vector2D p2, float delta) {
return new Vector2D((int)((1f - delta) * p1.x + delta * p2.x), (int)((1f - delta) * p1.y + delta * p2.y));
}
//LINE SORTING
//this gets two arrays of connected points from given lines. Returns true if all went well.
private bool setupPointGroups(List<Line> linesList) {
//find prev/next lines for each line
for (int i = 0; i < linesList.Count; i++) {
Line curLine = linesList[i];
for (int c = 0; c < linesList.Count; c++) {
if (c != i) {//don't wanna play with ourselves :)
Line line = linesList[c];
//check start and end points
if (curLine.Start == line.Start) {
line.Invert();
curLine.Previous = line;
} else if (curLine.Start == line.End) {
curLine.Previous = line;
} else if (curLine.End == line.End) {
line.Invert();
curLine.Next = line;
} else if (curLine.End == line.Start) {
curLine.Next = line;
}
}
}
}
List<List<Vector2D>> pointGroups = new List<List<Vector2D>>();
List<List<Line>> sortedLines = new List<List<Line>>();
//now find start lines
for (int i = 0; i < linesList.Count; i++) {
Line curLine = linesList[i];
if (curLine.Previous == null) { //found start
//collect points
Line l = curLine;
List<Vector2D> points = new List<Vector2D>();
List<Line> lines = new List<Line>();
points.Add(l.Start);
do {
points.Add(l.End);
lines.Add(l);
} while ((l = l.Next) != null);
pointGroups.Add(points);
sortedLines.Add(lines);
}
}
if (pointGroups.Count != 2) {
General.Interface.DisplayStatus(StatusType.Warning, "Incorrect number of linedef groups! Expected 2, but got " + pointGroups.Count);
return false;
}
if (pointGroups[0].Count != pointGroups[1].Count) {
General.Interface.DisplayStatus(StatusType.Warning, "Linedefs groups must have equal length! Got " + pointGroups[0].Count + " in first group and " + pointGroups[1].Count + " in second.");
return false;
}
//check if lines from first group intersect with lines from second group
foreach (Line l1 in sortedLines[0]) {
foreach (Line l2 in sortedLines[1]) {
if (linesIntersect(l1, l2)) {
General.Interface.DisplayStatus(StatusType.Warning, "One or more lines from first group intersect with one or more lines from second group!");
return false;
}
}
}
//both groups count should match at this point
segmentsCount = pointGroups[0].Count;
//collect sector properties
sectorProps1 = new SectorProperties[sortedLines[0].Count];
for (int i = 0; i < sortedLines[0].Count; i++ ) {
sectorProps1[i] = sortedLines[0][i].SectorProperties;
}
sectorProps2 = new SectorProperties[sortedLines[1].Count];
for (int i = 0; i < sortedLines[1].Count; i++) {
sectorProps2[i] = sortedLines[1][i].SectorProperties;
}
//check if we need to reverse one of point groups
Line line1 = new Line(pointGroups[0][0], pointGroups[1][0]);
Line line2 = new Line(pointGroups[0][segmentsCount - 1], pointGroups[1][segmentsCount - 1]);
if (linesIntersect(line1, line2)) {
pointGroups[0].Reverse();
Array.Reverse(sectorProps1);
}
//fill point groups
pointGroup1 = new Vector2D[segmentsCount];
pointGroup2 = new Vector2D[segmentsCount];
pointGroups[0].CopyTo(pointGroup1);
pointGroups[1].CopyTo(pointGroup2);
return true;
}
//Easing functions. Based on Robert Penner's original easing equations (http://www.robertpenner.com/easing/)
/**
* Easing equation function for a sinusoidal (sin(t)) easing in: accelerating from zero velocity.
*/
private int easeInSine(int val1, int val2, float delta) {
float f_val1 = (float)val1;
float f_val2 = (float)val2 - f_val1;
return (int)(-f_val2 * Math.Cos(delta * (Math.PI / 2.0f)) + f_val2 + f_val1);
}
/**
* Easing equation function for a sinusoidal (sin(t)) easing out: decelerating from zero velocity.
*/
private int easeOutSine(int val1, int val2, float delta) {
float f_val1 = (float)val1;
float f_val2 = (float)val2;
return (int)((f_val2 - f_val1) * Math.Sin(delta * ((float)Math.PI / 2.0f)) + f_val1);
}
/**
* Easing equation function for a sinusoidal (sin(t)) easing in/out: acceleration until halfway, then deceleration.
*/
private int easeInOutSine(int val1, int val2, float delta) {
float f_val1 = (float)val1;
float f_val2 = (float)val2;
return (int)(-f_val2 / 2.0f * (Math.Cos(Math.PI * delta) - 1.0f) + f_val1);
}
private int intepolateValue(int val1, int val2, float delta, string mode) {
switch (mode) {
case BridgeInterpolationMode.HIGHEST:
case BridgeInterpolationMode.BRIGHTNESS_HIGHEST:
return Math.Max(val1, val2);
break;
case BridgeInterpolationMode.LOWEST:
case BridgeInterpolationMode.BRIGHTNESS_LOWEST:
return Math.Min(val1, val2);
break;
case BridgeInterpolationMode.LINEAR:
return (int)(delta * (float)val2 + (1.0f - delta) * (float)val1);
break;
case BridgeInterpolationMode.IN_SINE:
return easeInSine(val1, val2, delta);
break;
case BridgeInterpolationMode.OUT_SINE:
return easeOutSine(val1, val2, delta);
break;
case BridgeInterpolationMode.IN_OUT_SINE:
return easeInOutSine(val1, val2, delta);
break;
default:
throw new Exception("DrawBezierPathMode.intepolateValue: got unknown mode: '" + mode + "'");
break;
}
return -1;
}
//EVENTS
private void form_OnSubdivisionChanged(object sender, EventArgs e) {
update();
}
private void form_OnOkClick(object sender, EventArgs e) {
FinishDraw();
}
private void form_OnCancelClick(object sender, EventArgs e) {
OnCancel();
}
private void form_OnFlipClick(object sender, EventArgs e) {
Array.Reverse(pointGroup1);
Array.Reverse(sectorProps1);
//swap handles position
Vector2D p = controlHandles[0].Position;
controlHandles[0].Position = controlHandles[2].Position;
controlHandles[2].Position = p;
update();
}
//ACTIONS
// Finish drawing
[BeginAction("finishdraw")]
public void FinishDraw() {
// Accept the changes
General.Editing.AcceptMode();
}
[BeginAction("increasesubdivlevel")]
private void increaseSubdivLevel() {
if (form != null && form.Subdivisions < MAX_SUBDIVISIONS)
form.Subdivisions++;
}
[BeginAction("decreasesubdivlevel")]
private void decreaseSubdivLevel() {
if (form != null && form.Subdivisions > MIN_SUBDIVISIONS)
form.Subdivisions--;
}
}
internal struct SectorProperties {
public int FloorHeight;
public int CeilingHeight;
public int Brightness;
public float Angle;
public string HighTexture;
public string LowTexture;
}
internal class ControlHandle
{
public Vector2D Position;
public Vector2D ControlledPoint; //point, to which this handle is assigned
public Vector2D RelativePosition {
get {
return new Vector2D(Position.x - ControlledPoint.x, Position.y - ControlledPoint.y);
}
set {
Position = new Vector2D(ControlledPoint.x + value.x, ControlledPoint.y + value.y);
}
}
public ControlHandle Pair; //second handle, to which this handle is paired
}
internal class Line {
public Vector2D Start { get { return start; } }
private Vector2D start;
public Vector2D End { get { return end; } }
private Vector2D end;
public SectorProperties SectorProperties;
public Line Previous;
public Line Next;
public Line(Linedef ld) {
start = new Vector2D((int)ld.Start.Position.x, (int)ld.Start.Position.y);
end = new Vector2D((int)ld.End.Position.x, (int)ld.End.Position.y);
SectorProperties = new SectorProperties();
SectorProperties.Angle = ld.Angle;
if (ld.Back != null) {
SectorProperties.CeilingHeight = ld.Back.Sector.CeilHeight;
SectorProperties.FloorHeight = ld.Back.Sector.FloorHeight;
SectorProperties.Brightness = ld.Back.Sector.Brightness;
SectorProperties.HighTexture = ld.Back.HighTexture;
SectorProperties.LowTexture = ld.Back.LowTexture;
}else if(ld.Front != null){
SectorProperties.CeilingHeight = ld.Front.Sector.CeilHeight;
SectorProperties.FloorHeight = ld.Front.Sector.FloorHeight;
SectorProperties.Brightness = ld.Front.Sector.Brightness;
SectorProperties.HighTexture = ld.Front.HighTexture;
SectorProperties.LowTexture = ld.Front.LowTexture;
}else{
SectorProperties.CeilingHeight = 128;
SectorProperties.FloorHeight = 0;
SectorProperties.Brightness = 192;
SectorProperties.HighTexture = "-";
SectorProperties.LowTexture = "-";
}
}
public Line(Vector2D start, Vector2D end) {
this.start = start;
this.end = end;
}
public void Invert() {
Vector2D s = start;
start = end;
end = s;
SectorProperties.Angle *= -1;
}
}
}

View file

@ -43,6 +43,13 @@ namespace CodeImp.DoomBuilder.BuilderModes.ClassicModes
snaptogrid = true;
cornersColor = General.Colors.BrightColors[new Random().Next(General.Colors.BrightColors.Length - 1)];
}
public override void Dispose() {
if (!isdisposed && hintLabel != null)
hintLabel.Dispose();
base.Dispose();
}
override protected void Update() {
PixelColor stitchcolor = General.Colors.Highlight;

View file

@ -138,7 +138,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
public LinedefProperties CopiedLinedefProps { get { return copiedlinedefprops; } set { copiedlinedefprops = value; } }
public ThingProperties CopiedThingProps { get { return copiedthingprops; } set { copiedthingprops = value; } }
public bool ViewSelectionNumbers { get { return viewselectionnumbers; } set { viewselectionnumbers = value; } }
public float StitchRange { get { return stitchrange; } }
public float StitchRange { get { return stitchrange; } internal set { stitchrange = value; } }
public float HighlightRange { get { return highlightrange; } }
public float HighlightThingsRange { get { return highlightthingsrange; } }
public float SplitLinedefsRange { get { return splitlinedefsrange; } }

View file

@ -0,0 +1,218 @@
namespace CodeImp.DoomBuilder.BuilderModes.Interface {
partial class BridgeModeForm {
/// <summary>
/// Требуется переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором форм Windows
/// <summary>
/// Обязательный метод для поддержки конструктора - не изменяйте
/// содержимое данного метода при помощи редактора кода.
/// </summary>
private void InitializeComponent() {
this.buttonOK = new System.Windows.Forms.Button();
this.buttonCancel = new System.Windows.Forms.Button();
this.cbFloorAlign = new System.Windows.Forms.ComboBox();
this.cbCeilingAlign = new System.Windows.Forms.ComboBox();
this.cbBrightness = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.nudSubdivisions = new System.Windows.Forms.NumericUpDown();
this.label4 = new System.Windows.Forms.Label();
this.buttonFlip = new System.Windows.Forms.Button();
this.cbMirror = new System.Windows.Forms.CheckBox();
this.cbCopy = new System.Windows.Forms.CheckBox();
((System.ComponentModel.ISupportInitialize)(this.nudSubdivisions)).BeginInit();
this.SuspendLayout();
//
// buttonOK
//
this.buttonOK.Location = new System.Drawing.Point(177, 139);
this.buttonOK.Name = "buttonOK";
this.buttonOK.Size = new System.Drawing.Size(75, 23);
this.buttonOK.TabIndex = 4;
this.buttonOK.Text = "OK";
this.buttonOK.UseVisualStyleBackColor = true;
this.buttonOK.Click += new System.EventHandler(this.buttonOK_Click);
//
// buttonCancel
//
this.buttonCancel.Location = new System.Drawing.Point(95, 139);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
this.buttonCancel.TabIndex = 5;
this.buttonCancel.Text = "Cancel";
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.buttonCancel_Click);
//
// cbFloorAlign
//
this.cbFloorAlign.FormattingEnabled = true;
this.cbFloorAlign.Location = new System.Drawing.Point(93, 12);
this.cbFloorAlign.Name = "cbFloorAlign";
this.cbFloorAlign.Size = new System.Drawing.Size(158, 21);
this.cbFloorAlign.TabIndex = 0;
//
// cbCeilingAlign
//
this.cbCeilingAlign.FormattingEnabled = true;
this.cbCeilingAlign.Location = new System.Drawing.Point(93, 39);
this.cbCeilingAlign.Name = "cbCeilingAlign";
this.cbCeilingAlign.Size = new System.Drawing.Size(158, 21);
this.cbCeilingAlign.TabIndex = 1;
//
// cbBrightness
//
this.cbBrightness.FormattingEnabled = true;
this.cbBrightness.Location = new System.Drawing.Point(93, 66);
this.cbBrightness.Name = "cbBrightness";
this.cbBrightness.Size = new System.Drawing.Size(158, 21);
this.cbBrightness.TabIndex = 2;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(31, 15);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(56, 13);
this.label1.TabIndex = 5;
this.label1.Text = "Align floor:";
this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(21, 42);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(66, 13);
this.label2.TabIndex = 6;
this.label2.Text = "Align ceiling:";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(28, 69);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(59, 13);
this.label3.TabIndex = 7;
this.label3.Text = "Brightness:";
this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// nudSubdivisions
//
this.nudSubdivisions.Location = new System.Drawing.Point(205, 93);
this.nudSubdivisions.Name = "nudSubdivisions";
this.nudSubdivisions.Size = new System.Drawing.Size(46, 20);
this.nudSubdivisions.TabIndex = 3;
this.nudSubdivisions.Value = new decimal(new int[] {
5,
0,
0,
0});
this.nudSubdivisions.ValueChanged += new System.EventHandler(this.nudSubdivisions_ValueChanged);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(130, 97);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(69, 13);
this.label4.TabIndex = 9;
this.label4.Text = "Subdivisions:";
this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// buttonFlip
//
this.buttonFlip.Location = new System.Drawing.Point(13, 139);
this.buttonFlip.Name = "buttonFlip";
this.buttonFlip.Size = new System.Drawing.Size(75, 23);
this.buttonFlip.TabIndex = 6;
this.buttonFlip.Text = "Flip Lines";
this.buttonFlip.UseVisualStyleBackColor = true;
this.buttonFlip.Click += new System.EventHandler(this.buttonFlip_Click);
//
// cbMirror
//
this.cbMirror.AutoSize = true;
this.cbMirror.Location = new System.Drawing.Point(14, 95);
this.cbMirror.Name = "cbMirror";
this.cbMirror.Size = new System.Drawing.Size(81, 17);
this.cbMirror.TabIndex = 10;
this.cbMirror.Text = "Mirror mode";
this.cbMirror.UseVisualStyleBackColor = true;
this.cbMirror.CheckStateChanged += new System.EventHandler(this.cbMirror_CheckStateChanged);
//
// cbCopy
//
this.cbCopy.AutoSize = true;
this.cbCopy.Location = new System.Drawing.Point(14, 118);
this.cbCopy.Name = "cbCopy";
this.cbCopy.Size = new System.Drawing.Size(79, 17);
this.cbCopy.TabIndex = 10;
this.cbCopy.Text = "Copy mode";
this.cbCopy.UseVisualStyleBackColor = true;
this.cbCopy.CheckedChanged += new System.EventHandler(this.cbCopy_CheckedChanged);
//
// BridgeModeForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(263, 166);
this.Controls.Add(this.cbCopy);
this.Controls.Add(this.cbMirror);
this.Controls.Add(this.buttonFlip);
this.Controls.Add(this.label4);
this.Controls.Add(this.nudSubdivisions);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.cbBrightness);
this.Controls.Add(this.cbCeilingAlign);
this.Controls.Add(this.cbFloorAlign);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonOK);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "BridgeModeForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.Text = "Options";
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.BezierPathForm_FormClosed);
this.MouseLeave += new System.EventHandler(this.BezierPathForm_MouseLeave);
((System.ComponentModel.ISupportInitialize)(this.nudSubdivisions)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button buttonOK;
private System.Windows.Forms.Button buttonCancel;
private System.Windows.Forms.ComboBox cbFloorAlign;
private System.Windows.Forms.ComboBox cbCeilingAlign;
private System.Windows.Forms.ComboBox cbBrightness;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.NumericUpDown nudSubdivisions;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Button buttonFlip;
private System.Windows.Forms.CheckBox cbMirror;
private System.Windows.Forms.CheckBox cbCopy;
}
}

View file

@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CodeImp.DoomBuilder.BuilderModes.ClassicModes;
namespace CodeImp.DoomBuilder.BuilderModes.Interface {
internal struct BridgeInterpolationMode {
public const string BRIGHTNESS_HIGHEST = "Use highest";
public const string BRIGHTNESS_LOWEST = "Use lowest";
public const string HIGHEST = "Highest ceiling";
public const string LOWEST = "Lowest floor";
public const string LINEAR = "Linear interpolation";
public const string IN_SINE = "EaseInSine interpolation";
public const string OUT_SINE = "EaseOutSine interpolation";
public const string IN_OUT_SINE = "EaseInOutSine interpolation";
public static string[] CEILING_INTERPOLATION_MODES = { LINEAR, HIGHEST, IN_SINE, OUT_SINE, IN_OUT_SINE/*, IN_OUT_CUBIC, OUT_IN_CUBIC*/ };
public static string[] FLOOR_INTERPOLATION_MODES = { LINEAR, LOWEST, IN_SINE, OUT_SINE, IN_OUT_SINE/*, IN_OUT_CUBIC, OUT_IN_CUBIC*/ };
public static string[] BRIGHTNESS_INTERPOLATION_MODES = { LINEAR, BRIGHTNESS_HIGHEST, BRIGHTNESS_LOWEST };
}
public partial class BridgeModeForm : Form {
internal int Subdivisions {
get {
return (int)nudSubdivisions.Value;
}
set {
nudSubdivisions.Value = value;
}
}
internal string FloorAlignMode { get { return (string)cbFloorAlign.SelectedItem; } }
internal string CeilingAlignMode { get { return (string)cbCeilingAlign.SelectedItem; } }
internal string BrightnessMode { get { return (string)cbBrightness.SelectedItem; } }
internal bool MirrorMode { get { return cbMirror.Checked; } }
internal bool CopyMode { get { return cbCopy.Checked; } }
internal event EventHandler OnSubdivisionChanged;
internal event EventHandler OnOkClick;
internal event EventHandler OnCancelClick;
internal event EventHandler OnFlipClick;
public BridgeModeForm() {
InitializeComponent();
cbBrightness.Items.AddRange(BridgeInterpolationMode.BRIGHTNESS_INTERPOLATION_MODES);
cbCeilingAlign.Items.AddRange(BridgeInterpolationMode.CEILING_INTERPOLATION_MODES);
cbFloorAlign.Items.AddRange(BridgeInterpolationMode.FLOOR_INTERPOLATION_MODES);
cbBrightness.SelectedIndex = 0;
cbCeilingAlign.SelectedIndex = 0;
cbFloorAlign.SelectedIndex = 0;
nudSubdivisions.Minimum = BridgeMode.MIN_SUBDIVISIONS;
nudSubdivisions.Maximum = BridgeMode.MAX_SUBDIVISIONS;
}
//events
private void BezierPathForm_FormClosed(object sender, FormClosedEventArgs e) {
if (OnCancelClick != null)
OnCancelClick(this, new EventArgs());
}
private void buttonCancel_Click(object sender, EventArgs e) {
if (OnCancelClick != null)
OnCancelClick(this, new EventArgs());
}
private void buttonOK_Click(object sender, EventArgs e) {
if (OnOkClick != null)
OnOkClick(this, new EventArgs());
}
private void nudSubdivisions_ValueChanged(object sender, EventArgs e) {
if (OnSubdivisionChanged != null)
OnSubdivisionChanged(this, new EventArgs());
}
private void BezierPathForm_MouseEnter(object sender, EventArgs e) {
this.Focus();
}
private void BezierPathForm_MouseLeave(object sender, EventArgs e) {
General.Interface.FocusDisplay();
}
private void buttonFlip_Click(object sender, EventArgs e) {
if (OnFlipClick != null)
OnFlipClick(this, new EventArgs());
}
private void cbCopy_CheckedChanged(object sender, EventArgs e) {
if (cbMirror.Checked && cbCopy.Checked)
cbMirror.Checked = false;
}
private void cbMirror_CheckStateChanged(object sender, EventArgs e) {
if (cbMirror.Checked && cbCopy.Checked)
cbCopy.Checked = false;
}
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -171,6 +171,19 @@ decreasebevel
default = 196603;
}
//mxd
bridgemode
{
title = "Bridge Mode";
category = "drawing";
description = "Select two lines or two series of lines, then activate this tool to draw a bezier path between them.";
allowkeys = true;
allowmouse = false;
allowscroll = false;
default = 131138;
}
drawpoint
{
title = "Draw Vertex";

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

View file

@ -1,6 +1,6 @@
togglelightpannel
{
title = "Open color picker";
title = "Open Color Picker";
category = "tools";
description = "Select dynamic light thing(s) or sector(s), then use this panel to set light properties quickly.";
allowkeys = true;

View file

@ -70,6 +70,7 @@
<ProjectReference Include="..\..\Core\Builder.csproj">
<Project>{818B3D10-F791-4C3F-9AF5-BB2D0079B63C}</Project>
<Name>Builder</Name>
<Private>False</Private>
</ProjectReference>
</ItemGroup>
<ItemGroup>