예제 #1
0
void CTileGenDialog::GenerateMission( const char *szMissionFile )
{
	m_pPropertySheet->SetActivePage( m_pPropertySheet->GetPage( 0 ) );
	m_pGenerationOptions->Clear();
	m_pGenerationOptions->LoadFromFile( g_pFullFileSystem, szMissionFile, "GAME" );
	
	if ( IsGenerating() )
	{
		MessageBox *pMessage = new MessageBox ("Error", "Already generating a layout.  Please wait for this to finish before starting a new one.", this);
		pMessage->DoModal();
		return;
	}
	
	delete m_pLayoutSystem;
	m_pLayoutSystem = NULL;
	// Preprocess the mission file (i.e. apply rules)
	if ( m_pLayoutSystemPage->GetPreprocessor()->SubstituteRules( m_pGenerationOptions ) )
	{
		KeyValues *pMissionSettings = m_pGenerationOptions->FindKey( "mission_settings" ); 

		if ( pMissionSettings == NULL )
		{
			MessageBox *pMessage = new MessageBox( "Error", "Mission is missing a Global Options block.", this );
			pMessage->DoModal();
			return;
		}
		// Copy the filename key over
		pMissionSettings->SetString( "Filename", m_pGenerationOptions->GetString( "Filename", "invalid_filename" ) );

		if ( tilegen_preprocess_mission.GetBool() )
		{
			m_pGenerationOptions->SaveToFile( g_pFullFileSystem, "preprocessed_mission.txt", "GAME" );
		}
		
		m_pLayoutSystem = new CLayoutSystem();
		
		AddListeners( m_pLayoutSystem );
		if ( !m_pLayoutSystem->LoadFromKeyValues( m_pGenerationOptions ) )
		{
			MessageBox *pMessage = new MessageBox( "Error", "Failed to load mission from pre-processed key-values.", this );
			pMessage->DoModal();
			return;
		}

		// Clear the current layout
		// @TODO: check the current map is saved, print a warning if not?
		delete m_pMapLayout;
		m_pMapLayout = new CMapLayout( pMissionSettings->MakeCopy() );

		m_pLayoutSystem->BeginGeneration( m_pMapLayout );
	}
	else
	{
		MessageBox *pMessage = new MessageBox ("Error", "Failed to pre-process layout system definition.", this);
		pMessage->DoModal();
		return;
	}
}
예제 #2
0
//-----------------------------------------------------------------------------
// Purpose: Display some information about the editor
//-----------------------------------------------------------------------------
void BuildModeDialog::ShowHelp()
{
	char helpText[]= "In the Build Mode Dialog Window:\n" 
		"Delete button - deletes the currently selected panel if it is deletable.\n"
		"Apply button - applies changes to the Context Panel.\n"
		"Save button - saves all settings to file. \n"
		"Revert to saved- reloads the last saved file.\n"
		"Auto Update - any changes apply instantly.\n"
		"Typing Enter in any text field applies changes.\n"
		"New Control menu - creates a new panel in the upper left corner.\n\n" 
		"In the Context Panel:\n"
		"After selecting and moving a panel Ctrl-z will undo the move.\n"
		"Shift clicking panels allows multiple panels to be selected into a group.\n"
		"Ctrl-c copies the settings of the last selected panel.\n"
		"Ctrl-v creates a new panel with the copied settings at the location of the mouse pointer.\n"
		"Arrow keys slowly move panels, holding shift + arrow will slowly resize it.\n"
		"Holding right mouse button down opens a dropdown panel creation menu.\n"
		"  Panel will be created where the menu was opened.\n"
		"Delete key deletes the currently selected panel if it is deletable.\n"
		"  Does nothing to multiple selections.";
		
	MessageBox *helpDlg = new MessageBox ("Build Mode Help", helpText, this);
	helpDlg->AddActionSignalTarget(this);
	helpDlg->DoModal();
}
예제 #3
0
//-----------------------------------------------------------------------------
// Purpose: saves control settings to file
//-----------------------------------------------------------------------------
bool BuildGroup::SaveControlSettings( void )
{
	bool bSuccess = false;
	if ( m_pResourceName )
	{
		KeyValues *rDat = new KeyValues( m_pResourceName );

		// get the data from our controls
		GetSettings( rDat );
		
		char fullpath[ 512 ];
		g_pFullFileSystem->RelativePathToFullPath( m_pResourceName, m_pResourcePathID, fullpath, sizeof( fullpath ) );

		// save the data out to a file
		bSuccess = rDat->SaveToFile( g_pFullFileSystem, fullpath, NULL );
		if (!bSuccess)
		{
			MessageBox *dlg = new MessageBox("BuildMode - Error saving file", "Error: Could not save changes.  File is most likely read only.");
			dlg->DoModal();
		}

		rDat->deleteThis();
	}

	return bSuccess;
}
//-----------------------------------------------------------------------------
// Purpose: Handles an OK message, creating the current token
//-----------------------------------------------------------------------------
void CCreateTokenDialog::OnOK()
{
	// get the data
	char tokenName[1024], tokenValue[1024];
	m_pTokenName->GetText(0, tokenName, 1023);
	m_pTokenValue->GetText(0, tokenValue, 1023);

	if (strlen(tokenName) < 4)
	{
		MessageBox *box = new MessageBox("Create Token Error", "Could not create token.\nToken names need to be at least 4 characters long.");
		box->DoModal();
	}
	else
	{
		// create the token
		wchar_t unicodeString[1024];
		vgui::localize()->ConvertANSIToUnicode(tokenValue, unicodeString, sizeof(unicodeString) / sizeof(wchar_t));
		vgui::localize()->AddString(tokenName, unicodeString);

		// notify the dialog creator
		PostActionSignal(new KeyValues("TokenCreated", "name", tokenName));

		// close
		if (!m_bMultiToken)
		{
			PostMessage(this, new KeyValues("Close"));
		}
	}
}
예제 #5
0
//-----------------------------------------------------------------------------
// Purpose: Handles dialog commands
//-----------------------------------------------------------------------------
void CThemeEditDialog::OnCommand( const char *command )
{
	if ( Q_stricmp( command, "Okay" ) == 0 )
	{
		// check the name is filled in
		char name[64];
		m_pThemeNameEdit->GetText(name, sizeof(name));
		if (Q_strlen(name) <= 0)
		{
			MessageBox *pMessage = new MessageBox ("Bad Theme Name", "Please enter a valid theme name", this);
			pMessage->DoModal();
			return;
		}

		m_pThemeNameEdit->GetText(m_pLevelTheme->m_szName, sizeof(m_pLevelTheme->m_szName));
		m_pThemeDescriptionEdit->GetText(m_pLevelTheme->m_szDescription, sizeof(m_pLevelTheme->m_szDescription));
		char buffer[128];
		m_pThemeAmbientEdit->GetText( buffer, sizeof( buffer ) );

		sscanf( buffer, "%f %f %f", &m_pLevelTheme->m_vecAmbientLight.x, &m_pLevelTheme->m_vecAmbientLight.y, &m_pLevelTheme->m_vecAmbientLight.z );
		// temp to avoid the 0,0,0 losing ambient light bug
		if ( m_pLevelTheme->m_vecAmbientLight == vec3_origin )
		{
			m_pLevelTheme->m_vecAmbientLight.x = 1;
			m_pLevelTheme->m_vecAmbientLight.y = 1;
			m_pLevelTheme->m_vecAmbientLight.z = 1;
		}
		m_pLevelTheme->m_bRequiresVMFTweak = m_pVMFTweakCheck->IsSelected();

		if (m_bCreatingNew)
		{
			CLevelTheme::s_LevelThemes.AddToTail(m_pLevelTheme);
		}
		if ( !m_pLevelTheme->SaveTheme(m_pLevelTheme->m_szName) )
		{
			VGUIMessageBox( this, "Save Error", "Failed to save %s.theme.  Make sure file is checked out from Perforce.", m_pLevelTheme->m_szName );
			return;
		}
		PostActionSignal(new KeyValues("ThemeChanged", "themename", m_pLevelTheme->m_szName));
		OnClose();
	}
	else if (Q_stricmp( command, "Close" ) == 0 )
	{
		if (m_bCreatingNew)
		{
			delete m_pLevelTheme;
			m_pLevelTheme = NULL;
			CLevelTheme::SetCurrentTheme(CLevelTheme::s_pPreviousTheme);
		}
	}
	BaseClass::OnCommand( command );
}
예제 #6
0
//-----------------------------------------------------------------------------
// Purpose: 
// Input  : *command - 
//-----------------------------------------------------------------------------
void CDialogAddBan::OnCommand(const char *command)
{
	bool bClose = false;

	if (!stricmp(command, "Okay"))
	{
		KeyValues *msg = new KeyValues("AddBanValue");
		char buf[64];
		m_pTimeTextEntry->GetText(0,buf,64);
		float time;
		sscanf(buf,"%f",&time);
		if(time<0) 
		{
			MessageBox *dlg = new MessageBox("Add Ban Error", "The time you entered is invalid. \nIt must be equal to or greater than zero.");
			dlg->DoModal();
			bClose=false;
		}
		else
		{
			msg->SetString("time", buf );
			m_pIDTextEntry->GetText(0, buf, sizeof(buf)-1);
			msg->SetString("id", buf);
			msg->SetString("type",m_cType);
			msg->SetInt("ipcheck",IsIPCheck());

			PostActionSignal(msg);

			bClose = true;
		}
	}
	else if (!stricmp(command, "Close"))
	{
		bClose = true;
	}
	else
	{
		BaseClass::OnCommand(command);
	}

	if (bClose)
	{
		PostMessage(this, new KeyValues("Close"));
		MarkForDeletion();
	}
}
void CTilegenKVEditorPage::OnCommand( const char *command )
{
	if ( !Q_stricmp( command, "Save" ) )
	{
		KeyValues *pKV = GetKeyValues();
						
		char fullFilePathBuffer [512];
		Q_snprintf(fullFilePathBuffer, sizeof(fullFilePathBuffer),"C:\\Program Files\\Steam\\steamapps\\sourcemods\\alienswarmdirectormod\\%s", m_szFilename);
		Msg("Saving to [%s]", fullFilePathBuffer);

		//if ( pKV != NULL && !pKV->SaveToFile( g_pFullFileSystem, m_szFilename, "GAME" ) )
		if ( pKV != NULL && !pKV->SaveToFile( g_pFullFileSystem, fullFilePathBuffer ) )
		{
			if ( p4 )
			{
				char fullPath[MAX_PATH];
				g_pFullFileSystem->RelativePathToFullPath( m_szFilename, "GAME", fullPath, MAX_PATH );
				if ( p4->IsFileInPerforce( fullPath ) )
				{
					MessageBox *pMessage = new MessageBox( "Check Out?", "File is not writeable. Would you like to check it out from Perforce?", this );
					pMessage->SetCancelButtonVisible( true );
					pMessage->SetOKButtonText( "#MessageBox_Yes" );
					pMessage->SetCancelButtonText( "#MessageBox_No" );
					pMessage->SetCommand( new KeyValues( "CheckOutFromP4", "file", fullPath ) );
					pMessage->DoModal();
					return;
				}
			}
			else
			{
				VGUIMessageBox( this, "Save Error", "Failed to save %s.  Make sure file is checked out from Perforce.", m_szFilename );
			}
		}
		UpdateList();
		return;
	}
	else if ( !Q_stricmp( command, "New" ) )
	{
		SaveNew();
		return;
	}
	BaseClass::OnCommand( command );
}
예제 #8
0
void CTilegenLayoutSystemPage::OnFileSelected( const char *pFullPath )
{
	if ( g_pFullFileSystem->FileExists( pFullPath ) )
	{
		VGUIMessageBox( this, "Save Error", "A layout system already exists with filename %s.", pFullPath );
		return;
	}
	// create new keys
	KeyValues *pNewKeys = new KeyValues( "Mission" );
	// save them at the full path
	if ( !pNewKeys->SaveToFile( g_pFullFileSystem, pFullPath ) )
	{
		VGUIMessageBox( this, "Save Error", "Failed to save new file %s.", pFullPath );
		return;
	}
	m_pEditor->SetMissionData( pNewKeys );

	m_pReloadMissionButton->SetVisible( true );
	m_pSaveButton->SetVisible( true );
	m_pGenerateButton->SetVisible( true );
	bool bConverted = g_pFullFileSystem->FullPathToRelativePath( pFullPath, m_szFilename, MAX_PATH );
	if ( !bConverted )
	{
		Warning( "Failed to convert this to a relative path: %s\n", pFullPath );
		return;
	}
	m_pFilenameLabel->SetText( m_szFilename + Q_strlen( "tilegen/" ) );	
	m_pNewMissionDatabase->AddFile( pNewKeys, m_szFilename );
	UpdateList();

	if ( p4 )
	{
		MessageBox *pMessage = new MessageBox( "Add to P4?", "Would you like to add this mission to perforce?", this );
		pMessage->SetCancelButtonVisible( true );
		pMessage->SetOKButtonText( "#MessageBox_Yes" );
		pMessage->SetCancelButtonText( "#MessageBox_No" );
		pMessage->SetCommand( new KeyValues( "AddToP4", "file", pFullPath ) );
		pMessage->DoModal();
	}
}
예제 #9
0
//-----------------------------------------------------------------------------
// Purpose: Parse posted messages
//			 
//-----------------------------------------------------------------------------
void CConfigPanel::OnCommand(const char *command)
{

	if(!stricmp(command,"okay"))
	{ // save away the new settings
		char timeText[20];
		int time,timeGraphs;

		m_pRefreshTextEntry->GetText(0,timeText,20);
		sscanf(timeText,"%i",&time);
	
		memset(timeText,0x0,sizeof(timeText));
		m_pGraphsRefreshTimeTextEntry->GetText(0,timeText,20);
		sscanf(timeText,"%i",&timeGraphs);


		if(time>0 && time < 9999 && timeGraphs>0 && timeGraphs< 9999) 
		{

			CServerPage::GetInstance()->SetConfig(m_pRefreshCheckButton->IsSelected(),
													m_pRconCheckButton->IsSelected(),
													time,
													m_pGraphsButton->IsSelected(),
													timeGraphs,
													m_pLogsButton->IsSelected());
			OnClose();

		}
		else
		{
			MessageBox *dlg = new MessageBox ("Config", "Time value is out of range. (0<x<9999)");
			dlg->DoModal();
		}
	}
	else if(!stricmp(command,"close") )
	{
		OnClose();
	}

}
예제 #10
0
void CTilegenKVEditorPage::OnCommand( const char *command )
{
	if ( !Q_stricmp( command, "Save" ) )
	{
		KeyValues *pKV = GetKeyValues();

		if ( pKV != NULL && !pKV->SaveToFile( g_pFullFileSystem, m_szFilename, "MOD" ) )
		{
			if ( p4 )
			{
				char fullPath[MAX_PATH];
				g_pFullFileSystem->RelativePathToFullPath( m_szFilename, "MOD", fullPath, MAX_PATH );
				if ( p4->IsFileInPerforce( fullPath ) )
				{
					MessageBox *pMessage = new MessageBox( "Check Out?", "File is not writeable. Would you like to check it out from Perforce?", this );
					pMessage->SetCancelButtonVisible( true );
					pMessage->SetOKButtonText( "#MessageBox_Yes" );
					pMessage->SetCancelButtonText( "#MessageBox_No" );
					pMessage->SetCommand( new KeyValues( "CheckOutFromP4", "file", fullPath ) );
					pMessage->DoModal();
					return;
				}
			}
			else
			{
				VGUIMessageBox( this, "Save Error", "Failed to save %s.  Make sure file is checked out from Perforce.", m_szFilename );
			}
		}
		UpdateList();
		return;
	}
	else if ( !Q_stricmp( command, "New" ) )
	{
		SaveNew();
		return;
	}
	BaseClass::OnCommand( command );
}
예제 #11
0
void CTileGenDialog::OnFileSelected( const char *fullpath )
{
	if ( m_FileSelectType == FST_LAYOUT_SAVE_AS )
	{
		m_pMapLayout->SetCurrentFilename(fullpath);
		m_pMapLayout->SaveMapLayout(fullpath);
	}
	else if ( m_FileSelectType == FST_LAYOUT_OPEN )
	{
		// clear the current map layout, if any
		delete m_pMapLayout;
		m_pMapLayout = new CMapLayout();
		// load in the new one
		if ( !m_pMapLayout->LoadMapLayout(fullpath) )
		{
			MessageBox *pMessage = new MessageBox ("Error", "Error loading map layout", this);
			pMessage->DoModal();
			return;
		}

		// make sure each placed CRoom has a UI panel
		GetMapLayoutPanel()->CreateAllUIPanels();
	}
}
예제 #12
0
//-----------------------------------------------------------------------------
// Purpose: Applies the current settings to the build controls
//-----------------------------------------------------------------------------
void BuildModeDialog::ApplyDataToControls()
{
	// don't apply if the panel is not editable
	if ( !m_pCurrentPanel->IsBuildModeEditable())
	{
		UpdateControlData( m_pCurrentPanel );
		return; // return success, since we are behaving as expected.
	}

	char fieldName[512];
	if (m_pPanelList->m_PanelList[0].m_EditPanel)
	{
		m_pPanelList->m_PanelList[0].m_EditPanel->GetText(fieldName, sizeof(fieldName));
	}
	else
	{
		m_pPanelList->m_PanelList[0].m_EditButton->GetText(fieldName, sizeof(fieldName));
	}

	// check to see if any buildgroup panels have this name
	Panel *panel = m_pBuildGroup->FieldNameTaken(fieldName);
	if (panel)
	{
		if (panel != m_pCurrentPanel)// make sure name is taken by some other panel not this one
		{
			char messageString[255];
			Q_snprintf(messageString, sizeof( messageString ), "Fieldname is not unique: %s\nRename it and try again.", fieldName);
			MessageBox *errorBox = new MessageBox("Cannot Apply", messageString , false);
			errorBox->DoModal();
			UpdateControlData(m_pCurrentPanel);
			m_pApplyButton->SetEnabled(false);
			return;
		}
	}

	// create a section to store settings
	// m_pPanelList->m_pResourceData->getSection( m_pCurrentPanel->GetName(), true );
	KeyValues *dat = new KeyValues( m_pCurrentPanel->GetName() );

	// loop through the textedit filling in settings
	for ( int i = 0; i < m_pPanelList->m_PanelList.Size(); i++ )
	{
		const char *name = m_pPanelList->m_PanelList[i].m_szName;
		char buf[512];
		if (m_pPanelList->m_PanelList[i].m_EditPanel)
		{
			m_pPanelList->m_PanelList[i].m_EditPanel->GetText(buf, sizeof(buf));
		}
		else
		{
			m_pPanelList->m_PanelList[i].m_EditButton->GetText(buf, sizeof(buf));
		}

		switch (m_pPanelList->m_PanelList[i].m_iType)
		{
		case TYPE_CORNER:
		case TYPE_AUTORESIZE:
			// the integer value is assumed to be the first part of the string for these items
			dat->SetInt(name, atoi(buf));
			break;

		default:
			dat->SetString(name, buf);
			break;
		}
	}

	// dat is built, hand it back to the control
	m_pCurrentPanel->ApplySettings( dat );

	if ( m_pBuildGroup->GetContextPanel() )
	{
		m_pBuildGroup->GetContextPanel()->Repaint();
	}

	m_pApplyButton->SetEnabled(false);
	m_pSaveButton->SetEnabled(true);
}
예제 #13
0
void CRoomTemplatePanel::OnMouseReleased(vgui::MouseCode code)
{
	if (m_bRoomTemplateEditMode && code == MOUSE_RIGHT)
	{
		// find which tile we clicked in
		int rx, ry;
		rx = ry = 0;
		LocalToScreen( rx, ry );
		int mx, my;
		input()->GetCursorPos(mx, my);
		mx = mx - rx;
		my = my - ry;
		if (mx < 0 || my < 0)
			return;

		if ( m_hMenu.Get() != NULL )
		{
			m_hMenu->MarkForDeletion();
			m_hMenu = NULL;
		}

		int tile_size = g_pTileGenDialog->RoomTemplatePanelTileSize();
		int iTileX = mx / tile_size;
		int iTileY = my / tile_size;

		vgui::Panel *parent = GetParent();
		CRoomTemplateEditDialog *pEdit = dynamic_cast<CRoomTemplateEditDialog*>(parent);
		if (pEdit)
		{
			pEdit->m_iSelectedTileX = iTileX;
			pEdit->m_iSelectedTileY = iTileY; //(m_pRoomTemplate->GetTilesY()-1) - iTileY;	// reverse y axis

			// find exits in this tile at this spot
			const CRoomTemplate *pTemplate = pEdit->m_pRoomTemplate;
			int iExits = pEdit->m_pRoomTemplate->m_Exits.Count();
			bool bHasNorthExit = false, bHasEastExit = false, bHasSouthExit = false, bHasWestExit = false;
			for (int i=iExits-1;i>=0;i--)
			{
				CRoomTemplateExit *pExit = pTemplate->m_Exits[i];
				if (pExit->m_iXPos == iTileX && pExit->m_iYPos == iTileY)
				{
					switch( pExit->m_ExitDirection )
					{
						case EXITDIR_NORTH: bHasNorthExit = true; break;
						case EXITDIR_EAST: bHasEastExit = true; break;
						case EXITDIR_SOUTH: bHasSouthExit = true; break;
						case EXITDIR_WEST: bHasWestExit = true; break;
					}
				}
			}

			vgui::Menu *pEditExitMenu = new Menu(this, "EditExitMenu");

			if ( bHasNorthExit )
			{
				pEditExitMenu->AddMenuItem("North exit", "EditExitNorth", parent);
			}			
			if ( bHasEastExit )
			{
				pEditExitMenu->AddMenuItem("East exit", "EditExitEast", parent);
			}
			if ( bHasSouthExit )
			{
				pEditExitMenu->AddMenuItem("South exit", "EditExitSouth", parent);
			}
			if ( bHasWestExit )
			{
				pEditExitMenu->AddMenuItem("West exit", "EditExitWest", parent);
			}

			vgui::Menu *pAddExitMenu = new Menu(this, "AddExitMenu");
			if ( !bHasNorthExit )
			{
				pAddExitMenu->AddMenuItem("To the north", "AddExitNorth", parent);
			}
			if ( !bHasEastExit )
			{
				pAddExitMenu->AddMenuItem("To the east", "AddExitEast", parent);
			}
			if ( !bHasSouthExit )
			{
				pAddExitMenu->AddMenuItem("To the south", "AddExitSouth", parent);
			}
			if ( !bHasWestExit )
			{
				pAddExitMenu->AddMenuItem("To the west", "AddExitWest", parent);
			}

			vgui::Menu *pRightClickMenu = new Menu(this, "RightClickMenu");				
			pRightClickMenu->AddMenuItem("Clear all exits from this tile", "ClearExitsFromTile" , parent);
			pRightClickMenu->AddMenuItem("Clear all exits from this room template", "ClearAllExits", parent);
			pRightClickMenu->AddCascadingMenuItem( "AddExit", "Add exit to this tile...", "", this, pAddExitMenu );
			pRightClickMenu->AddCascadingMenuItem( "EditExit", "Exit properties...", "", this, pEditExitMenu );
			pRightClickMenu->SetPos( mx+rx, my+ry );
			pRightClickMenu->SetVisible( true );
			m_hMenu = pRightClickMenu;
		}
		else
		{
			MessageBox *pMessage = new MessageBox ("Error", "Couldn't cast RoomTemplatePanel's parent to RoomTemplateEditDialog", this);
			pMessage->DoModal();
		}
		
		//char buffer[256];
		//Q_snprintf(buffer, sizeof(buffer), "tilex = %d tiley = %d\n", iTileX, iTileY);
		//MessageBox *pMessage = new MessageBox ("Right clicked roomtemplatepanel", buffer, this);
		//pMessage->DoModal();
		return;
	}
	if (m_bRoomTemplateBrowserMode)
	{
		if (code == MOUSE_LEFT)
		{
			g_pTileGenDialog->SetCursorRoomTemplate( m_pRoomTemplate );
		}
		else if (code == MOUSE_RIGHT)
		{
			if (m_pRoomTemplate)
			{
				// The convoluted FindRoom() call is so we can get a non-const pointer to the room template for the edit dialog to modify.
				CRoomTemplateEditDialog *pDialog = new CRoomTemplateEditDialog( g_pTileGenDialog, "RoomTemplateEditDialog", m_pRoomTemplate->m_pLevelTheme->FindRoom( m_pRoomTemplate->GetFullName() ), false );

				pDialog->AddActionSignalTarget( g_pTileGenDialog );
				pDialog->DoModal();
			}
		}
	}
	BaseClass::OnMouseReleased(code);
}
예제 #14
0
//-----------------------------------------------------------------------------
// Purpose: Parse commands coming in from the VGUI dialog
//-----------------------------------------------------------------------------
void CTileGenDialog::OnCommand( const char *command )
{
	if ( Q_stricmp( command, "Themes" ) == 0 )
	{
		// Launch the theme editing window
		CThemesDialog *pDialog = new CThemesDialog( this, "ThemesDialog", true );

		pDialog->AddActionSignalTarget( this );
		pDialog->DoModal();
	}
	else if ( Q_stricmp( command, "NewRoomTemplate" ) == 0 )
	{
		if (!CLevelTheme::s_pCurrentTheme)
		{
			MessageBox *pMessage = new MessageBox ("No theme selected", "You must select a theme before creating a new room template.", this);
			pMessage->DoModal();
			return;
		}
		CRoomTemplate *pRoomTemplate = new CRoomTemplate(CLevelTheme::s_pCurrentTheme);
		if (pRoomTemplate)
		{
			// Launch the room template editing window
			CRoomTemplateEditDialog *pDialog = new CRoomTemplateEditDialog( this, "RoomTemplateEditDialog", pRoomTemplate, true );

			pDialog->AddActionSignalTarget( this );
			pDialog->DoModal();
		}
	}
	else if ( Q_stricmp( command, "ExportVMF" ) == 0 )
	{
		if (!m_VMFExporter->ExportVMF( GetMapLayout(), "output.vmf", true ) )
		{			
			MessageBox *pMessage = new MessageBox ("VMF Export Error", m_VMFExporter->m_szLastExporterError, this);
			pMessage->DoModal();
			return;
		}
		if ( !m_VMFExporter->ShowExportErrors() )
		{
			MessageBox *pMessage = new MessageBox ("VMF Export", "Output.vmf exported okay!", this);
			pMessage->DoModal();
		}
		return;
	}
	else if ( Q_stricmp( command, "ExportAndPlay" ) == 0 || Q_stricmp( command, "ExportAndPlayClean" ) == 0 )
	{
		m_pMapLayout->SaveMapLayout( "maps/output.layout" );
		if ( engine )
		{
			char buffer[512];
			if ( Q_stricmp( command, "ExportAndPlayClean" ) == 0 )
			{
				Q_snprintf(buffer, sizeof(buffer), "asw_spawning_enabled 0;  asw_build_map %s", "output.layout" );
			}
			else
			{
				Q_snprintf(buffer, sizeof(buffer), "asw_spawning_enabled 1;  asw_build_map %s", "output.layout" );
			}
			engine->ClientCmd_Unrestricted( buffer );
		}
		else
		{
			MessageBox *pMessage = new MessageBox ("Map Exported", "To build and play map, enter into the console:\n\nasw_build_map output", this);
			pMessage->DoModal();
		}
	}
	else if ( Q_stricmp( command, "NewMapLayout" ) == 0 )
	{
		// todo: check the current map is saved, print a warning if not?
		delete m_pMapLayout;
		m_pMapLayout = new CMapLayout();
		return;
	}
	else if ( Q_stricmp( command, "OpenMapLayout" ) == 0 )
	{
		// todo: check the current map is saved, print a warning if not?
		DoFileOpen();
		return;
	}
	else if ( Q_stricmp( command, "OpenCurrentMapLayout" ) == 0 )
	{
		// todo: check the current map is saved, print a warning if not?
		
		// clear the current map layout, if any
		delete m_pMapLayout;
		m_pMapLayout = new CMapLayout();
		char mapname[ 255 ];
		Q_snprintf( mapname, sizeof( mapname ), "maps/%s.layout", engine->GetLevelNameShort() );
		// load in the new one
		if ( !m_pMapLayout->LoadMapLayout( mapname ) )
		{
			MessageBox *pMessage = new MessageBox ("Error", "Error loading map layout", this);
			pMessage->DoModal();
			return;
		}

		// make sure each placed CRoom has a UI panel
		GetMapLayoutPanel()->CreateAllUIPanels();

		return;
	}	
	else if ( Q_stricmp( command, "SaveMapLayout" ) == 0 )
	{
		if (Q_strlen(m_pMapLayout->m_szFilename) <= 0)
		{
			DoFileSaveAs();
		}
		else
		{
			m_pMapLayout->SaveMapLayout(m_pMapLayout->m_szFilename);
		}
		return;
	}
	else if ( Q_stricmp( command, "SaveMapLayoutAs" ) == 0 )
	{
		DoFileSaveAs();
		return;
	}
	else if ( Q_stricmp( command, "GenerateThumbnails" ) == 0 )
	{
		if ( p4 )
		{
			MessageBox *pMessage = new MessageBox( "Add to P4?", "Would you like to add the thumbnails to perforce?", this );
			pMessage->SetCancelButtonVisible( true );
			pMessage->SetOKButtonText( "#MessageBox_Yes" );
			pMessage->SetCancelButtonText( "#MessageBox_No" );
			pMessage->SetCommand( new KeyValues( "AddToP4", "add", "1" ) );
			pMessage->SetCancelCommand( new KeyValues( "AddToP4", "add", "0" ) );
			pMessage->DoModal();
			return;
		}

		GenerateRoomThumbnails();
		return;
	}
	else if ( !Q_stricmp( command, "PushEncountersApart" ) )
	{
		CASWMissionChooserNPCs::PushEncountersApart( m_pMapLayout );
	}
	else if ( Q_stricmp( command, "LocationLayoutEditor" ) == 0 )
	{
		vgui::Frame *pFrame = new CLocation_Editor_Frame( this, "LocationEditorFrame" );
		pFrame->MoveToCenterOfScreen();
		pFrame->Activate();
		return;
	}
	else if ( Q_stricmp( command, "ZoomIn" ) == 0 )
	{
		Zoom( 10 );
		return;
	}
	else if ( Q_stricmp( command, "ZoomOut" ) == 0 )
	{
		Zoom( -10 );
		return;
	}
	else if ( !Q_stricmp( command, "TileCheck" ) )
	{
		vgui::Frame *pFrame = new CTile_Check_Frame( this, "TileCheckFrame" );
		pFrame->MoveToCenterOfScreen();
		pFrame->Activate();
		return;
	}
	else if ( !Q_stricmp( command, "ShowOptionalParameters" ) )
	{
		m_pLayoutSystemPage->GetEditor()->ShowOptionalValues( m_pToolsMenu->IsChecked( m_nShowDefaultParametersMenuItemID ) );
		return;
	}
	else if ( !Q_stricmp( command, "ShowAddButtons" ) )
	{
		m_pLayoutSystemPage->GetEditor()->ShowAddButtons( m_pToolsMenu->IsChecked( m_nShowAddButtonsMenuItemID ) );
		return;
	}

	BaseClass::OnCommand( command );
}