2009-04-19 18:07:22 +00:00
#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.Windows.Forms ;
using CodeImp.DoomBuilder.IO ;
using CodeImp.DoomBuilder.Map ;
using System.IO ;
using System.Collections ;
using CodeImp.DoomBuilder.Data ;
using CodeImp.DoomBuilder.Config ;
#endregion
namespace CodeImp.DoomBuilder.Windows
{
internal partial class OpenMapOptionsForm : DelayedForm
{
// Variables
private Configuration mapsettings ;
private MapOptions options ;
private WAD wadfile ;
2014-07-12 13:10:41 +00:00
private readonly string filepathname ;
2009-04-19 18:07:22 +00:00
private string selectedmapname ;
// Properties
public string FilePathName { get { return filepathname ; } }
public MapOptions Options { get { return options ; } }
// Constructor
public OpenMapOptionsForm ( string filepathname )
{
// Initialize
InitializeComponent ( ) ;
this . Text = "Open Map from " + Path . GetFileName ( filepathname ) ;
this . filepathname = filepathname ;
2013-03-18 13:52:27 +00:00
datalocations . StartPath = filepathname ; //mxd
2011-07-26 20:06:38 +00:00
this . options = null ;
}
// Constructor
public OpenMapOptionsForm ( string filepathname , MapOptions options )
{
// Initialize
InitializeComponent ( ) ;
this . Text = "Open Map from " + Path . GetFileName ( filepathname ) ;
this . filepathname = filepathname ;
this . options = options ;
2013-03-18 13:52:27 +00:00
datalocations . StartPath = filepathname ; //mxd
2011-07-26 20:06:38 +00:00
datalocations . EditResourceLocationList ( options . Resources ) ;
2009-04-19 18:07:22 +00:00
}
// This loads the settings and attempt to find a suitable config
private void LoadSettings ( )
{
string gameconfig ;
int index ;
// Busy
Cursor . Current = Cursors . WaitCursor ;
// Check if the file exists
if ( ! File . Exists ( filepathname ) )
{
// WAD file does not exist
MessageBox . Show ( this , "Could not open the WAD file: The file does not exist." , Application . ProductName , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
this . DialogResult = DialogResult . Cancel ;
this . Close ( ) ;
return ;
}
try
{
// Open the WAD file
wadfile = new WAD ( filepathname , true ) ;
}
catch ( Exception )
{
// Unable to open WAD file (or its config)
MessageBox . Show ( this , "Could not open the WAD file for reading. Please make sure the file you selected is valid and is not in use by any other application." , Application . ProductName , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
if ( wadfile ! = null ) wadfile . Dispose ( ) ;
this . DialogResult = DialogResult . Cancel ;
this . Close ( ) ;
return ;
}
// Open the Map Settings configuration
2014-02-18 14:04:14 +00:00
string dbsfile = filepathname . Substring ( 0 , filepathname . Length - 4 ) + ".dbs" ;
2009-04-19 18:07:22 +00:00
if ( File . Exists ( dbsfile ) )
try { mapsettings = new Configuration ( dbsfile , true ) ; }
catch ( Exception ) { mapsettings = new Configuration ( true ) ; }
else
mapsettings = new Configuration ( true ) ;
2014-02-18 14:04:14 +00:00
// Check strict patches box, check what game configuration is preferred
2014-12-03 09:06:05 +00:00
if ( options ! = null )
{
2011-07-26 20:06:38 +00:00
strictpatches . Checked = options . StrictPatches ;
gameconfig = options . ConfigFile ;
2014-12-03 09:06:05 +00:00
}
else
{
2014-02-18 14:04:14 +00:00
strictpatches . Checked = mapsettings . ReadSetting ( "strictpatches" , false ) ;
2011-07-26 20:06:38 +00:00
gameconfig = mapsettings . ReadSetting ( "gameconfig" , "" ) ;
2014-02-18 14:04:14 +00:00
}
2009-04-19 18:07:22 +00:00
2014-07-12 13:10:41 +00:00
//mxd. Fill script compilers list
2014-12-03 09:06:05 +00:00
foreach ( KeyValuePair < string , ScriptConfiguration > group in General . CompiledScriptConfigs )
{
2014-07-12 13:10:41 +00:00
scriptcompiler . Items . Add ( group . Value ) ;
}
2014-02-18 14:04:14 +00:00
//mxd. Go for all enabled configurations
2014-12-03 09:06:05 +00:00
for ( int i = 0 ; i < General . Configs . Count ; i + + )
{
2014-02-18 14:04:14 +00:00
if ( ! General . Configs [ i ] . Enabled ) continue ;
2009-04-19 18:07:22 +00:00
// Add config name to list
index = config . Items . Add ( General . Configs [ i ] ) ;
2014-12-03 09:06:05 +00:00
// Select this item
if ( General . Configs [ i ] . Filename = = gameconfig ) config . SelectedIndex = index ;
2009-04-19 18:07:22 +00:00
}
2014-02-18 14:04:14 +00:00
//mxd. No dice? Try disabled ones
2014-12-03 09:06:05 +00:00
if ( config . SelectedIndex = = - 1 )
{
for ( int i = 0 ; i < General . Configs . Count ; i + + )
{
2014-02-18 14:04:14 +00:00
if ( General . Configs [ i ] . Enabled ) continue ;
2014-12-03 09:06:05 +00:00
if ( General . Configs [ i ] . Filename = = gameconfig )
{
2014-02-18 14:04:14 +00:00
//add and Select this item
config . SelectedIndex = config . Items . Add ( General . Configs [ i ] ) ;
break ;
}
}
}
2009-04-19 18:07:22 +00:00
// Still no configuration selected?
2014-12-03 09:06:05 +00:00
if ( config . SelectedIndex = = - 1 )
{
2009-04-19 18:07:22 +00:00
// Then go for all configurations to find a suitable one
for ( int i = 0 ; i < General . Configs . Count ; i + + )
{
2014-02-18 14:04:14 +00:00
// Check if a resource location is set for this configuration, if so, match the wad against this configuration
if ( General . Configs [ i ] . Resources . Count > 0 & & MatchConfiguration ( General . Configs [ i ] . Configuration , wadfile ) )
2009-04-19 18:07:22 +00:00
{
2014-02-18 14:04:14 +00:00
//mxd. Already added?
index = config . Items . IndexOf ( General . Configs [ i ] ) ;
2014-12-03 09:06:05 +00:00
if ( index ! = - 1 )
{
2009-04-19 18:07:22 +00:00
// Select this item
2014-02-18 14:04:14 +00:00
config . SelectedIndex = index ;
2014-12-03 09:06:05 +00:00
}
else
{
2014-02-18 14:04:14 +00:00
// Add and select this item
config . SelectedIndex = config . Items . Add ( General . Configs [ i ] ) ;
2009-04-19 18:07:22 +00:00
}
2014-02-18 14:04:14 +00:00
break ;
2009-04-19 18:07:22 +00:00
}
}
}
// Done
Cursor . Current = Cursors . Default ;
}
2013-11-27 15:38:03 +00:00
// mxd. This matches a WAD file with the specified game configuration
2009-04-19 18:07:22 +00:00
// by checking if the specific lumps are detected
2014-05-20 09:09:28 +00:00
private static bool MatchConfiguration ( Configuration cfg , WAD wadfile )
{
2013-11-27 15:38:03 +00:00
int scanindex , checkoffset ;
int lumpsfound , lumpsrequired = 0 ;
string lumpname ;
2009-04-19 18:07:22 +00:00
2013-11-27 15:38:03 +00:00
// Get the map lump names
IDictionary maplumpnames = cfg . ReadSetting ( "maplumpnames" , new Hashtable ( ) ) ;
2009-04-19 18:07:22 +00:00
2013-11-27 15:38:03 +00:00
// Count how many required lumps we have to find
2014-12-03 09:06:05 +00:00
foreach ( DictionaryEntry ml in maplumpnames )
{
2013-11-27 15:38:03 +00:00
// Ignore the map header (it will not be found because the name is different)
2014-12-03 09:06:05 +00:00
if ( ml . Key . ToString ( ) ! = MapManager . CONFIG_MAP_HEADER )
{
2013-11-27 15:38:03 +00:00
// Read lump setting and count it
if ( cfg . ReadSetting ( "maplumpnames." + ml . Key + ".required" , false ) )
lumpsrequired + + ;
}
}
// Go for all the lumps in the wad
2014-12-03 09:06:05 +00:00
for ( scanindex = 0 ; scanindex < ( wadfile . Lumps . Count - 1 ) ; scanindex + + )
{
2013-11-27 15:38:03 +00:00
// Make sure this lump is not part of the map.
2014-12-03 09:06:05 +00:00
if ( ! maplumpnames . Contains ( wadfile . Lumps [ scanindex ] . Name ) )
{
2013-11-27 15:38:03 +00:00
// Reset check
lumpsfound = 0 ;
checkoffset = 1 ;
// Continue while still within bounds and lumps are still recognized
while ( ( ( scanindex + checkoffset ) < wadfile . Lumps . Count ) & &
2014-12-03 09:06:05 +00:00
maplumpnames . Contains ( wadfile . Lumps [ scanindex + checkoffset ] . Name ) )
{
2013-11-27 15:38:03 +00:00
lumpname = wadfile . Lumps [ scanindex + checkoffset ] . Name ;
//mxd. Lump cannot present in current map format, fail this check
2014-12-03 09:06:05 +00:00
if ( cfg . ReadSetting ( "maplumpnames." + lumpname + ".forbidden" , false ) )
{
2013-11-27 15:38:03 +00:00
lumpsfound = - 1 ;
break ;
}
// Count the lump when it is marked as required
if ( cfg . ReadSetting ( "maplumpnames." + lumpname + ".required" , false ) )
lumpsfound + + ;
// Check the next lump
checkoffset + + ;
2009-04-19 18:07:22 +00:00
}
2013-11-27 15:38:03 +00:00
// Map found? Let's call it a day :)
if ( lumpsfound > = lumpsrequired ) return true ;
2009-04-19 18:07:22 +00:00
}
}
2013-11-27 15:38:03 +00:00
return false ;
2009-04-19 18:07:22 +00:00
}
// Configuration is selected
private void config_SelectedIndexChanged ( object sender , EventArgs e )
{
2013-11-27 15:38:03 +00:00
// Anything selected?
if ( config . SelectedIndex < 0 ) return ;
2009-04-19 18:07:22 +00:00
int scanindex , checkoffset ;
int lumpsfound , lumpsrequired = 0 ;
string lumpname , selectedname = "" ;
2013-11-27 15:38:03 +00:00
// Keep selected name, if any
if ( mapslist . SelectedItems . Count > 0 )
selectedname = mapslist . SelectedItems [ 0 ] . Text ;
2009-04-19 18:07:22 +00:00
2013-11-27 15:38:03 +00:00
// Make an array for the map names
2014-02-18 14:04:14 +00:00
List < ListViewItem > mapnames = new List < ListViewItem > ( ) ;
2009-04-19 18:07:22 +00:00
2013-11-27 15:38:03 +00:00
// Get selected configuration info
2014-02-18 14:04:14 +00:00
ConfigurationInfo ci = ( config . SelectedItem as ConfigurationInfo ) ;
2009-04-19 18:07:22 +00:00
2014-02-18 14:04:14 +00:00
//mxd. Get configuration
Configuration cfg = ci . Configuration ;
2009-04-19 18:07:22 +00:00
2013-11-27 15:38:03 +00:00
// Get the map lump names
2014-02-18 14:04:14 +00:00
IDictionary maplumpnames = cfg . ReadSetting ( "maplumpnames" , new Hashtable ( ) ) ;
2013-11-27 15:38:03 +00:00
// Count how many required lumps we have to find
2014-12-03 09:06:05 +00:00
foreach ( DictionaryEntry ml in maplumpnames )
{
2013-11-27 15:38:03 +00:00
// Ignore the map header (it will not be found because the name is different)
2014-12-03 09:06:05 +00:00
if ( ml . Key . ToString ( ) ! = MapManager . CONFIG_MAP_HEADER )
{
2013-11-27 15:38:03 +00:00
// Read lump setting and count it
if ( cfg . ReadSetting ( "maplumpnames." + ml . Key + ".required" , false ) )
lumpsrequired + + ;
2009-04-19 18:07:22 +00:00
}
2013-11-27 15:38:03 +00:00
}
2009-04-19 18:07:22 +00:00
2013-11-27 15:38:03 +00:00
// Go for all the lumps in the wad
2014-12-03 09:06:05 +00:00
for ( scanindex = 0 ; scanindex < ( wadfile . Lumps . Count - 1 ) ; scanindex + + )
{
2013-11-27 15:38:03 +00:00
// Make sure this lump is not part of the map.
2014-12-03 09:06:05 +00:00
if ( ! maplumpnames . Contains ( wadfile . Lumps [ scanindex ] . Name ) )
{
2013-11-27 15:38:03 +00:00
// Reset check
lumpsfound = 0 ;
checkoffset = 1 ;
2009-04-19 18:07:22 +00:00
2013-11-27 15:38:03 +00:00
// Continue while still within bounds and lumps are still recognized
while ( ( ( scanindex + checkoffset ) < wadfile . Lumps . Count ) & &
2014-12-03 09:06:05 +00:00
maplumpnames . Contains ( wadfile . Lumps [ scanindex + checkoffset ] . Name ) )
{
2013-11-27 15:38:03 +00:00
lumpname = wadfile . Lumps [ scanindex + checkoffset ] . Name ;
//mxd. Lump cannot present in current map format, fail this check
2014-12-03 09:06:05 +00:00
if ( cfg . ReadSetting ( "maplumpnames." + lumpname + ".forbidden" , false ) )
{
2013-11-27 15:38:03 +00:00
lumpsfound = - 1 ;
break ;
2009-04-19 18:07:22 +00:00
}
2013-11-27 15:38:03 +00:00
// Count the lump when it is marked as required
if ( cfg . ReadSetting ( "maplumpnames." + lumpname + ".required" , false ) )
lumpsfound + + ;
// Check the next lump
checkoffset + + ;
2009-04-19 18:07:22 +00:00
}
2013-11-27 15:38:03 +00:00
// Map found? Then add it to the list
if ( lumpsfound > = lumpsrequired )
mapnames . Add ( new ListViewItem ( wadfile . Lumps [ scanindex ] . Name ) ) ;
2009-04-19 18:07:22 +00:00
}
2013-11-27 15:38:03 +00:00
}
2009-04-19 18:07:22 +00:00
2013-11-27 15:38:03 +00:00
// Clear the list and add the new map names
mapslist . BeginUpdate ( ) ;
mapslist . Items . Clear ( ) ;
mapslist . Items . AddRange ( mapnames . ToArray ( ) ) ;
mapslist . Sort ( ) ;
2009-04-19 18:07:22 +00:00
2013-11-27 15:38:03 +00:00
// Go for all items in the list
2014-12-03 09:06:05 +00:00
foreach ( ListViewItem item in mapslist . Items )
{
2013-11-27 15:38:03 +00:00
// Was this item previously selected?
2014-12-03 09:06:05 +00:00
if ( item . Text = = selectedname )
{
2013-11-27 15:38:03 +00:00
// Select it again
item . Selected = true ;
break ;
2009-04-19 18:07:22 +00:00
}
}
2013-11-27 15:38:03 +00:00
if ( ( mapslist . SelectedItems . Count = = 0 ) & & ( mapslist . Items . Count > 0 ) )
mapslist . Items [ 0 ] . Selected = true ;
mapslist . EndUpdate ( ) ;
2014-07-12 13:10:41 +00:00
//mxd. Disable script compiler selector when there are no maps detected using current configuration
if ( mapslist . Items . Count = = 0 )
{
scriptcompiler . Enabled = false ;
scriptcompiler . SelectedIndex = - 1 ;
scriptcompilerlabel . Enabled = false ;
}
2013-11-27 15:38:03 +00:00
// Show configuration resources
datalocations . FixedResourceLocationList ( ci . Resources ) ;
2014-12-16 09:01:52 +00:00
// Update long texture names checkbox (mxd)
longtexturenames . Enabled = cfg . ReadSetting ( "longtexturenames" , false ) ;
2015-02-19 13:00:19 +00:00
longtexturenames . Checked = longtexturenames . Enabled & & options . UseLongTextureNames ;
2009-04-19 18:07:22 +00:00
}
// OK clicked
private void apply_Click ( object sender , EventArgs e )
{
// Configuration selected?
if ( config . SelectedIndex = = - 1 )
{
// Select a configuration!
MessageBox . Show ( this , "Please select a game configuration to use for editing your map." , Application . ProductName , MessageBoxButtons . OK , MessageBoxIcon . Warning ) ;
config . Focus ( ) ;
return ;
}
// Collect information
2014-02-18 14:04:14 +00:00
ConfigurationInfo configinfo = ( config . SelectedItem as ConfigurationInfo ) ; //mxd
2009-04-19 18:07:22 +00:00
DataLocationList locations = datalocations . GetResources ( ) ;
2014-12-16 09:01:52 +00:00
// Resources are valid? (mxd)
if ( ! datalocations . ResourcesAreValid ( ) )
{
MessageBox . Show ( this , "Cannot open map: at least one resource doesn't exist!" , Application . ProductName , MessageBoxButtons . OK , MessageBoxIcon . Warning ) ;
datalocations . Focus ( ) ;
return ;
}
2009-04-19 18:07:22 +00:00
// No map selected?
if ( mapslist . SelectedItems . Count = = 0 )
{
// Choose a map!
MessageBox . Show ( this , "Please select a map to load for editing." , Application . ProductName , MessageBoxButtons . OK , MessageBoxIcon . Warning ) ;
mapslist . Focus ( ) ;
return ;
}
2014-12-29 19:38:24 +00:00
//mxd. We cant't deal with this... We just can't...
2014-12-30 13:21:01 +00:00
if ( ! configinfo . ValidateMapName ( mapslist . SelectedItems [ 0 ] . Text . ToUpperInvariant ( ) ) )
2014-12-29 19:38:24 +00:00
{
2014-12-29 21:44:25 +00:00
// Choose a different map!
2014-12-30 13:21:01 +00:00
MessageBox . Show ( this , "Selected map name conflicts with a lump name defined for current map format.\nPlease rename the map and try again." , Application . ProductName , MessageBoxButtons . OK , MessageBoxIcon . Warning ) ;
2014-12-29 19:38:24 +00:00
mapslist . Focus ( ) ;
return ;
}
2009-04-19 18:07:22 +00:00
// Check if we should warn the user for missing resources
if ( ( wadfile . Type ! = WAD . TYPE_IWAD ) & & ( locations . Count = = 0 ) & & ( configinfo . Resources . Count = = 0 ) )
{
if ( MessageBox . Show ( this , "You are about to load a map without selecting any resources. Textures, flats and " +
"sprites may not be shown correctly or may not show up at all. Do you want to continue?" , Application . ProductName ,
MessageBoxButtons . YesNo , MessageBoxIcon . Warning , MessageBoxDefaultButton . Button2 ) = = DialogResult . No )
{
return ;
}
}
// Apply changes
options . ClearResources ( ) ;
options . ConfigFile = configinfo . Filename ;
options . CurrentName = mapslist . SelectedItems [ 0 ] . Text ;
options . StrictPatches = strictpatches . Checked ;
options . CopyResources ( locations ) ;
2014-07-12 13:10:41 +00:00
//mxd. Store script compiler
if ( scriptcompiler . Enabled & & scriptcompiler . SelectedIndex > - 1 )
{
ScriptConfiguration scriptcfg = scriptcompiler . SelectedItem as ScriptConfiguration ;
foreach ( KeyValuePair < string , ScriptConfiguration > group in General . CompiledScriptConfigs )
{
if ( group . Value = = scriptcfg )
{
options . ScriptCompiler = group . Key ;
break ;
}
}
}
2014-12-16 09:01:52 +00:00
//mxd. Use long texture names?
2015-02-19 13:00:19 +00:00
if ( longtexturenames . Enabled ) options . UseLongTextureNames = longtexturenames . Checked ;
2014-12-16 09:01:52 +00:00
2009-04-19 18:07:22 +00:00
// Hide window
wadfile . Dispose ( ) ;
this . DialogResult = DialogResult . OK ;
this . Close ( ) ;
}
// Cancel clicked
private void cancel_Click ( object sender , EventArgs e )
{
// Just hide window
wadfile . Dispose ( ) ;
this . DialogResult = DialogResult . Cancel ;
this . Close ( ) ;
}
// Window is shown
private void OpenMapOptionsForm_Shown ( object sender , EventArgs e )
{
// Update window
this . Update ( ) ;
// Load settings
LoadSettings ( ) ;
}
// Map name doubleclicked
private void mapslist_DoubleClick ( object sender , EventArgs e )
{
// Click OK
if ( mapslist . SelectedItems . Count > 0 ) apply . PerformClick ( ) ;
}
// Map name selected
private void mapslist_ItemSelectionChanged ( object sender , ListViewItemSelectionChangedEventArgs e )
{
2014-07-15 08:22:45 +00:00
if ( ! e . IsSelected ) return ; //mxd. Don't want to trigger this twice
2014-07-12 13:10:41 +00:00
2009-04-19 18:07:22 +00:00
DataLocationList locations ;
DataLocationList listedlocations ;
2014-07-12 13:10:41 +00:00
string scriptconfig = string . Empty ;
2009-04-19 18:07:22 +00:00
// Map previously selected?
2014-02-18 14:04:14 +00:00
if ( ! string . IsNullOrEmpty ( selectedmapname ) )
2009-04-19 18:07:22 +00:00
{
// Get locations from previous selected map settings
locations = new DataLocationList ( mapsettings , "maps." + selectedmapname + ".resources" ) ;
listedlocations = datalocations . GetResources ( ) ;
// Remove data locations that this map has in its config
foreach ( DataLocation dl in locations )
listedlocations . Remove ( dl ) ;
// Set new data locations
datalocations . EditResourceLocationList ( listedlocations ) ;
// Done
selectedmapname = null ;
}
// Anything selected?
if ( mapslist . SelectedItems . Count > 0 )
{
// Get the map name
selectedmapname = mapslist . SelectedItems [ 0 ] . Text ;
2015-02-19 13:00:19 +00:00
options = new MapOptions ( mapsettings , selectedmapname , longtexturenames . Enabled ) ;
2009-04-19 18:07:22 +00:00
// Get locations from previous selected map settings
locations = new DataLocationList ( mapsettings , "maps." + selectedmapname + ".resources" ) ;
listedlocations = datalocations . GetResources ( ) ;
// Add data locations that this map has in its config
foreach ( DataLocation dl in locations )
if ( ! listedlocations . Contains ( dl ) ) listedlocations . Add ( dl ) ;
// Set new data locations
datalocations . EditResourceLocationList ( listedlocations ) ;
2014-07-12 13:10:41 +00:00
//mxd. Select script compiler
2014-11-25 11:52:01 +00:00
if ( ! string . IsNullOrEmpty ( options . ScriptCompiler ) & & General . CompiledScriptConfigs . ContainsKey ( options . ScriptCompiler ) )
{
2014-07-12 13:10:41 +00:00
scriptconfig = options . ScriptCompiler ;
}
else
{
string defaultscriptconfig = ( config . SelectedItem as ConfigurationInfo ) . Configuration . ReadSetting ( "defaultscriptcompiler" , string . Empty ) ;
if ( ! string . IsNullOrEmpty ( defaultscriptconfig ) & & General . CompiledScriptConfigs . ContainsKey ( defaultscriptconfig ) )
scriptconfig = defaultscriptconfig ;
}
}
//mxd. Select proper script compiler
if ( ! string . IsNullOrEmpty ( scriptconfig ) )
{
scriptcompiler . Enabled = true ;
scriptcompiler . SelectedItem = General . CompiledScriptConfigs [ scriptconfig ] ;
scriptcompilerlabel . Enabled = true ;
}
else
{
scriptcompiler . Enabled = false ;
scriptcompiler . SelectedIndex = - 1 ;
scriptcompilerlabel . Enabled = false ;
2009-04-19 18:07:22 +00:00
}
}
// Help
private void OpenMapOptionsForm_HelpRequested ( object sender , HelpEventArgs hlpevent )
{
General . ShowHelp ( "w_openmapoptions.html" ) ;
hlpevent . Handled = true ;
}
}
}