UltimateZoneBuilder/Source/General/MapManager.cs

376 lines
12 KiB
C#
Raw Normal View History

2007-06-14 23:31:57 +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;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using CodeImp.DoomBuilder.Interface;
using CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Map;
2007-06-15 18:30:55 +00:00
using CodeImp.DoomBuilder.Editing;
using System.Diagnostics;
using CodeImp.DoomBuilder.Rendering;
2007-10-05 11:17:58 +00:00
using CodeImp.DoomBuilder.Data;
2007-06-14 23:31:57 +00:00
#endregion
namespace CodeImp.DoomBuilder
{
internal class MapManager : IDisposable
{
#region ================== Constants
2007-06-24 18:56:43 +00:00
private const string TEMP_MAP_HEADER = "TEMPMAP";
2007-06-14 23:31:57 +00:00
#endregion
#region ================== Variables
// Status
private bool changed;
// Map information
private string filetitle;
private string filepathname;
2007-10-05 11:17:58 +00:00
private MapSet map;
2007-06-14 23:31:57 +00:00
private MapOptions options;
2007-09-27 22:55:03 +00:00
private ConfigurationInfo configinfo;
2007-06-14 23:31:57 +00:00
private Configuration config;
2007-10-05 11:17:58 +00:00
private DataManager data;
2007-06-15 18:30:55 +00:00
private EditMode mode;
private D3DGraphics graphics;
2007-06-24 18:56:43 +00:00
private WAD tempwad;
2007-06-15 18:30:55 +00:00
2007-06-14 23:31:57 +00:00
// Disposing
private bool isdisposed = false;
#endregion
#region ================== Properties
public string FilePathName { get { return filepathname; } }
public string FileTitle { get { return filetitle; } }
public MapOptions Options { get { return options; } }
2007-10-05 11:17:58 +00:00
public MapSet Map { get { return map; } }
2007-06-15 18:30:55 +00:00
public EditMode Mode { get { return mode; } }
2007-10-07 22:21:47 +00:00
public DataManager Data { get { return data; } }
2007-06-14 23:31:57 +00:00
public bool IsChanged { get { return changed; } set { changed = value; } }
public bool IsDisposed { get { return isdisposed; } }
public D3DGraphics Graphics { get { return graphics; } }
2007-10-07 22:21:47 +00:00
public Configuration Configuration { get { return config; } }
2007-06-15 22:38:42 +00:00
2007-06-14 23:31:57 +00:00
#endregion
#region ================== Constructor / Disposer
2007-06-26 08:47:19 +00:00
// Constructor
2007-06-15 18:30:55 +00:00
public MapManager()
2007-06-14 23:31:57 +00:00
{
// We have no destructor
GC.SuppressFinalize(this);
}
// Diposer
public void Dispose()
{
// Not already disposed?
if(!isdisposed)
{
// Dispose
2007-10-05 11:17:58 +00:00
General.WriteLogLine("Unloading data resources...");
2007-06-14 23:31:57 +00:00
data.Dispose();
2007-10-05 11:17:58 +00:00
General.WriteLogLine("Closing temporary file...");
tempwad.Dispose();
General.WriteLogLine("Unloading map data...");
map.Dispose();
General.WriteLogLine("Stopping edit mode...");
2007-06-15 18:30:55 +00:00
mode.Dispose();
2007-10-05 11:17:58 +00:00
General.WriteLogLine("Stopping graphics device...");
2007-06-15 18:30:55 +00:00
graphics.Dispose();
2007-06-24 18:56:43 +00:00
// Remove temp file
2007-10-05 11:17:58 +00:00
General.WriteLogLine("Removing temporary file...");
2007-06-24 18:56:43 +00:00
try { File.Delete(tempwad.Filename); } catch(Exception) { }
// We may spend some time to clean things up here
GC.Collect();
2007-06-14 23:31:57 +00:00
// Done
isdisposed = true;
}
}
#endregion
2007-06-15 18:30:55 +00:00
#region ================== Initialize
// Initializes for a new map
public bool InitializeNewMap(MapOptions options)
{
2007-10-05 10:00:15 +00:00
string tempfile;
2007-06-15 18:30:55 +00:00
// Apply settings
this.filetitle = "unnamed.wad";
this.filepathname = "";
this.changed = false;
this.options = options;
2007-10-05 10:00:15 +00:00
General.WriteLogLine("Creating new map '" + options.CurrentName + "' with configuration '" + options.ConfigFile + "'");
// Initiate graphics
2007-10-05 10:00:15 +00:00
General.WriteLogLine("Initializing graphics device...");
graphics = new D3DGraphics(General.MainWindow.Display);
if(!graphics.Initialize()) return false;
// Load game configuration
2007-10-05 10:00:15 +00:00
General.WriteLogLine("Loading game configuration...");
2007-09-27 22:55:03 +00:00
configinfo = General.GetConfigurationInfo(options.ConfigFile);
2007-06-15 18:30:55 +00:00
config = General.LoadGameConfiguration(options.ConfigFile);
// Create map data
2007-10-05 11:17:58 +00:00
map = new MapSet();
2007-06-26 08:47:19 +00:00
// Create temp wadfile
2007-10-05 10:00:15 +00:00
tempfile = General.MakeTempFilename();
General.WriteLogLine("Creating temporary file: " + tempfile);
tempwad = new WAD(tempfile);
2007-06-26 08:47:19 +00:00
2007-10-05 11:17:58 +00:00
// Load data manager
General.WriteLogLine("Loading data resources...");
data = new DataManager();
data.Load(configinfo.Resources, options.Resources);
2007-06-15 18:30:55 +00:00
// Set default mode
ChangeMode(typeof(FrozenOverviewMode));
// Success
2007-10-05 10:00:15 +00:00
General.WriteLogLine("Map creation done");
2007-06-15 18:30:55 +00:00
return true;
}
2007-06-16 19:53:51 +00:00
// Initializes for an existing map
public bool InitializeOpenMap(string filepathname, MapOptions options)
{
2007-06-24 18:56:43 +00:00
WAD mapwad;
MapSetIO mapio;
2007-10-05 10:00:15 +00:00
string tempfile;
string iointerface;
2007-10-05 11:17:58 +00:00
DataLocation maplocation;
2007-06-24 18:56:43 +00:00
2007-06-16 19:53:51 +00:00
// Apply settings
this.filetitle = Path.GetFileName(filepathname);
this.filepathname = filepathname;
this.changed = false;
this.options = options;
2007-10-05 10:00:15 +00:00
General.WriteLogLine("Opening map '" + options.CurrentName + "' with configuration '" + options.ConfigFile + "'");
// Initiate graphics
2007-10-05 10:00:15 +00:00
General.WriteLogLine("Initializing graphics device...");
graphics = new D3DGraphics(General.MainWindow.Display);
if(!graphics.Initialize()) return false;
// Load game configuration
2007-10-05 10:00:15 +00:00
General.WriteLogLine("Loading game configuration...");
configinfo = General.GetConfigurationInfo(options.ConfigFile);
2007-06-16 19:53:51 +00:00
config = General.LoadGameConfiguration(options.ConfigFile);
// Create map data
2007-10-05 11:17:58 +00:00
map = new MapSet();
2007-06-24 18:56:43 +00:00
// Create temp wadfile
2007-10-05 10:00:15 +00:00
tempfile = General.MakeTempFilename();
General.WriteLogLine("Creating temporary file: " + tempfile);
tempwad = new WAD(tempfile);
2007-06-24 18:56:43 +00:00
// Now open the map file
2007-10-05 10:00:15 +00:00
General.WriteLogLine("Opening source file: " + filepathname);
2007-06-24 18:56:43 +00:00
mapwad = new WAD(filepathname, true);
// Copy the map lumps to the temp file
2007-10-05 10:00:15 +00:00
General.WriteLogLine("Copying map lumps to temporary file...");
2007-06-24 18:56:43 +00:00
CopyLumpsByType(mapwad, options.CurrentName, tempwad, TEMP_MAP_HEADER,
true, true, true, true);
// Close the map file
mapwad.Dispose();
// Read the map from temp file
2007-10-05 10:00:15 +00:00
iointerface = config.ReadSetting("formatinterface", "");
General.WriteLogLine("Initializing map format interface " + iointerface + "...");
mapio = MapSetIO.Create(iointerface, tempwad);
General.WriteLogLine("Reading map data...");
2007-10-05 11:17:58 +00:00
map = mapio.Read(map, TEMP_MAP_HEADER);
2007-06-16 19:53:51 +00:00
// Update structures
2007-10-05 11:17:58 +00:00
map.Update();
// Load data manager
General.WriteLogLine("Loading data resources...");
data = new DataManager();
maplocation = new DataLocation(DataLocation.RESOURCE_WAD, filepathname, false, false);
data.Load(configinfo.Resources, options.Resources, maplocation);
2007-06-16 19:53:51 +00:00
// Set default mode
ChangeMode(typeof(FrozenOverviewMode));
// Success
2007-10-05 10:00:15 +00:00
General.WriteLogLine("Map loading done");
2007-06-16 19:53:51 +00:00
return true;
}
2007-06-15 18:30:55 +00:00
#endregion
2007-06-14 23:31:57 +00:00
#region ================== Methods
2007-06-15 18:30:55 +00:00
2007-06-24 18:56:43 +00:00
// This copies specific map lumps from one WAD to another
private void CopyLumpsByType(WAD source, string sourcemapname,
WAD target, string targetmapname,
bool copyrequired, bool copyblindcopy,
bool copynodebuild, bool copyscript)
2007-06-15 18:30:55 +00:00
{
2007-06-24 18:56:43 +00:00
bool lumprequired, lumpblindcopy, lumpnodebuild;
string lumpscript;
int srcindex, tgtindex;
IDictionary maplumps;
Lump lump, newlump;
2007-06-15 18:30:55 +00:00
2007-06-24 18:56:43 +00:00
// Find the map header in target
tgtindex = target.FindLumpIndex(targetmapname);
// If this header doesnt exists in the target
// then insert at the end of the target
tgtindex = target.Lumps.Count;
// Remove the lumps from target
RemoveLumpsByType(target, targetmapname, copyrequired,
copyblindcopy, copynodebuild, copyscript);
// Find the map header in source
srcindex = source.FindLumpIndex(sourcemapname);
if(srcindex > -1)
2007-06-15 18:30:55 +00:00
{
2007-06-24 18:56:43 +00:00
// Copy the map header from source to target
newlump = target.Insert(targetmapname, tgtindex++, source.Lumps[srcindex].Length);
source.Lumps[srcindex].CopyTo(newlump);
// Go for all the map lump names
maplumps = config.ReadSetting("maplumpnames", new Hashtable());
foreach(DictionaryEntry ml in maplumps)
{
// Read lump settings from map config
lumprequired = config.ReadSetting("maplumpnames." + ml.Key + ".required", false);
lumpblindcopy = config.ReadSetting("maplumpnames." + ml.Key + ".blindcopy", false);
lumpnodebuild = config.ReadSetting("maplumpnames." + ml.Key + ".nodebuild", false);
lumpscript = config.ReadSetting("maplumpnames." + ml.Key + ".script", "");
// Check if this lump should be copied
if((lumprequired && copyrequired) || (lumpblindcopy && copyblindcopy) ||
(lumpnodebuild && copynodebuild) || ((lumpscript != "") && copyscript))
{
// Find the lump in the source
lump = source.FindLump(ml.Key.ToString(), srcindex, srcindex + maplumps.Count + 2);
if(lump != null)
{
// Copy the lump to the target
2007-10-05 11:17:58 +00:00
General.WriteLogLine(ml.Key.ToString() + " copying");
2007-06-24 18:56:43 +00:00
newlump = target.Insert(ml.Key.ToString(), tgtindex++, lump.Length);
lump.CopyTo(newlump);
}
2007-10-05 11:17:58 +00:00
else
{
General.WriteLogLine("WARNING: " + ml.Key.ToString() + " should be copied but was not found!");
}
2007-06-24 18:56:43 +00:00
}
}
2007-06-15 18:30:55 +00:00
}
2007-06-24 18:56:43 +00:00
}
// This copies specific map lumps from one WAD to another
private void RemoveLumpsByType(WAD source, string sourcemapname,
bool copyrequired, bool copyblindcopy,
bool copynodebuild, bool copyscript)
{
bool lumprequired, lumpblindcopy, lumpnodebuild;
string nextlumpname, lumpscript;
int index;
// Find the map header in target
index = source.FindLumpIndex(sourcemapname);
if(index > -1)
2007-06-15 18:30:55 +00:00
{
2007-06-24 18:56:43 +00:00
// Remove the header from target
source.RemoveAt(index);
// Get the name of the next lump
if(index < source.Lumps.Count) nextlumpname = source.Lumps[index].Name;
else nextlumpname = "";
// Do we recognize this lump type?
while(config.ReadSetting("maplumpnames." + nextlumpname, (IDictionary)null) != null)
{
// Read lump settings from map config
lumprequired = config.ReadSetting("maplumpnames." + nextlumpname + ".required", false);
lumpblindcopy = config.ReadSetting("maplumpnames." + nextlumpname + ".blindcopy", false);
lumpnodebuild = config.ReadSetting("maplumpnames." + nextlumpname + ".nodebuild", false);
lumpscript = config.ReadSetting("maplumpnames." + nextlumpname + ".script", "");
2007-10-05 11:17:58 +00:00
// Check if this lump will be removed from target
2007-06-24 18:56:43 +00:00
if((lumprequired && copyrequired) || (lumpblindcopy && copyblindcopy) ||
(lumpnodebuild && copynodebuild) || ((lumpscript != "") && copyscript))
{
// Then remove it from target
2007-10-05 11:17:58 +00:00
General.WriteLogLine(nextlumpname + " removing");
2007-06-24 18:56:43 +00:00
source.RemoveAt(index);
}
else
{
// Advance to the next lump
index++;
}
// Get the name of the next lump
if(index < source.Lumps.Count) nextlumpname = source.Lumps[index].Name;
else nextlumpname = "";
}
2007-06-15 18:30:55 +00:00
}
2007-06-24 18:56:43 +00:00
}
// This changes editing mode
public void ChangeMode(Type modetype, params object[] args)
{
// Dispose current mode
if(mode != null) mode.Dispose();
// Create a new mode
2007-10-05 10:00:15 +00:00
General.WriteLogLine("Switching edit mode to " + modetype.Name + "...");
2007-06-24 18:56:43 +00:00
mode = EditMode.Create(modetype, args);
2007-06-16 19:53:51 +00:00
// Redraw the display
2007-10-05 10:00:15 +00:00
General.MainWindow.RedrawDisplay();
2007-06-15 18:30:55 +00:00
}
2007-06-14 23:31:57 +00:00
#endregion
}
}