Пример #1
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;
}
Пример #2
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;
}
Пример #3
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;
}