Пример #1
0
/* MapEditorWindow::loadMapScripts
 * Loads any scripts from [map] into the script editor
 *******************************************************************/
void MapEditorWindow::loadMapScripts(Archive::mapdesc_t map)
{
	// Don't bother if no scripting language specified
	if (theGameConfiguration->scriptLanguage().IsEmpty())
	{
		// Hide script editor
		wxAuiManager* m_mgr = wxAuiManager::GetManager(this);
		wxAuiPaneInfo& p_inf = m_mgr->GetPane("script_editor");
		p_inf.Show(false);
		m_mgr->Update();
		return;
	}

	// Don't bother if new map
	if (!map.head)
	{
		panel_script_editor->openScripts(NULL, NULL);
		return;
	}

	// Check for pk3 map
	if (map.archive)
	{
		WadArchive* wad = new WadArchive();
		wad->open(map.head->getMCData());
		vector<Archive::mapdesc_t> maps = wad->detectMaps();
		if (!maps.empty())
		{
			loadMapScripts(maps[0]);
			wad->close();
			delete wad;
			return;
		}
	}

	// Go through map entries
	ArchiveEntry* entry = map.head->nextEntry();
	ArchiveEntry* scripts = NULL;
	ArchiveEntry* compiled = NULL;
	while (entry && entry != map.end->nextEntry())
	{
		// Check for SCRIPTS/BEHAVIOR
		if (theGameConfiguration->scriptLanguage() == "acs_hexen" ||
		        theGameConfiguration->scriptLanguage() == "acs_zdoom")
		{
			if (S_CMPNOCASE(entry->getName(), "SCRIPTS"))
				scripts = entry;
			if (S_CMPNOCASE(entry->getName(), "BEHAVIOR"))
				compiled = entry;
		}

		// Next entry
		entry = entry->nextEntry();
	}

	// Open scripts/compiled if found
	panel_script_editor->openScripts(scripts, compiled);
}
Пример #2
0
/* MapEditorWindow::saveMapAs
 * Saves the current map to a new archive
 *******************************************************************/
bool MapEditorWindow::saveMapAs()
{
	// Show dialog
	SFileDialog::fd_info_t info;
	if (!SFileDialog::saveFile(info, "Save Map As", "Wad Archives (*.wad)|*.wad", this))
		return false;

	// Create new, empty wad
	WadArchive wad;
	ArchiveEntry* head = wad.addNewEntry(mdesc_current.name);
	ArchiveEntry* end = NULL;
	if (mdesc_current.format == MAP_UDMF)
	{
		wad.addNewEntry("TEXTMAP");
		end = wad.addNewEntry("ENDMAP");
	}
	else
	{
		wad.addNewEntry("THINGS");
		wad.addNewEntry("LINEDEFS");
		wad.addNewEntry("SIDEDEFS");
		wad.addNewEntry("VERTEXES");
		end = wad.addNewEntry("SECTORS");
	}

	// Save map data
	mdesc_current.head = head;
	mdesc_current.archive = false;
	mdesc_current.end = end;
	saveMap();

	// Write wad to file
	wad.save(info.filenames[0]);
	Archive* archive = theArchiveManager->openArchive(info.filenames[0], true, true);
	theArchiveManager->addRecentFile(info.filenames[0]);

	// Update current map description
	vector<Archive::mapdesc_t> maps = archive->detectMaps();
	if (!maps.empty())
	{
		mdesc_current.head = maps[0].head;
		mdesc_current.archive = false;
		mdesc_current.end = maps[0].end;
	}

	// Set window title
	SetTitle(S_FMT("SLADE - %s of %s", mdesc_current.name, wad.getFilename(false)));

	return true;
}
Пример #3
0
/* EntryOperations::openMapDB2
 * Opens the map at [entry] with Doom Builder 2, including all open
 * resource archives. Sets up a FileMonitor to update the map in the
 * archive if any changes are made to it in DB2
 *******************************************************************/
bool EntryOperations::openMapDB2(ArchiveEntry* entry)
{
#ifdef __WXMSW__	// Windows only
	string path = path_db2;

	if (path.IsEmpty())
	{
		// Check for DB2 location registry key
		wxRegKey key(wxRegKey::HKLM, "SOFTWARE\\CodeImp\\Doom Builder");
		key.QueryValue("Location", path);

		// Can't proceed if DB2 isn't installed
		if (path.IsEmpty())
		{
			wxMessageBox("Doom Builder 2 must be installed to use this feature.", "Doom Builder 2 Not Found");
			return false;
		}

		// Add default executable name
		path += "\\Builder.exe";
	}

	// Get map info for entry
	Archive::mapdesc_t map = entry->getParent()->getMapInfo(entry);

	// Check valid map
	if (map.format == MAP_UNKNOWN)
		return false;

	// Export the map to a temp .wad file
	string filename = appPath(entry->getParent()->getFilename(false) + "-" + entry->getName(true) + ".wad", DIR_TEMP);
	filename.Replace("/", "-");
	if (map.archive)
	{
		entry->exportFile(filename);
		entry->lock();
	}
	else
	{
		// Write map entries to temporary wad archive
		if (map.head)
		{
			WadArchive archive;

			// Add map entries to archive
			ArchiveEntry* e = map.head;
			while (true)
			{
				archive.addEntry(e, "", true);
				e->lock();
				if (e == map.end) break;
				e = e->nextEntry();
			}

			// Write archive to file
			archive.save(filename);
		}
	}

	// Generate Doom Builder command line
	string cmd = S_FMT("%s \"%s\" -map %s", path, filename, entry->getName());

	// Add base resource archive to command line
	Archive* base = theArchiveManager->baseResourceArchive();
	if (base)
	{
		if (base->getType() == ARCHIVE_WAD)
			cmd += S_FMT(" -resource wad \"%s\"", base->getFilename());
		else if (base->getType() == ARCHIVE_ZIP)
			cmd += S_FMT(" -resource pk3 \"%s\"", base->getFilename());
	}

	// Add resource archives to command line
	for (int a = 0; a < theArchiveManager->numArchives(); ++a)
	{
		Archive* archive = theArchiveManager->getArchive(a);

		// Check archive type (only wad and zip supported by db2)
		if (archive->getType() == ARCHIVE_WAD)
			cmd += S_FMT(" -resource wad \"%s\"", archive->getFilename());
		else if (archive->getType() == ARCHIVE_ZIP)
			cmd += S_FMT(" -resource pk3 \"%s\"", archive->getFilename());
	}

	// Run DB2
	FileMonitor* fm = new DB2MapFileMonitor(filename, entry->getParent(), entry->getName(true));
	wxExecute(cmd, wxEXEC_ASYNC, fm->getProcess());

	return true;
#else
	return false;
#endif//__WXMSW__
}
Пример #4
0
/* MapEditorWindow::saveMap
 * Saves the current map to its archive, or opens the 'save as'
 * dialog if it doesn't currently belong to one
 *******************************************************************/
bool MapEditorWindow::saveMap()
{
	// Check for newly created map
	if (!mdesc_current.head)
		return saveMapAs();

	// Write map to temp wad
	WadArchive* wad = writeMap();
	if (!wad)
		return false;

	// Check for map archive
	Archive* tempwad = NULL;
	Archive::mapdesc_t map = mdesc_current;
	if (mdesc_current.archive && mdesc_current.head)
	{
		tempwad = new WadArchive();
		tempwad->open(mdesc_current.head);
		vector<Archive::mapdesc_t> amaps = tempwad->detectMaps();
		if (amaps.size() > 0)
			map = amaps[0];
		else
			return false;
	}

	// Unlock current map entries
	lockMapEntries(false);

	// Delete current map entries
	ArchiveEntry* entry = map.end;
	Archive* archive = map.head->getParent();
	while (entry && entry != map.head)
	{
		ArchiveEntry* prev = entry->prevEntry();
		archive->removeEntry(entry);
		entry = prev;
	}

	// Create backup
	if (!backup_manager->writeBackup(map_data, map.head->getTopParent()->getFilename(false), map.head->getName(true)))
		LOG_MESSAGE(1, "Warning: Failed to backup map data");

	// Add new map entries
	for (unsigned a = 1; a < wad->numEntries(); a++)
		entry = archive->addEntry(wad->getEntry(a), archive->entryIndex(map.head) + a, NULL, true);

	// Clean up
	delete wad;
	if (tempwad)
	{
		tempwad->save();
		delete tempwad;
	}
	else
	{
		// Update map description
		mdesc_current.end = entry;
	}

	// Finish
	lockMapEntries();
	editor.getMap().setOpenedTime();

	return true;
}
Пример #5
0
/* MapEditorWindow::writeMap
 * Writes the current map as [name] to a wad archive and returns it
 *******************************************************************/
WadArchive* MapEditorWindow::writeMap(string name, bool nodes)
{
	// Get map data entries
	vector<ArchiveEntry*> new_map_data;
	SLADEMap& map = editor.getMap();
	if (mdesc_current.format == MAP_DOOM)
		map.writeDoomMap(new_map_data);
	else if (mdesc_current.format == MAP_HEXEN)
		map.writeHexenMap(new_map_data);
	else if (mdesc_current.format == MAP_UDMF)
	{
		ArchiveEntry* udmf = new ArchiveEntry("TEXTMAP");
		map.writeUDMFMap(udmf);
		new_map_data.push_back(udmf);
	}
	else // TODO: doom64
		return NULL;

	// Check script language
	bool acs = false;
	if (theGameConfiguration->scriptLanguage() == "acs_hexen" ||
		theGameConfiguration->scriptLanguage() == "acs_zdoom")
		acs = true;
	// Force ACS on for Hexen map format, and off for Doom map format
	if (mdesc_current.format == MAP_DOOM) acs = false;
	if (mdesc_current.format == MAP_HEXEN) acs = true;
	bool dialogue = false;
	if (theGameConfiguration->scriptLanguage() == "usdf" ||
		theGameConfiguration->scriptLanguage() == "zsdf")
		dialogue = true;

	// Add map data to temporary wad
	WadArchive* wad = new WadArchive();
	wad->addNewEntry(name);
	// Handle fragglescript and similar content in the map header
	if (mdesc_current.head && mdesc_current.head->getSize() && !mdesc_current.archive)
	{
		wad->getEntry(name)->importMemChunk(mdesc_current.head->getMCData());
	}
	for (unsigned a = 0; a < new_map_data.size(); a++)
		wad->addEntry(new_map_data[a]);
	if (acs) // BEHAVIOR
		wad->addEntry(panel_script_editor->compiledEntry(), "", true);
	if (acs && panel_script_editor->scriptEntry()->getSize() > 0) // SCRIPTS (if any)
		wad->addEntry(panel_script_editor->scriptEntry(), "", true);
	if (mdesc_current.format == MAP_UDMF)
	{
		// Add extra UDMF entries
		for (unsigned a = 0; a < map.udmfExtraEntries().size(); a++)
			wad->addEntry(map.udmfExtraEntries()[a], -1, NULL, true);

		wad->addNewEntry("ENDMAP");
	}

	// Build nodes
	if (nodes)
		buildNodes(wad);

	// Clear current map data
	for (unsigned a = 0; a < map_data.size(); a++)
		delete map_data[a];
	map_data.clear();

	// Update map data
	for (unsigned a = 0; a < wad->numEntries(); a++)
		map_data.push_back(new ArchiveEntry(*(wad->getEntry(a))));

	return wad;
}
Пример #6
0
/* MapEditorWindow::openMap
 * Opens [map] in the editor
 *******************************************************************/
bool MapEditorWindow::openMap(Archive::mapdesc_t map)
{
	// If a map is currently open and modified, prompt to save changes
	if (editor.getMap().isModified())
	{
		wxMessageDialog md(this, S_FMT("Save changes to map %s?", currentMapDesc().name), "Unsaved Changes", wxYES_NO | wxCANCEL);
		int answer = md.ShowModal();
		if (answer == wxID_YES)
			saveMap();
		else if (answer == wxID_CANCEL)
			return true;
	}

	// Show blank map
	this->Show(true);
	map_canvas->Refresh();
	Layout();
	Update();
	Refresh();

	// Clear current map data
	for (unsigned a = 0; a < map_data.size(); a++)
		delete map_data[a];
	map_data.clear();

	// Get map parent archive
	Archive* archive = NULL;
	if (map.head)
	{
		archive = map.head->getParent();

		// Load map data
		if (map.archive)
		{
			WadArchive temp;
			temp.open(map.head->getMCData());
			for (unsigned a = 0; a < temp.numEntries(); a++)
				map_data.push_back(new ArchiveEntry(*(temp.getEntry(a))));
		}
		else
		{
			ArchiveEntry* entry = map.head;
			while (entry)
			{
				bool end = (entry == map.end);
				map_data.push_back(new ArchiveEntry(*entry));
				entry = entry->nextEntry();
				if (end)
					break;
			}
		}
	}

	// Set texture manager archive
	tex_man.setArchive(archive);

	// Clear current map
	closeMap();

	// Attempt to open map
	theSplashWindow->show("Loading Map", true, this);
	bool ok = editor.openMap(map);
	theSplashWindow->hide();

	// Show window if opened ok
	if (ok)
	{
		mdesc_current = map;

		// Read DECORATE definitions if any
		theGameConfiguration->parseDecorateDefs(theArchiveManager->baseResourceArchive());
		for (int i = 0; i < theArchiveManager->numArchives(); ++i)
			theGameConfiguration->parseDecorateDefs(theArchiveManager->getArchive(i));

		// Load scripts if any
		loadMapScripts(map);

		// Lock map entries
		lockMapEntries();

		// Reset map checks panel
		panel_checks->reset();

		map_canvas->viewFitToMap(true);
		map_canvas->Refresh();

		// Set window title
		if (archive)
			SetTitle(S_FMT("SLADE - %s of %s", map.name, archive->getFilename(false)));
		else
			SetTitle(S_FMT("SLADE - %s (UNSAVED)", map.name));

		// Create backup
		if (map.head && !backup_manager->writeBackup(map_data, map.head->getTopParent()->getFilename(false), map.head->getName(true)))
			LOG_MESSAGE(1, "Warning: Failed to backup map data");
	}

	return ok;
}
Пример #7
0
/* MapEditorWindow::handleAction
 * Handles the action [id]. Returns true if the action was handled,
 * false otherwise
 *******************************************************************/
bool MapEditorWindow::handleAction(string id)
{
	// Don't handle actions if hidden
	if (!IsShown())
		return false;

	// Map->Save
	if (id == "mapw_save")
	{
		// Save map
		if (saveMap())
		{
			// Save archive
			Archive* a = currentMapDesc().head->getParent();
			if (a && save_archive_with_map) a->save();
		}

		return true;
	}

	// Map->Save As
	if (id == "mapw_saveas")
	{
		saveMapAs();
		return true;
	}

	// Map->Restore Backup
	if (id == "mapw_backup")
	{
		if (mdesc_current.head)
		{
			Archive* data = backup_manager->openBackup(mdesc_current.head->getTopParent()->getFilename(false), mdesc_current.name);
			if (data)
			{
				vector<Archive::mapdesc_t> maps = data->detectMaps();
				if (!maps.empty())
				{
					editor.getMap().clearMap();
					editor.openMap(maps[0]);
					loadMapScripts(maps[0]);
				}
			}
		}

		return true;
	}

	// Edit->Undo
	if (id == "mapw_undo")
	{
		editor.doUndo();
		return true;
	}

	// Edit->Redo
	if (id == "mapw_redo")
	{
		editor.doRedo();
		return true;
	}

	// Editor->Set Base Resource Archive
	if (id == "mapw_setbra")
	{
		wxDialog dialog_ebr(this, -1, "Edit Base Resource Archives", wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
		BaseResourceArchivesPanel brap(&dialog_ebr);

		wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL);
		sizer->Add(&brap, 1, wxEXPAND|wxALL, 4);

		sizer->Add(dialog_ebr.CreateButtonSizer(wxOK|wxCANCEL), 0, wxEXPAND|wxLEFT|wxRIGHT|wxDOWN, 4);

		dialog_ebr.SetSizer(sizer);
		dialog_ebr.Layout();
		dialog_ebr.SetInitialSize(wxSize(500, 300));
		dialog_ebr.CenterOnParent();
		if (dialog_ebr.ShowModal() == wxID_OK)
			theArchiveManager->openBaseResource(brap.getSelectedPath());

		return true;
	}

	// Editor->Preferences
	if (id == "mapw_preferences")
	{
		PreferencesDialog::openPreferences(this);

		return true;
	}

	// View->Item Properties
	if (id == "mapw_showproperties")
	{
		wxAuiManager* m_mgr = wxAuiManager::GetManager(this);
		wxAuiPaneInfo& p_inf = m_mgr->GetPane("item_props");

		// Toggle window and focus
		p_inf.Show(!p_inf.IsShown());
		map_canvas->SetFocus();

		m_mgr->Update();
		return true;
	}

	// View->Console
	else if (id == "mapw_showconsole")
	{
		wxAuiManager* m_mgr = wxAuiManager::GetManager(this);
		wxAuiPaneInfo& p_inf = m_mgr->GetPane("console");

		// Toggle window and focus
		if (p_inf.IsShown())
		{
			p_inf.Show(false);
			map_canvas->SetFocus();
		}
		else
		{
			p_inf.Show(true);
			p_inf.window->SetFocus();
		}

		p_inf.MinSize(200, 128);
		m_mgr->Update();
		return true;
	}

	// View->Script Editor
	else if (id == "mapw_showscripteditor")
	{
		wxAuiManager* m_mgr = wxAuiManager::GetManager(this);
		wxAuiPaneInfo& p_inf = m_mgr->GetPane("script_editor");

		// Toggle window and focus
		if (p_inf.IsShown())
		{
			p_inf.Show(false);
			map_canvas->SetFocus();
		}
		else if (!theGameConfiguration->scriptLanguage().IsEmpty())
		{
			p_inf.Show(true);
			p_inf.window->SetFocus();
		}

		p_inf.MinSize(200, 128);
		m_mgr->Update();
		return true;
	}

	// View->Map Checks
	else if (id == "mapw_showchecks")
	{
		wxAuiManager* m_mgr = wxAuiManager::GetManager(this);
		wxAuiPaneInfo& p_inf = m_mgr->GetPane("map_checks");

		// Toggle window and focus
		if (p_inf.IsShown())
		{
			p_inf.Show(false);
			map_canvas->SetFocus();
		}
		else
		{
			p_inf.Show(true);
			p_inf.window->SetFocus();
		}

		//p_inf.MinSize(200, 128);
		m_mgr->Update();
		return true;
	}

	// View->Undo History
	else if (id == "mapw_showundohistory")
	{
		wxAuiManager* m_mgr = wxAuiManager::GetManager(this);
		wxAuiPaneInfo& p_inf = m_mgr->GetPane("undo_history");

		// Toggle window
		p_inf.Show(!p_inf.IsShown());

		m_mgr->Update();
		return true;
	}

	// Run Map
	else if (id == "mapw_run_map")
	{
		Archive* archive = NULL;
		if (mdesc_current.head)
			archive = mdesc_current.head->getParent();
		RunDialog dlg(this, archive);
		if (dlg.ShowModal() == wxID_OK)
		{
			WadArchive* wad = writeMap(mdesc_current.name);
			if (wad)
				wad->save(appPath("sladetemp_run.wad", DIR_TEMP));

			string command = dlg.getSelectedCommandLine(archive, mdesc_current.name, wad->getFilename());
			if (!command.IsEmpty())
			{
				// Set working directory
				string wd = wxGetCwd();
				wxSetWorkingDirectory(dlg.getSelectedExeDir());

				// Run
				wxExecute(command, wxEXEC_ASYNC);

				// Restore working directory
				wxSetWorkingDirectory(wd);
			}
		}

		return true;
	}
	
	return false;
}