mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-18 14:31:50 +00:00
Thing Info panel: thing action is no longer shown in Doom map format.
Sector and Thing Info panels: fixed possible crash when trying to show unknown thing/sector flag. Hints were not shown properly when multiselection was started while highlighting a map element. Copy/Paste actions work much faster now. Classic modes: rendered grid size in now adjusted to current zoom level.
This commit is contained in:
parent
1bd58bab4b
commit
9df67e8b22
15 changed files with 754 additions and 151 deletions
|
@ -789,7 +789,9 @@
|
|||
<Compile Include="GZBuilder\Windows\TagStatisticsForm.Designer.cs">
|
||||
<DependentUpon>TagStatisticsForm.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="IO\ClipboardStreamReader.cs" />
|
||||
<Compile Include="IO\DoomColormapReader.cs" />
|
||||
<Compile Include="IO\ClipboardStreamWriter.cs" />
|
||||
<Compile Include="Map\GroupInfo.cs" />
|
||||
<Compile Include="Map\SelectionType.cs" />
|
||||
<Compile Include="Map\MapElementCollection.cs" />
|
||||
|
|
|
@ -236,7 +236,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
flags.Items.Clear();
|
||||
foreach(KeyValuePair<string, bool> group in s.Flags) {
|
||||
if(group.Value) {
|
||||
ListViewItem item = new ListViewItem(General.Map.Config.SectorFlags[group.Key]);
|
||||
ListViewItem item = new ListViewItem(General.Map.Config.SectorFlags.ContainsKey(group.Key) ? General.Map.Config.SectorFlags[group.Key] : group.Key);
|
||||
item.Checked = true;
|
||||
flags.Items.Add(item);
|
||||
}
|
||||
|
|
20
Source/Core/Controls/ThingInfoPanel.Designer.cs
generated
20
Source/Core/Controls/ThingInfoPanel.Designer.cs
generated
|
@ -31,8 +31,8 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
System.Windows.Forms.Label label5;
|
||||
System.Windows.Forms.Label label4;
|
||||
System.Windows.Forms.Label label3;
|
||||
System.Windows.Forms.Label label2;
|
||||
System.Windows.Forms.Label label1;
|
||||
this.labelaction = new System.Windows.Forms.Label();
|
||||
this.infopanel = new System.Windows.Forms.GroupBox();
|
||||
this.arg5 = new System.Windows.Forms.Label();
|
||||
this.arglbl5 = new System.Windows.Forms.Label();
|
||||
|
@ -57,7 +57,6 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
label5 = new System.Windows.Forms.Label();
|
||||
label4 = new System.Windows.Forms.Label();
|
||||
label3 = new System.Windows.Forms.Label();
|
||||
label2 = new System.Windows.Forms.Label();
|
||||
label1 = new System.Windows.Forms.Label();
|
||||
this.infopanel.SuspendLayout();
|
||||
this.spritepanel.SuspendLayout();
|
||||
|
@ -91,14 +90,14 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
label3.TabIndex = 3;
|
||||
label3.Text = "Position:";
|
||||
//
|
||||
// label2
|
||||
// labelaction
|
||||
//
|
||||
label2.AutoSize = true;
|
||||
label2.Location = new System.Drawing.Point(17, 39);
|
||||
label2.Name = "label2";
|
||||
label2.Size = new System.Drawing.Size(41, 14);
|
||||
label2.TabIndex = 2;
|
||||
label2.Text = "Action:";
|
||||
this.labelaction.AutoSize = true;
|
||||
this.labelaction.Location = new System.Drawing.Point(17, 39);
|
||||
this.labelaction.Name = "labelaction";
|
||||
this.labelaction.Size = new System.Drawing.Size(41, 14);
|
||||
this.labelaction.TabIndex = 2;
|
||||
this.labelaction.Text = "Action:";
|
||||
//
|
||||
// label1
|
||||
//
|
||||
|
@ -128,7 +127,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
this.infopanel.Controls.Add(this.action);
|
||||
this.infopanel.Controls.Add(label4);
|
||||
this.infopanel.Controls.Add(label3);
|
||||
this.infopanel.Controls.Add(label2);
|
||||
this.infopanel.Controls.Add(this.labelaction);
|
||||
this.infopanel.Controls.Add(this.type);
|
||||
this.infopanel.Controls.Add(label1);
|
||||
this.infopanel.Location = new System.Drawing.Point(0, 0);
|
||||
|
@ -381,6 +380,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
private System.Windows.Forms.GroupBox infopanel;
|
||||
private System.Windows.Forms.GroupBox flagsPanel;
|
||||
private System.Windows.Forms.ListView flags;
|
||||
private System.Windows.Forms.Label labelaction;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,34 +56,23 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
float zvalue;
|
||||
|
||||
// Show/hide stuff depending on format
|
||||
if(!General.Map.FormatInterface.HasActionArgs)
|
||||
{
|
||||
arglbl1.Visible = false;
|
||||
arglbl2.Visible = false;
|
||||
arglbl3.Visible = false;
|
||||
arglbl4.Visible = false;
|
||||
arglbl5.Visible = false;
|
||||
arg1.Visible = false;
|
||||
arg2.Visible = false;
|
||||
arg3.Visible = false;
|
||||
arg4.Visible = false;
|
||||
arg5.Visible = false;
|
||||
infopanel.Width = doomformatwidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
arglbl1.Visible = true;
|
||||
arglbl2.Visible = true;
|
||||
arglbl3.Visible = true;
|
||||
arglbl4.Visible = true;
|
||||
arglbl5.Visible = true;
|
||||
arg1.Visible = true;
|
||||
arg2.Visible = true;
|
||||
arg3.Visible = true;
|
||||
arg4.Visible = true;
|
||||
arg5.Visible = true;
|
||||
infopanel.Width = hexenformatwidth;
|
||||
}
|
||||
bool hasArgs = General.Map.FormatInterface.HasActionArgs;
|
||||
arglbl1.Visible = hasArgs;
|
||||
arglbl2.Visible = hasArgs;
|
||||
arglbl3.Visible = hasArgs;
|
||||
arglbl4.Visible = hasArgs;
|
||||
arglbl5.Visible = hasArgs;
|
||||
arg1.Visible = hasArgs;
|
||||
arg2.Visible = hasArgs;
|
||||
arg3.Visible = hasArgs;
|
||||
arg4.Visible = hasArgs;
|
||||
arg5.Visible = hasArgs;
|
||||
infopanel.Width = (hasArgs ? hexenformatwidth : doomformatwidth);
|
||||
|
||||
//mxd
|
||||
bool hasAction = General.Map.FormatInterface.HasThingAction;
|
||||
action.Visible = hasAction;
|
||||
labelaction.Visible = hasAction;
|
||||
|
||||
// Move panel
|
||||
spritepanel.Left = infopanel.Left + infopanel.Width + infopanel.Margin.Right + spritepanel.Margin.Left;
|
||||
|
@ -206,7 +195,7 @@ namespace CodeImp.DoomBuilder.Controls
|
|||
flags.Items.Clear();
|
||||
foreach(KeyValuePair<string, bool> group in t.Flags){
|
||||
if(group.Value) {
|
||||
ListViewItem item = new ListViewItem(General.Map.Config.ThingFlags[group.Key]);
|
||||
ListViewItem item = new ListViewItem(General.Map.Config.ThingFlags.ContainsKey(group.Key) ? General.Map.Config.ThingFlags[group.Key] : group.Key);
|
||||
item.Checked = true;
|
||||
flags.Items.Add(item);
|
||||
}
|
||||
|
|
|
@ -135,12 +135,9 @@
|
|||
<metadata name="label3.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="label2.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<metadata name="labelaction.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="label2.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="label1.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
{
|
||||
#region ================== Constants
|
||||
|
||||
private const string CLIPBOARD_DATA_FORMAT = "DOOM_BUILDER_GEOMETRY";
|
||||
private const string CLIPBOARD_DATA_FORMAT = "GZDOOM_BUILDER_GEOMETRY";
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -228,9 +228,8 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
|
||||
// Write data to stream
|
||||
MemoryStream memstream = new MemoryStream();
|
||||
UniversalStreamWriter writer = new UniversalStreamWriter();
|
||||
writer.RememberCustomTypes = false;
|
||||
writer.Write(copyset, memstream, null);
|
||||
ClipboardStreamWriter writer = new ClipboardStreamWriter(); //mxd
|
||||
writer.Write(copyset, memstream);
|
||||
|
||||
// Set on clipboard
|
||||
Clipboard.SetData(CLIPBOARD_DATA_FORMAT, memstream);
|
||||
|
@ -283,8 +282,7 @@ namespace CodeImp.DoomBuilder.Editing
|
|||
General.Map.Map.ClearAllMarks(true);
|
||||
|
||||
// Read data stream
|
||||
UniversalStreamReader reader = new UniversalStreamReader(General.Map.FormatInterface.UIFields); //mxd
|
||||
reader.StrictChecking = false;
|
||||
ClipboardStreamReader reader = new ClipboardStreamReader(); //mxd
|
||||
General.Map.Map.BeginAddRemove();
|
||||
reader.Read(General.Map.Map, memstream);
|
||||
General.Map.Map.EndAddRemove();
|
||||
|
|
354
Source/Core/IO/ClipboardStreamReader.cs
Normal file
354
Source/Core/IO/ClipboardStreamReader.cs
Normal file
|
@ -0,0 +1,354 @@
|
|||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using CodeImp.DoomBuilder.Config;
|
||||
using CodeImp.DoomBuilder.Geometry;
|
||||
using CodeImp.DoomBuilder.Map;
|
||||
using CodeImp.DoomBuilder.Types;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace CodeImp.DoomBuilder.IO
|
||||
{
|
||||
internal class ClipboardStreamReader
|
||||
{
|
||||
|
||||
#region ================== Variables
|
||||
|
||||
private struct SidedefData
|
||||
{
|
||||
public int OffsetX;
|
||||
public int OffsetY;
|
||||
public int SectorID;
|
||||
public string HighTexture;
|
||||
public string MiddleTexture;
|
||||
public string LowTexture;
|
||||
public Dictionary<string, UniValue> Fields;
|
||||
public Dictionary<string, bool> Flags;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Reading
|
||||
|
||||
// This reads from a stream
|
||||
public MapSet Read(MapSet map, Stream stream) {
|
||||
BinaryReader reader = new BinaryReader(stream);
|
||||
|
||||
// Read the map
|
||||
Dictionary<int, Vertex> vertexlink = ReadVertices(map, reader);
|
||||
Dictionary<int, Sector> sectorlink = ReadSectors(map, reader);
|
||||
Dictionary<int, SidedefData> sidedeflink = ReadSidedefs(reader);
|
||||
ReadLinedefs(map, reader, vertexlink, sectorlink, sidedeflink);
|
||||
ReadThings(map, reader);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private Dictionary<int, Vertex> ReadVertices(MapSet map, BinaryReader reader) {
|
||||
int count = reader.ReadInt32();
|
||||
|
||||
// Create lookup table
|
||||
Dictionary<int, Vertex> link = new Dictionary<int, Vertex>(count);
|
||||
|
||||
// Go for all collections
|
||||
map.SetCapacity(map.Vertices.Count + count, 0, 0, 0, 0);
|
||||
for(int i = 0; i < count; i++) {
|
||||
float x = reader.ReadSingle();
|
||||
float y = reader.ReadSingle();
|
||||
float zc = reader.ReadSingle();
|
||||
float zf = reader.ReadSingle();
|
||||
|
||||
// Create new item
|
||||
Dictionary<string, UniValue> fields = ReadCustomFields(reader);
|
||||
Vertex v = map.CreateVertex(new Vector2D(x, y));
|
||||
if(v != null) {
|
||||
//zoffsets
|
||||
v.ZCeiling = zc;
|
||||
v.ZFloor = zf;
|
||||
|
||||
// Add custom fields
|
||||
v.Fields.BeforeFieldsChange();
|
||||
foreach (KeyValuePair<string, UniValue> group in fields) {
|
||||
v.Fields.Add(group.Key, group.Value);
|
||||
}
|
||||
|
||||
// Add it to the lookup table
|
||||
link.Add(i, v);
|
||||
}
|
||||
}
|
||||
|
||||
// Return lookup table
|
||||
return link;
|
||||
}
|
||||
|
||||
private Dictionary<int, Sector> ReadSectors(MapSet map, BinaryReader reader) {
|
||||
int count = reader.ReadInt32();
|
||||
|
||||
// Create lookup table
|
||||
Dictionary<int, Sector> link = new Dictionary<int, Sector>(count);
|
||||
|
||||
// Go for all collections
|
||||
map.SetCapacity(0, 0, 0, map.Sectors.Count + count, 0);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
int tag = reader.ReadInt32();
|
||||
int effect = reader.ReadInt32();
|
||||
int hfloor = reader.ReadInt32();
|
||||
int hceil = reader.ReadInt32();
|
||||
int bright = reader.ReadInt32();
|
||||
string tfloor = ReadString(reader);
|
||||
string tceil = ReadString(reader);
|
||||
|
||||
//flags
|
||||
Dictionary<string, bool> stringflags = new Dictionary<string, bool>();
|
||||
int numFlags = reader.ReadInt32();
|
||||
for(int f = 0; f < numFlags; f++)
|
||||
stringflags.Add(ReadString(reader), true);
|
||||
|
||||
//add missing flags
|
||||
foreach (KeyValuePair<string, string> flag in General.Map.Config.SectorFlags) {
|
||||
if(stringflags.ContainsKey(flag.Key)) continue;
|
||||
stringflags.Add(flag.Key, false);
|
||||
}
|
||||
|
||||
// Create new item
|
||||
Dictionary<string, UniValue> fields = ReadCustomFields(reader);
|
||||
Sector s = map.CreateSector();
|
||||
if(s != null) {
|
||||
s.Update(hfloor, hceil, tfloor, tceil, effect, stringflags, tag, bright);
|
||||
|
||||
// Add custom fields
|
||||
s.Fields.BeforeFieldsChange();
|
||||
foreach(KeyValuePair<string, UniValue> group in fields) {
|
||||
s.Fields.Add(group.Key, group.Value);
|
||||
}
|
||||
|
||||
// Add it to the lookup table
|
||||
link.Add(i, s);
|
||||
}
|
||||
}
|
||||
|
||||
// Return lookup table
|
||||
return link;
|
||||
}
|
||||
|
||||
// This reads the linedefs and sidedefs
|
||||
private void ReadLinedefs(MapSet map, BinaryReader reader, Dictionary<int, Vertex> vertexlink, Dictionary<int, Sector> sectorlink, Dictionary<int, SidedefData> sidedeflink) {
|
||||
int count = reader.ReadInt32();
|
||||
|
||||
// Go for all lines
|
||||
map.SetCapacity(0, map.Linedefs.Count + count, map.Sidedefs.Count + sidedeflink.Count, 0, 0);
|
||||
for(int i = 0; i < count; i++) {
|
||||
int[] args = new int[Linedef.NUM_ARGS];
|
||||
int tag = reader.ReadInt32();
|
||||
int v1 = reader.ReadInt32();
|
||||
int v2 = reader.ReadInt32();
|
||||
int s1 = reader.ReadInt32();
|
||||
int s2 = reader.ReadInt32();
|
||||
int special = reader.ReadInt32();
|
||||
for(int a = 0; a < Linedef.NUM_ARGS; a++) {
|
||||
args[a] = reader.ReadInt32();
|
||||
}
|
||||
|
||||
//flags
|
||||
Dictionary<string, bool> stringflags = new Dictionary<string, bool>();
|
||||
int numFlags = reader.ReadInt32();
|
||||
for(int f = 0; f < numFlags; f++)
|
||||
stringflags.Add(ReadString(reader), true);
|
||||
|
||||
//add missing flags
|
||||
foreach(KeyValuePair<string, string> flag in General.Map.Config.LinedefFlags) {
|
||||
if(stringflags.ContainsKey(flag.Key)) continue;
|
||||
stringflags.Add(flag.Key, false);
|
||||
}
|
||||
|
||||
//add missing activations
|
||||
foreach (LinedefActivateInfo activate in General.Map.Config.LinedefActivates) {
|
||||
if(stringflags.ContainsKey(activate.Key)) continue;
|
||||
stringflags.Add(activate.Key, false);
|
||||
}
|
||||
|
||||
// Read custom fields
|
||||
Dictionary<string, UniValue> fields = ReadCustomFields(reader);
|
||||
|
||||
// Check if not zero-length
|
||||
if (Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f) {
|
||||
// Create new linedef
|
||||
Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]);
|
||||
if (l != null) {
|
||||
l.Update(stringflags, 0, tag, special, args);
|
||||
l.UpdateCache();
|
||||
|
||||
// Add custom fields
|
||||
l.Fields.BeforeFieldsChange();
|
||||
foreach(KeyValuePair<string, UniValue> group in fields) {
|
||||
l.Fields.Add(group.Key, group.Value);
|
||||
}
|
||||
|
||||
// Connect sidedefs to the line
|
||||
if(s1 > -1) {
|
||||
if(s1 < sidedeflink.Count)
|
||||
AddSidedef(map, sidedeflink[s1], l, true, sectorlink, s1);
|
||||
else
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid front sidedef " + s1 + ". Sidedef has been removed.");
|
||||
}
|
||||
|
||||
if(s2 > -1) {
|
||||
if(s2 < sidedeflink.Count)
|
||||
AddSidedef(map, sidedeflink[s2], l, false, sectorlink, s2);
|
||||
else
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid back sidedef " + s1 + ". Sidedef has been removed.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " is zero-length. Linedef has been removed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddSidedef(MapSet map, SidedefData data, Linedef ld, bool front, Dictionary<int, Sector> sectorlink, int index) {
|
||||
// Create sidedef
|
||||
if(sectorlink.ContainsKey(data.SectorID)) {
|
||||
Sidedef s = map.CreateSidedef(ld, front, sectorlink[data.SectorID]);
|
||||
if(s != null) {
|
||||
s.Update(data.OffsetX, data.OffsetY, data.HighTexture, data.MiddleTexture, data.LowTexture, data.Flags);
|
||||
|
||||
// Add custom fields
|
||||
foreach (KeyValuePair<string, UniValue> group in data.Fields) {
|
||||
s.Fields.Add(group.Key, group.Value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Sidedef references invalid sector " + data.SectorID + ". Sidedef has been removed.");
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<int, SidedefData> ReadSidedefs(BinaryReader reader) {
|
||||
Dictionary<int, SidedefData> sidedeflink = new Dictionary<int, SidedefData>();
|
||||
int count = reader.ReadInt32();
|
||||
|
||||
for(int i = 0; i < count; i++) {
|
||||
SidedefData data = new SidedefData();
|
||||
data.OffsetX = reader.ReadInt32();
|
||||
data.OffsetY = reader.ReadInt32();
|
||||
data.SectorID = reader.ReadInt32();
|
||||
|
||||
data.HighTexture = ReadString(reader);
|
||||
data.MiddleTexture = ReadString(reader);
|
||||
data.LowTexture = ReadString(reader);
|
||||
|
||||
//flags
|
||||
data.Flags = new Dictionary<string, bool>();
|
||||
int numFlags = reader.ReadInt32();
|
||||
for(int f = 0; f < numFlags; f++)
|
||||
data.Flags.Add(ReadString(reader), true);
|
||||
|
||||
//add missing flags
|
||||
foreach(KeyValuePair<string, string> flag in General.Map.Config.SidedefFlags) {
|
||||
if(data.Flags.ContainsKey(flag.Key)) continue;
|
||||
data.Flags.Add(flag.Key, false);
|
||||
}
|
||||
|
||||
//custom fields
|
||||
data.Fields = ReadCustomFields(reader);
|
||||
|
||||
sidedeflink.Add(i, data);
|
||||
}
|
||||
|
||||
return sidedeflink;
|
||||
}
|
||||
|
||||
private void ReadThings(MapSet map, BinaryReader reader) {
|
||||
int count = reader.ReadInt32();
|
||||
|
||||
// Go for all collections
|
||||
map.SetCapacity(0, 0, 0, 0, map.Things.Count + count);
|
||||
for(int i = 0; i < count; i++) {
|
||||
int[] args = new int[Linedef.NUM_ARGS];
|
||||
int tag = reader.ReadInt32();
|
||||
float x = reader.ReadSingle();
|
||||
float y = reader.ReadSingle();
|
||||
float height = reader.ReadSingle();
|
||||
int angledeg = reader.ReadInt32();
|
||||
int type = reader.ReadInt32();
|
||||
int special = reader.ReadInt32();
|
||||
for(int a = 0; a < Linedef.NUM_ARGS; a++) {
|
||||
args[a] = reader.ReadInt32();
|
||||
}
|
||||
|
||||
//flags
|
||||
Dictionary<string, bool> stringflags = new Dictionary<string, bool>();
|
||||
int numFlags = reader.ReadInt32();
|
||||
for(int f = 0; f < numFlags; f++)
|
||||
stringflags.Add(ReadString(reader), true);
|
||||
|
||||
//add missing flags
|
||||
foreach(KeyValuePair<string, string> flag in General.Map.Config.ThingFlags) {
|
||||
if(stringflags.ContainsKey(flag.Key)) continue;
|
||||
stringflags.Add(flag.Key, false);
|
||||
}
|
||||
|
||||
// Create new item
|
||||
Dictionary<string, UniValue> fields = ReadCustomFields(reader);
|
||||
Thing t = map.CreateThing();
|
||||
if(t != null) {
|
||||
t.Update(type, x, y, height, angledeg, stringflags, tag, special, args);
|
||||
|
||||
// Add custom fields
|
||||
t.Fields.BeforeFieldsChange();
|
||||
foreach(KeyValuePair<string, UniValue> group in fields) {
|
||||
t.Fields.Add(group.Key, group.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, UniValue> ReadCustomFields(BinaryReader reader) {
|
||||
Dictionary<string, UniValue> fields = new Dictionary<string, UniValue>();
|
||||
int fieldscount = reader.ReadInt32();
|
||||
|
||||
for(int f = 0; f < fieldscount; f++) {
|
||||
string name = ReadString(reader);
|
||||
UniversalType type = (UniversalType)reader.ReadInt32();
|
||||
UniversalType valueType = (UniversalType)reader.ReadInt32();
|
||||
|
||||
switch(valueType) {
|
||||
case UniversalType.Float:
|
||||
fields.Add(name, new UniValue(type, reader.ReadSingle()));
|
||||
break;
|
||||
|
||||
case UniversalType.Boolean:
|
||||
fields.Add(name, new UniValue(type, reader.ReadBoolean()));
|
||||
break;
|
||||
|
||||
case UniversalType.Integer:
|
||||
fields.Add(name, new UniValue(type, reader.ReadInt32()));
|
||||
break;
|
||||
|
||||
case UniversalType.String:
|
||||
fields.Add(name, new UniValue(type, ReadString(reader)));
|
||||
break;
|
||||
|
||||
default: //WOLOLO! ERRORS!
|
||||
throw new Exception("Got unknown value type while reading custom fields from clipboard data! Field '" + name + "', type '" + type + "', primitive type '" + valueType + "'");
|
||||
}
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
private string ReadString(BinaryReader reader) {
|
||||
int len = reader.ReadInt32();
|
||||
if (len == 0) return string.Empty;
|
||||
char[] chars = new char[len];
|
||||
for (int i = 0; i < len; ++i) chars[i] = reader.ReadChar(); //sb.Append(reader.ReadChar());
|
||||
return new string(chars);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
271
Source/Core/IO/ClipboardStreamWriter.cs
Normal file
271
Source/Core/IO/ClipboardStreamWriter.cs
Normal file
|
@ -0,0 +1,271 @@
|
|||
#region ================== Namespaces
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
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>();
|
||||
|
||||
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
|
||||
}
|
||||
}
|
|
@ -172,6 +172,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
private int cpErrorLine = 0;
|
||||
private string cpErrorFile = "";
|
||||
private char[] space = new[]{ ' ' }; //mxd
|
||||
private char[] newline = new[] { '\n' }; //mxd
|
||||
|
||||
// Configuration root
|
||||
private IDictionary root = null;
|
||||
|
@ -1091,7 +1092,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
{
|
||||
// Count the lines in the block comment
|
||||
string blockdata = data.Substring(pos, np - pos + 2);
|
||||
line += (blockdata.Split("\n".ToCharArray()).Length - 1);
|
||||
line += (blockdata.Split(newline).Length - 1);
|
||||
|
||||
// Skip everything in this block
|
||||
pos = np + 2;
|
||||
|
|
|
@ -61,6 +61,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
private int cpErrorResult = 0;
|
||||
private string cpErrorDescription = "";
|
||||
private int cpErrorLine = 0;
|
||||
private char[] newline = new[]{'\n'}; //mxd
|
||||
|
||||
// Configuration root
|
||||
private UniversalCollection root = null;
|
||||
|
@ -296,7 +297,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
{
|
||||
// Count the lines in the block comment
|
||||
string blockdata = data.Substring(pos, np - pos + 2);
|
||||
line += (blockdata.Split("\n".ToCharArray()).Length - 1);
|
||||
line += (blockdata.Split(newline).Length - 1);
|
||||
|
||||
// Skip everything in this block
|
||||
pos = np + 1;
|
||||
|
@ -690,19 +691,8 @@ namespace CodeImp.DoomBuilder.IO
|
|||
// Check if the value is of boolean type
|
||||
else if(de.Current.Value is bool)
|
||||
{
|
||||
// Check value
|
||||
if((bool)de.Current.Value == true)
|
||||
{
|
||||
// Output the keyword "true"
|
||||
db.Append(leveltabs); db.Append(de.Current.Key); db.Append(spacing);
|
||||
db.Append("="); db.Append(spacing); db.Append("true;"); db.Append(newline);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Output the keyword "false"
|
||||
db.Append(leveltabs); db.Append(de.Current.Key); db.Append(spacing);
|
||||
db.Append("="); db.Append(spacing); db.Append("false;"); db.Append(newline);
|
||||
}
|
||||
db.Append(leveltabs).Append(de.Current.Key).Append(spacing).Append("=").Append(spacing);
|
||||
db.Append((bool)de.Current.Value ? "true;" : "false;").Append(newline);
|
||||
}
|
||||
// Check if value is of float type
|
||||
else if(de.Current.Value is float)
|
||||
|
|
|
@ -231,9 +231,15 @@ namespace CodeImp.DoomBuilder.IO
|
|||
UniversalCollection lc = linescolls[i];
|
||||
int[] args = new int[Linedef.NUM_ARGS];
|
||||
string where = "linedef " + i;
|
||||
int tag = GetCollectionEntry<int>(lc, "id", false, 0, where);
|
||||
int v1 = GetCollectionEntry<int>(lc, "v1", true, 0, where);
|
||||
int v2 = GetCollectionEntry<int>(lc, "v2", true, 0, where);
|
||||
|
||||
if (!vertexlink.ContainsKey(v1) || !vertexlink.ContainsKey(v2)) { //mxd
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references one or more invalid vertices. Linedef has been removed.");
|
||||
continue;
|
||||
}
|
||||
|
||||
int tag = GetCollectionEntry<int>(lc, "id", false, 0, where);
|
||||
int special = GetCollectionEntry<int>(lc, "special", false, 0, where);
|
||||
args[0] = GetCollectionEntry<int>(lc, "arg0", false, 0, where);
|
||||
args[1] = GetCollectionEntry<int>(lc, "arg1", false, 0, where);
|
||||
|
@ -256,48 +262,41 @@ namespace CodeImp.DoomBuilder.IO
|
|||
// Activations
|
||||
foreach(LinedefActivateInfo activate in General.Map.Config.LinedefActivates)
|
||||
stringflags[activate.Key] = GetCollectionEntry<bool>(lc, activate.Key, false, false, where);
|
||||
|
||||
// Create new linedef
|
||||
if(vertexlink.ContainsKey(v1) && vertexlink.ContainsKey(v2))
|
||||
|
||||
// Check if not zero-length
|
||||
if(Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f)
|
||||
{
|
||||
// Check if not zero-length
|
||||
if(Vector2D.ManhattanDistance(vertexlink[v1].Position, vertexlink[v2].Position) > 0.0001f)
|
||||
// Create new linedef
|
||||
Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]);
|
||||
if(l != null)
|
||||
{
|
||||
Linedef l = map.CreateLinedef(vertexlink[v1], vertexlink[v2]);
|
||||
if(l != null)
|
||||
l.Update(stringflags, 0, tag, special, args);
|
||||
l.UpdateCache();
|
||||
|
||||
// Custom fields
|
||||
ReadCustomFields(lc, l, "linedef");
|
||||
|
||||
// Read sidedefs and connect them to the line
|
||||
if(s1 > -1)
|
||||
{
|
||||
l.Update(stringflags, 0, tag, special, args);
|
||||
l.UpdateCache();
|
||||
if(s1 < sidescolls.Count)
|
||||
ReadSidedef(map, sidescolls[s1], l, true, sectorlink, s1);
|
||||
else
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid front sidedef " + s1 + ". Sidedef has been removed.");
|
||||
}
|
||||
|
||||
// Custom fields
|
||||
ReadCustomFields(lc, l, "linedef");
|
||||
|
||||
// Read sidedefs and connect them to the line
|
||||
if(s1 > -1)
|
||||
{
|
||||
if(s1 < sidescolls.Count)
|
||||
ReadSidedef(map, sidescolls[s1], l, true, sectorlink, s1);
|
||||
else
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid front sidedef " + s1 + ". Sidedef has been removed.");
|
||||
}
|
||||
|
||||
if(s2 > -1)
|
||||
{
|
||||
if(s2 < sidescolls.Count)
|
||||
ReadSidedef(map, sidescolls[s2], l, false, sectorlink, s2);
|
||||
else
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid back sidedef " + s1 + ". Sidedef has been removed.");
|
||||
}
|
||||
if(s2 > -1)
|
||||
{
|
||||
if(s2 < sidescolls.Count)
|
||||
ReadSidedef(map, sidescolls[s2], l, false, sectorlink, s2);
|
||||
else
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references invalid back sidedef " + s1 + ". Sidedef has been removed.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " is zero-length. Linedef has been removed.");
|
||||
}
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " references one or more invalid vertices. Linedef has been removed.");
|
||||
General.ErrorLogger.Add(ErrorType.Warning, "Linedef " + i + " is zero-length. Linedef has been removed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -505,8 +504,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
if(e.Key == entryname)
|
||||
{
|
||||
// Let's be kind and cast any int to a float if needed
|
||||
if((typeof(T) == typeof(float)) &&
|
||||
(e.Value.GetType() == typeof(int)))
|
||||
if((typeof(T) == typeof(float)) && (e.Value is int))
|
||||
{
|
||||
// Make it a float
|
||||
object fvalue = (float)(int)e.Value;
|
||||
|
@ -547,8 +545,10 @@ namespace CodeImp.DoomBuilder.IO
|
|||
List<UniversalCollection> list = new List<UniversalCollection>();
|
||||
|
||||
// Make list
|
||||
foreach(UniversalEntry e in collection)
|
||||
if((e.Value is UniversalCollection) && (e.Key == entryname)) list.Add(e.Value as UniversalCollection);
|
||||
foreach (UniversalEntry e in collection) {
|
||||
if (!(e.Value is UniversalCollection) || (e.Key != entryname)) continue; //mxd
|
||||
list.Add(e.Value as UniversalCollection);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
|
|
@ -290,7 +290,7 @@ namespace CodeImp.DoomBuilder.IO
|
|||
if(t.Tag != 0) coll.Add("id", t.Tag);
|
||||
coll.Add("x", t.Position.x);
|
||||
coll.Add("y", t.Position.y);
|
||||
if(t.Position.z != 0.0f) coll.Add("height", (float)t.Position.z);
|
||||
if(t.Position.z != 0.0f) coll.Add("height", t.Position.z);
|
||||
coll.Add("angle", t.AngleDoom);
|
||||
coll.Add("type", t.Type);
|
||||
if(t.Action != 0) coll.Add("special", t.Action);
|
||||
|
|
|
@ -135,6 +135,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
case UniversalType.SectorEffect:
|
||||
case UniversalType.SectorTag:
|
||||
case UniversalType.ThingTag:
|
||||
case UniversalType.ThingType:
|
||||
{
|
||||
int v = 0;
|
||||
//mxd. Seems to work faster this way
|
||||
|
@ -160,6 +161,7 @@ namespace CodeImp.DoomBuilder.Map
|
|||
case UniversalType.String:
|
||||
case UniversalType.Texture:
|
||||
case UniversalType.EnumStrings:
|
||||
case UniversalType.ThingClass:
|
||||
{
|
||||
string v = (string)value;
|
||||
s.rwString(ref v);
|
||||
|
|
|
@ -872,64 +872,62 @@ namespace CodeImp.DoomBuilder.Rendering
|
|||
Vector2D ltpos, rbpos;
|
||||
Vector2D tlb, rbb;
|
||||
Vector2D pos = new Vector2D();
|
||||
float sizeinv = 1f / size;
|
||||
float ystart, yend;
|
||||
float xstart, xend;
|
||||
float from, to;
|
||||
|
||||
// Only render grid when not screen-filling
|
||||
if((size * scale) > 6f)
|
||||
//mxd. Increase rendered grid size if needed
|
||||
if(size * scale <= 6f) do { size *= 2; } while(size * scale <= 6f);
|
||||
float sizeinv = 1f / size;
|
||||
|
||||
// Determine map coordinates for view window
|
||||
ltpos = DisplayToMap(new Vector2D(0, 0));
|
||||
rbpos = DisplayToMap(new Vector2D(windowsize.Width, windowsize.Height));
|
||||
|
||||
// Clip to nearest grid
|
||||
ltpos = GridSetup.SnappedToGrid(ltpos, size, sizeinv);
|
||||
rbpos = GridSetup.SnappedToGrid(rbpos, size, sizeinv);
|
||||
|
||||
// Translate top left boundary and right bottom boundary of map to screen coords
|
||||
tlb = new Vector2D(General.Map.Config.LeftBoundary, General.Map.Config.TopBoundary).GetTransformed(translatex, translatey, scale, -scale);
|
||||
rbb = new Vector2D(General.Map.Config.RightBoundary, General.Map.Config.BottomBoundary).GetTransformed(translatex, translatey, scale, -scale);
|
||||
|
||||
// Draw all horizontal grid lines
|
||||
ystart = rbpos.y > General.Map.Config.BottomBoundary ? rbpos.y : General.Map.Config.BottomBoundary;
|
||||
yend = ltpos.y < General.Map.Config.TopBoundary ? ltpos.y : General.Map.Config.TopBoundary;
|
||||
|
||||
for(float y = ystart; y < yend + size; y += size)
|
||||
{
|
||||
// Determine map coordinates for view window
|
||||
ltpos = DisplayToMap(new Vector2D(0, 0));
|
||||
rbpos = DisplayToMap(new Vector2D(windowsize.Width, windowsize.Height));
|
||||
if(y > General.Map.Config.TopBoundary) y = General.Map.Config.TopBoundary;
|
||||
else if(y < General.Map.Config.BottomBoundary) y = General.Map.Config.BottomBoundary;
|
||||
|
||||
// Clip to nearest grid
|
||||
ltpos = GridSetup.SnappedToGrid(ltpos, size, sizeinv);
|
||||
rbpos = GridSetup.SnappedToGrid(rbpos, size, sizeinv);
|
||||
from = tlb.x < 0 ? 0 : tlb.x;
|
||||
to = rbb.x > windowsize.Width ? windowsize.Width : rbb.x;
|
||||
|
||||
// Translate top left boundary and right bottom boundary of map
|
||||
// to screen coords
|
||||
tlb = new Vector2D(General.Map.Config.LeftBoundary, General.Map.Config.TopBoundary).GetTransformed(translatex, translatey, scale, -scale);
|
||||
rbb = new Vector2D(General.Map.Config.RightBoundary, General.Map.Config.BottomBoundary).GetTransformed(translatex, translatey, scale, -scale);
|
||||
pos.y = y;
|
||||
pos = pos.GetTransformed(translatex, translatey, scale, -scale);
|
||||
|
||||
// Draw all horizontal grid lines
|
||||
ystart = rbpos.y > General.Map.Config.BottomBoundary ? rbpos.y : General.Map.Config.BottomBoundary;
|
||||
yend = ltpos.y < General.Map.Config.TopBoundary ? ltpos.y : General.Map.Config.TopBoundary;
|
||||
// Note: I'm not using Math.Ceiling in this case, because that doesn't work right.
|
||||
gridplotter.DrawGridLineH((int)pos.y, (int)Math.Round(from + 0.49999f), (int)Math.Round(to + 0.49999f), ref c);
|
||||
}
|
||||
|
||||
for (float y = ystart; y < yend + size; y += size)
|
||||
{
|
||||
if (y > General.Map.Config.TopBoundary) y = General.Map.Config.TopBoundary;
|
||||
else if (y < General.Map.Config.BottomBoundary) y = General.Map.Config.BottomBoundary;
|
||||
// Draw all vertical grid lines
|
||||
xstart = ltpos.x > General.Map.Config.LeftBoundary ? ltpos.x : General.Map.Config.LeftBoundary;
|
||||
xend = rbpos.x < General.Map.Config.RightBoundary ? rbpos.x : General.Map.Config.RightBoundary;
|
||||
|
||||
from = tlb.x < 0 ? 0 : tlb.x;
|
||||
to = rbb.x > windowsize.Width ? windowsize.Width : rbb.x;
|
||||
for(float x = xstart; x < xend + size; x += size)
|
||||
{
|
||||
if(x > General.Map.Config.RightBoundary) x = General.Map.Config.RightBoundary;
|
||||
else if(x < General.Map.Config.LeftBoundary) x = General.Map.Config.LeftBoundary;
|
||||
|
||||
pos.y = y;
|
||||
pos = pos.GetTransformed(translatex, translatey, scale, -scale);
|
||||
from = tlb.y < 0 ? 0 : tlb.y;
|
||||
to = rbb.y > windowsize.Height ? windowsize.Height : rbb.y;
|
||||
|
||||
// Note: I'm not using Math.Ceiling in this case, because that doesn't work right.
|
||||
gridplotter.DrawGridLineH((int)pos.y, (int)Math.Round(from + 0.49999f), (int)Math.Round(to + 0.49999f), ref c);
|
||||
}
|
||||
pos.x = x;
|
||||
pos = pos.GetTransformed(translatex, translatey, scale, -scale);
|
||||
|
||||
// Draw all vertical grid lines
|
||||
xstart = ltpos.x > General.Map.Config.LeftBoundary ? ltpos.x : General.Map.Config.LeftBoundary;
|
||||
xend = rbpos.x < General.Map.Config.RightBoundary ? rbpos.x : General.Map.Config.RightBoundary;
|
||||
|
||||
for (float x = xstart; x < xend + size; x += size)
|
||||
{
|
||||
if (x > General.Map.Config.RightBoundary) x = General.Map.Config.RightBoundary;
|
||||
else if (x < General.Map.Config.LeftBoundary) x = General.Map.Config.LeftBoundary;
|
||||
|
||||
from = tlb.y < 0 ? 0 : tlb.y;
|
||||
to = rbb.y > windowsize.Height ? windowsize.Height : rbb.y;
|
||||
|
||||
pos.x = x;
|
||||
pos = pos.GetTransformed(translatex, translatey, scale, -scale);
|
||||
|
||||
// Note: I'm not using Math.Ceiling in this case, because that doesn't work right.
|
||||
gridplotter.DrawGridLineV((int)pos.x, (int)Math.Round(from + 0.49999f), (int)Math.Round(to + 0.49999f), ref c);
|
||||
}
|
||||
// Note: I'm not using Math.Ceiling in this case, because that doesn't work right.
|
||||
gridplotter.DrawGridLineV((int)pos.x, (int)Math.Round(from + 0.49999f), (int)Math.Round(to + 0.49999f), ref c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -182,6 +182,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
|
||||
//mxd
|
||||
protected override void StartMultiSelection() {
|
||||
General.Interface.HideInfo();
|
||||
General.Interface.ShowEditModeHints(multiselectionHints);
|
||||
base.StartMultiSelection();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue