mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2024-11-30 15:41:30 +00:00
0369c969d1
Draw Curve Mode: added settings panel. Sectors mode: added "Make Door" button to the toolbar. Swapped Side panel and Info panel z-order. Interface: split toolbar into 3 separate toolbars. All toolbar buttons are now viewable at 1024x768. Interface: grouped stuff in "Modes" menu a bit better. Interface: added "Draw [stuff]" buttons to modes toolbar. Interface: reorganized main menu. Hope it makes more sense now. API: added General.Interface.AddModesButton() and General.Interface.AddModesMenu(), which can be used to add buttons to specific group in "Modes" toolbar and menu items to specific group in "Modes" menu, so actions, which behave like an editing mode, but are not part of one can be added there.
270 lines
8.6 KiB
C#
270 lines
8.6 KiB
C#
#region ================== Namespaces
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using CodeImp.DoomBuilder.Map;
|
|
using System.IO;
|
|
using CodeImp.DoomBuilder.Config;
|
|
using CodeImp.DoomBuilder.Types;
|
|
|
|
#endregion
|
|
|
|
namespace CodeImp.DoomBuilder.IO
|
|
{
|
|
internal class ClipboardStreamWriter
|
|
{
|
|
#region ================== Constants
|
|
|
|
private const string UDMF_CONFIG_NAME = "UDMF.cfg";
|
|
|
|
#endregion
|
|
|
|
#region ================== Variables
|
|
|
|
private Configuration config;
|
|
|
|
#endregion
|
|
|
|
#region ================== Constructor / Disposer
|
|
|
|
public ClipboardStreamWriter() {
|
|
// Make configurations
|
|
config = new Configuration();
|
|
|
|
// Find a resource named UDMF.cfg
|
|
string[] resnames = General.ThisAssembly.GetManifestResourceNames();
|
|
foreach(string rn in resnames) {
|
|
// Found it?
|
|
if(rn.EndsWith(UDMF_CONFIG_NAME, StringComparison.InvariantCultureIgnoreCase)) {
|
|
// Get a stream from the resource
|
|
Stream udmfcfg = General.ThisAssembly.GetManifestResourceStream(rn);
|
|
StreamReader udmfcfgreader = new StreamReader(udmfcfg, Encoding.ASCII);
|
|
|
|
// Load configuration from stream
|
|
config.InputConfiguration(udmfcfgreader.ReadToEnd());
|
|
|
|
// Now we add the linedef flags, activations and thing flags
|
|
// to this list, so that these don't show up in the custom
|
|
// fields list either. We use true as dummy value (it has no meaning)
|
|
|
|
// Add linedef flags
|
|
foreach(KeyValuePair<string, string> flag in General.Map.Config.LinedefFlags)
|
|
config.WriteSetting("managedfields.linedef." + flag.Key, true);
|
|
|
|
// Add linedef activations
|
|
foreach(LinedefActivateInfo activate in General.Map.Config.LinedefActivates)
|
|
config.WriteSetting("managedfields.linedef." + activate.Key, true);
|
|
|
|
//mxd. Add sidedef flags
|
|
foreach(KeyValuePair<string, string> flag in General.Map.Config.SidedefFlags)
|
|
config.WriteSetting("managedfields.sidedef." + flag.Key, true);
|
|
|
|
//mxd. Add sector flags
|
|
foreach(KeyValuePair<string, string> flag in General.Map.Config.SectorFlags)
|
|
config.WriteSetting("managedfields.sector." + flag.Key, true);
|
|
|
|
// Add thing flags
|
|
foreach(KeyValuePair<string, string> flag in General.Map.Config.ThingFlags)
|
|
config.WriteSetting("managedfields.thing." + flag.Key, true);
|
|
|
|
// Done
|
|
udmfcfgreader.Dispose();
|
|
udmfcfg.Dispose();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region ================== Writing
|
|
|
|
public void Write(MapSet map, Stream stream) {
|
|
Write(map.Vertices, map.Linedefs, map.Sidedefs, map.Sectors, map.Things, stream);
|
|
}
|
|
|
|
public void Write(ICollection<Vertex> vertices, ICollection<Linedef> linedefs, ICollection<Sidedef> sidedefs,
|
|
ICollection<Sector> sectors, ICollection<Thing> things, Stream stream) {
|
|
// Create collections
|
|
Dictionary<Vertex, int> vertexids = new Dictionary<Vertex, int>();
|
|
Dictionary<Sidedef, int> sidedefids = new Dictionary<Sidedef, int>();
|
|
Dictionary<Sector, int> sectorids = new Dictionary<Sector, int>();
|
|
|
|
// Index the elements in the data structures
|
|
foreach(Vertex v in vertices) vertexids.Add(v, vertexids.Count);
|
|
foreach(Sidedef sd in sidedefs) sidedefids.Add(sd, sidedefids.Count);
|
|
foreach(Sector s in sectors) sectorids.Add(s, sectorids.Count);
|
|
|
|
BinaryWriter writer = new BinaryWriter(stream);
|
|
// Write the data structures to stream
|
|
WriteVertices(vertices, writer);
|
|
WriteSectors(sectors, writer);
|
|
WriteSidedefs(sidedefs, writer, sectorids);
|
|
WriteLinedefs(linedefs, writer, sidedefids, vertexids);
|
|
WriteThings(things, writer);
|
|
writer.Flush();
|
|
}
|
|
|
|
private void WriteVertices(ICollection<Vertex> vertices, BinaryWriter writer) {
|
|
writer.Write(vertices.Count);
|
|
|
|
foreach(Vertex v in vertices) {
|
|
//write "static" properties
|
|
writer.Write(v.Position.x);
|
|
writer.Write(v.Position.y);
|
|
writer.Write(v.ZCeiling);
|
|
writer.Write(v.ZFloor);
|
|
|
|
// Write custom fields
|
|
AddCustomFields(v.Fields, "vertex", writer);
|
|
}
|
|
}
|
|
|
|
// This adds linedefs
|
|
private void WriteLinedefs(ICollection<Linedef> linedefs, BinaryWriter writer, IDictionary<Sidedef, int> sidedefids, IDictionary<Vertex, int> vertexids) {
|
|
writer.Write(linedefs.Count);
|
|
|
|
// Go for all linedefs
|
|
foreach(Linedef l in linedefs) {
|
|
//write "static" properties
|
|
writer.Write(l.Tag);
|
|
writer.Write(vertexids[l.Start]);
|
|
writer.Write(vertexids[l.End]);
|
|
|
|
//sidedefs
|
|
writer.Write((l.Front != null && sidedefids.ContainsKey(l.Front)) ? sidedefids[l.Front] : -1);
|
|
writer.Write((l.Back != null && sidedefids.ContainsKey(l.Back)) ? sidedefids[l.Back] : -1);
|
|
|
|
//action and args
|
|
writer.Write(l.Action);
|
|
for(int i = 0; i < l.Args.Length; i++) writer.Write(l.Args[i]);
|
|
|
|
AddFlags(l.Flags, writer);
|
|
AddCustomFields(l.Fields, "linedef", writer);
|
|
}
|
|
}
|
|
|
|
// This adds sidedefs
|
|
private void WriteSidedefs(ICollection<Sidedef> sidedefs, BinaryWriter writer, IDictionary<Sector, int> sectorids) {
|
|
writer.Write(sidedefs.Count);
|
|
|
|
// Go for all sidedefs
|
|
foreach(Sidedef s in sidedefs) {
|
|
//write "static" properties
|
|
writer.Write(s.OffsetX);
|
|
writer.Write(s.OffsetY);
|
|
writer.Write(sectorids[s.Sector]);
|
|
|
|
//textures
|
|
writer.Write(s.HighTexture.Length);
|
|
writer.Write(s.HighTexture.ToCharArray());
|
|
writer.Write(s.MiddleTexture.Length);
|
|
writer.Write(s.MiddleTexture.ToCharArray());
|
|
writer.Write(s.LowTexture.Length);
|
|
writer.Write(s.LowTexture.ToCharArray());
|
|
|
|
AddFlags(s.Flags, writer);
|
|
AddCustomFields(s.Fields, "sidedef", writer);
|
|
}
|
|
}
|
|
|
|
// This adds sectors
|
|
private void WriteSectors(ICollection<Sector> sectors, BinaryWriter writer) {
|
|
writer.Write(sectors.Count);
|
|
|
|
// Go for all sectors
|
|
foreach(Sector s in sectors) {
|
|
//write "static" properties
|
|
writer.Write(s.Tag);
|
|
writer.Write(s.Effect);
|
|
writer.Write(s.FloorHeight);
|
|
writer.Write(s.CeilHeight);
|
|
writer.Write(s.Brightness);
|
|
|
|
//textures
|
|
writer.Write(s.FloorTexture.Length);
|
|
writer.Write(s.FloorTexture.ToCharArray());
|
|
writer.Write(s.CeilTexture.Length);
|
|
writer.Write(s.CeilTexture.ToCharArray());
|
|
|
|
AddFlags(s.Flags, writer);
|
|
AddCustomFields(s.Fields, "sector", writer);
|
|
}
|
|
}
|
|
|
|
// This adds things
|
|
private void WriteThings(ICollection<Thing> things, BinaryWriter writer) {
|
|
writer.Write(things.Count);
|
|
|
|
// Go for all things
|
|
foreach(Thing t in things) {
|
|
//write "static" properties
|
|
writer.Write(t.Tag);
|
|
writer.Write(t.Position.x);
|
|
writer.Write(t.Position.y);
|
|
writer.Write(t.Position.z);
|
|
writer.Write(t.AngleDoom);
|
|
writer.Write(t.Type);
|
|
writer.Write(t.Action);
|
|
for(int i = 0; i < t.Args.Length; i++) writer.Write(t.Args[i]);
|
|
|
|
AddFlags(t.Flags, writer);
|
|
AddCustomFields(t.Fields, "thing", writer);
|
|
}
|
|
}
|
|
|
|
private void AddCustomFields(UniFields elementFields, string elementname, BinaryWriter writer) {
|
|
Dictionary<string, UniValue> fields = new Dictionary<string, UniValue>(StringComparer.Ordinal);
|
|
|
|
foreach(KeyValuePair<string, UniValue> f in elementFields) {
|
|
if(config.SettingExists("managedfields." + elementname + "." + f.Key)) continue;
|
|
fields.Add(f.Key, f.Value);
|
|
}
|
|
|
|
writer.Write(fields.Count);
|
|
|
|
foreach(KeyValuePair<string, UniValue> f in fields) {
|
|
writer.Write(f.Key.Length);
|
|
writer.Write(f.Key.ToCharArray());
|
|
|
|
writer.Write(f.Value.Type);
|
|
if(f.Value.Value is bool) {
|
|
writer.Write((int)UniversalType.Boolean);
|
|
writer.Write((bool)f.Value.Value);
|
|
} else if(f.Value.Value is float) {
|
|
writer.Write((int)UniversalType.Float);
|
|
writer.Write((float)f.Value.Value);
|
|
} else if(f.Value.Value.GetType().IsPrimitive) {
|
|
writer.Write((int)UniversalType.Integer);
|
|
writer.Write((int)f.Value.Value);
|
|
} else if(f.Value.Value is string) {
|
|
writer.Write((int)UniversalType.String);
|
|
string s = (string)f.Value.Value;
|
|
writer.Write(s.Length);
|
|
writer.Write(s.ToCharArray());
|
|
} else { //WOLOLO! ERRORS!
|
|
General.ErrorLogger.Add(ErrorType.Error, "Unable to copy Universal Field '" + f.Key + "' to clipboard: unknown value type '" + f.Value.Type + "'!");
|
|
}
|
|
}
|
|
}
|
|
|
|
private void AddFlags(Dictionary<string, bool> elementFlags, BinaryWriter writer) {
|
|
List<string> flags = new List<string>();
|
|
|
|
foreach(KeyValuePair<string, bool> f in elementFlags) {
|
|
if(!f.Value) continue;
|
|
flags.Add(f.Key);
|
|
}
|
|
|
|
writer.Write(flags.Count);
|
|
|
|
foreach(string s in flags) {
|
|
writer.Write(s.Length);
|
|
writer.Write(s.ToCharArray());
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|