some stuff regarding UDMF

This commit is contained in:
codeimp 2008-01-25 19:12:34 +00:00
parent ea75719392
commit 80f4d05965
21 changed files with 3356 additions and 3 deletions

View file

@ -205,6 +205,74 @@ maplumpnames
}
/*
ADDITIONAL UNIVERSAL DOOM MAP FORMAT FIELD DEFINITIONS
Only add fields here that Doom Builder does not edit with its own user-interface!
Field types:
0 = integer
1 = float
2 = string
3 = linedef action
4 = sector effect
5 = texture
6 = flat
*/
universalfields
{
linedefs
{
texture_scale_x
{
type = 1;
default = 1.0f;
}
texture_scale_y
{
type = 1;
default = 1.0f;
}
texture_offset_x
{
type = 1;
default = 0.0f;
}
texture_offset_y
{
type = 1;
default = 0.0f;
}
brightness
{
type = 0;
default = -1;
}
colormap
{
type = 2;
default = "";
}
normalmap
{
type = 5;
default = "STARTAN3";
}
second_action
{
type = 3;
default = 0;
}
}
}
// DEFAULT SECTOR BRIGHTNESS LEVELS
sectorbrightness
{

File diff suppressed because it is too large Load diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 464 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

View file

@ -53,6 +53,8 @@
<Compile Include="Config\TagType.cs" />
<Compile Include="Config\ThingCategory.cs" />
<Compile Include="Config\ThingTypeInfo.cs" />
<Compile Include="Config\UniversalFieldInfo.cs" />
<Compile Include="Config\UniversalFieldType.cs" />
<Compile Include="Controls\ActionAttribute.cs" />
<Compile Include="Controls\KeyControl.cs" />
<Compile Include="Controls\MouseInput.cs" />
@ -143,6 +145,13 @@
<Compile Include="Interface\ConfigForm.Designer.cs">
<DependentUpon>ConfigForm.cs</DependentUpon>
</Compile>
<Compile Include="Interface\FieldsEditorRow.cs" />
<Compile Include="Interface\FieldsEditorControl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Interface\FieldsEditorControl.Designer.cs">
<DependentUpon>FieldsEditorControl.cs</DependentUpon>
</Compile>
<Compile Include="Interface\FlatBrowserForm.cs">
<SubType>Form</SubType>
</Compile>
@ -273,6 +282,7 @@
<Compile Include="IO\IImageReader.cs" />
<Compile Include="IO\Lump.cs" />
<Compile Include="IO\MapSetIO.cs" />
<Compile Include="IO\UniversalMapSetIO.cs" />
<Compile Include="IO\UnknownImageReader.cs" />
<Compile Include="IO\WAD.cs" />
<Compile Include="Interface\MainForm.cs">
@ -409,6 +419,10 @@
<SubType>Designer</SubType>
<DependentUpon>ConfigForm.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Interface\FieldsEditorControl.resx">
<SubType>Designer</SubType>
<DependentUpon>FieldsEditorControl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Interface\FlatBrowserForm.resx">
<DependentUpon>FlatBrowserForm.cs</DependentUpon>
<SubType>Designer</SubType>

View file

@ -74,6 +74,9 @@ namespace CodeImp.DoomBuilder.Config
private List<LinedefActivateInfo> linedefactivates;
private List<GeneralActionCategory> genactioncategories;
// Universal fields
private List<UniversalFieldInfo> linedeffields;
#endregion
#region ================== Properties
@ -110,6 +113,9 @@ namespace CodeImp.DoomBuilder.Config
public List<LinedefActivateInfo> LinedefActivates { get { return linedefactivates; } }
public List<GeneralActionCategory> GenActionCategories { get { return genactioncategories; } }
// Universal fields
public List<UniversalFieldInfo> LinedefFields { get { return linedeffields; } }
#endregion
#region ================== Constructor / Disposer
@ -156,6 +162,9 @@ namespace CodeImp.DoomBuilder.Config
LoadLinedefActions();
LoadLinedefActivations();
LoadLinedefGeneralizedAction();
// Universal fields
linedeffields = LoadUniversalFields("linedefs");
}
// Destructor
@ -169,6 +178,33 @@ namespace CodeImp.DoomBuilder.Config
#region ================== Loading
// This loads a universal fields list
private List<UniversalFieldInfo> LoadUniversalFields(string elementname)
{
List<UniversalFieldInfo> list = new List<UniversalFieldInfo>();
UniversalFieldInfo uf;
IDictionary dic;
// Get fields
dic = cfg.ReadSetting("universalfields." + elementname, new Hashtable());
foreach(DictionaryEntry de in dic)
{
try
{
// Read the field info and add to list
uf = new UniversalFieldInfo(elementname, de.Key.ToString(), cfg);
list.Add(uf);
}
catch(Exception e)
{
General.WriteLogLine("WARNING: Unable to read universal field definition 'universalfields." + elementname + "." + de.Key + "'!");
}
}
// Return result
return list;
}
// Things and thing categories
private void LoadThingCategories()
{

View file

@ -0,0 +1,125 @@
#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 CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Data;
using System.IO;
using System.Diagnostics;
using System.Windows.Forms;
using CodeImp.DoomBuilder.Map;
#endregion
namespace CodeImp.DoomBuilder.Config
{
public class UniversalFieldInfo : IComparable<UniversalFieldInfo>
{
#region ================== Constants
#endregion
#region ================== Variables
// Properties
private string name;
private UniversalFieldType type;
private string defstring;
private int defint;
private float deffloat;
#endregion
#region ================== Properties
public string Name { get { return name; } }
public UniversalFieldType Type { get { return type; } }
public string DefaultStr { get { return defstring; } }
public int DefaultInt { get { return defint; } }
public float DefaultFloat { get { return deffloat; } }
#endregion
#region ================== Constructor / Disposer
// Constructor
internal UniversalFieldInfo(string path, string name, Configuration cfg)
{
string setting = "universalfields." + path + "." + name;
// Initialize
this.name = name;
// Read type
this.type = (UniversalFieldType)cfg.ReadSetting(setting + ".type", 0);
switch(this.type)
{
case UniversalFieldType.Integer:
case UniversalFieldType.LinedefAction:
case UniversalFieldType.SectorEffect:
defint = cfg.ReadSetting(setting + ".default", 0);
deffloat = (float)defint;
defstring = DefaultInt.ToString(CultureInfo.InvariantCulture);
break;
case UniversalFieldType.Float:
deffloat = cfg.ReadSetting(setting + ".default", 0.0f);
defint = (int)Math.Round(deffloat);
defstring = DefaultFloat.ToString(CultureInfo.InvariantCulture);
break;
case UniversalFieldType.String:
case UniversalFieldType.Flat:
case UniversalFieldType.Texture:
defstring = cfg.ReadSetting(setting + ".default", "");
float.TryParse(DefaultStr, NumberStyles.Number, CultureInfo.InvariantCulture, out deffloat);
int.TryParse(DefaultStr, NumberStyles.Number, CultureInfo.InvariantCulture, out defint);
break;
default:
General.WriteLogLine("WARNING: Universal field '" + path + "." + name + "' is defined as unknown type " + (int)this.type + "!");
break;
}
// We have no destructor
GC.SuppressFinalize(this);
}
#endregion
#region ================== Methods
// This presents the item as string
public override string ToString()
{
return name;
}
// This compares against another field
public int CompareTo(UniversalFieldInfo other)
{
return string.Compare(this.name, other.name);
}
#endregion
}
}

View file

@ -0,0 +1,44 @@
#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 CodeImp.DoomBuilder.IO;
using CodeImp.DoomBuilder.Data;
using System.IO;
using System.Diagnostics;
using System.Windows.Forms;
#endregion
namespace CodeImp.DoomBuilder.Config
{
public enum UniversalFieldType
{
Integer = 0,
Float = 1,
String = 2,
LinedefAction = 3,
SectorEffect = 4,
Texture = 5,
Flat = 6
}
}

View file

@ -709,8 +709,8 @@ namespace CodeImp.DoomBuilder.IO
key = "";
val = "";
}
// Otherwise (if not a space) it will be a keyword
else if(c != ' ')
// Otherwise (if not whitespace) it will be a keyword
else if((c != ' ') && (c != '\t'))
{
// Now parsing a keyword
pm = PM_KEYWORD;

View file

@ -0,0 +1,79 @@
#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.IO;
using CodeImp.DoomBuilder.Map;
using CodeImp.DoomBuilder.Geometry;
#endregion
namespace CodeImp.DoomBuilder.IO
{
internal class UniversalMapSetIO : MapSetIO
{
#region ================== Constants
#endregion
#region ================== Constructor / Disposer
// Constructor
public UniversalMapSetIO(WAD wad, MapManager manager)
: base(wad, manager)
{
}
#endregion
#region ================== Properties
public override int MaxSidedefs { get { return int.MaxValue; } }
#endregion
#region ================== Parsing
#endregion
#region ================== Reading
// This reads a map from the file and returns a MapSet
public override MapSet Read(MapSet map, string mapname)
{
// Return result
return map;
}
#endregion
#region ================== Writing
// This writes a MapSet to the file
public override void Write(MapSet map, string mapname, int position)
{
}
#endregion
}
}

View file

@ -0,0 +1,164 @@
namespace CodeImp.DoomBuilder.Interface
{
partial class FieldsEditorControl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle16 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle13 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle14 = new System.Windows.Forms.DataGridViewCellStyle();
System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle15 = new System.Windows.Forms.DataGridViewCellStyle();
this.fieldslist = new System.Windows.Forms.DataGridView();
this.deleterowstimer = new System.Windows.Forms.Timer(this.components);
this.browsebutton = new System.Windows.Forms.Button();
this.fieldname = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.fieldtype = new System.Windows.Forms.DataGridViewComboBoxColumn();
this.fieldvalue = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.fieldslist)).BeginInit();
this.SuspendLayout();
//
// fieldslist
//
this.fieldslist.AllowUserToResizeColumns = false;
this.fieldslist.AllowUserToResizeRows = false;
this.fieldslist.BackgroundColor = System.Drawing.SystemColors.Window;
this.fieldslist.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.fieldslist.CellBorderStyle = System.Windows.Forms.DataGridViewCellBorderStyle.None;
this.fieldslist.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.Disable;
this.fieldslist.ColumnHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.Single;
this.fieldslist.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.fieldslist.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.fieldname,
this.fieldtype,
this.fieldvalue});
dataGridViewCellStyle16.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleLeft;
dataGridViewCellStyle16.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle16.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
dataGridViewCellStyle16.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle16.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle16.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
dataGridViewCellStyle16.WrapMode = System.Windows.Forms.DataGridViewTriState.False;
this.fieldslist.DefaultCellStyle = dataGridViewCellStyle16;
this.fieldslist.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically;
this.fieldslist.Location = new System.Drawing.Point(0, 0);
this.fieldslist.MultiSelect = false;
this.fieldslist.Name = "fieldslist";
this.fieldslist.RowHeadersVisible = false;
this.fieldslist.RowTemplate.DefaultCellStyle.BackColor = System.Drawing.SystemColors.Window;
this.fieldslist.RowTemplate.DefaultCellStyle.ForeColor = System.Drawing.SystemColors.WindowText;
this.fieldslist.RowTemplate.DefaultCellStyle.SelectionBackColor = System.Drawing.SystemColors.Highlight;
this.fieldslist.RowTemplate.DefaultCellStyle.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
this.fieldslist.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.fieldslist.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
this.fieldslist.Size = new System.Drawing.Size(444, 244);
this.fieldslist.TabIndex = 1;
this.fieldslist.UserDeletingRow += new System.Windows.Forms.DataGridViewRowCancelEventHandler(this.fieldslist_UserDeletingRow);
this.fieldslist.CellBeginEdit += new System.Windows.Forms.DataGridViewCellCancelEventHandler(this.fieldslist_CellBeginEdit);
this.fieldslist.CellClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.fieldslist_CellClick);
this.fieldslist.CellEndEdit += new System.Windows.Forms.DataGridViewCellEventHandler(this.fieldslist_CellEndEdit);
this.fieldslist.SelectionChanged += new System.EventHandler(this.fieldslist_SelectionChanged);
//
// deleterowstimer
//
this.deleterowstimer.Interval = 1;
this.deleterowstimer.Tick += new System.EventHandler(this.deleterowstimer_Tick);
//
// browsebutton
//
this.browsebutton.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.browsebutton.Image = global::CodeImp.DoomBuilder.Properties.Resources.treeview;
this.browsebutton.ImageAlign = System.Drawing.ContentAlignment.BottomCenter;
this.browsebutton.Location = new System.Drawing.Point(370, 43);
this.browsebutton.Name = "browsebutton";
this.browsebutton.Size = new System.Drawing.Size(30, 24);
this.browsebutton.TabIndex = 2;
this.browsebutton.UseVisualStyleBackColor = true;
this.browsebutton.Visible = false;
//
// fieldname
//
dataGridViewCellStyle13.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle13.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle13.NullValue = null;
dataGridViewCellStyle13.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle13.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
this.fieldname.DefaultCellStyle = dataGridViewCellStyle13;
this.fieldname.Frozen = true;
this.fieldname.HeaderText = "Property";
this.fieldname.Name = "fieldname";
this.fieldname.Width = 180;
//
// fieldtype
//
dataGridViewCellStyle14.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle14.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle14.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle14.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
this.fieldtype.DefaultCellStyle = dataGridViewCellStyle14;
this.fieldtype.DisplayStyle = System.Windows.Forms.DataGridViewComboBoxDisplayStyle.Nothing;
this.fieldtype.HeaderText = "Type";
this.fieldtype.Name = "fieldtype";
this.fieldtype.Resizable = System.Windows.Forms.DataGridViewTriState.True;
//
// fieldvalue
//
dataGridViewCellStyle15.BackColor = System.Drawing.SystemColors.Window;
dataGridViewCellStyle15.ForeColor = System.Drawing.SystemColors.WindowText;
dataGridViewCellStyle15.SelectionBackColor = System.Drawing.SystemColors.Highlight;
dataGridViewCellStyle15.SelectionForeColor = System.Drawing.SystemColors.HighlightText;
this.fieldvalue.DefaultCellStyle = dataGridViewCellStyle15;
this.fieldvalue.HeaderText = "Value";
this.fieldvalue.Name = "fieldvalue";
this.fieldvalue.Resizable = System.Windows.Forms.DataGridViewTriState.True;
this.fieldvalue.Width = 120;
//
// FieldsEditorControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.browsebutton);
this.Controls.Add(this.fieldslist);
this.Name = "FieldsEditorControl";
this.Size = new System.Drawing.Size(474, 266);
this.Layout += new System.Windows.Forms.LayoutEventHandler(this.FieldsEditorControl_Layout);
this.Resize += new System.EventHandler(this.FieldsEditorControl_Resize);
((System.ComponentModel.ISupportInitialize)(this.fieldslist)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView fieldslist;
private System.Windows.Forms.Timer deleterowstimer;
private System.Windows.Forms.Button browsebutton;
private System.Windows.Forms.DataGridViewTextBoxColumn fieldname;
private System.Windows.Forms.DataGridViewComboBoxColumn fieldtype;
private System.Windows.Forms.DataGridViewTextBoxColumn fieldvalue;
}
}

View file

@ -0,0 +1,266 @@
#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.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Diagnostics;
using CodeImp.DoomBuilder.Controls;
using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Rendering;
using SlimDX.Direct3D9;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using CodeImp.DoomBuilder.Map;
using System.Globalization;
#endregion
namespace CodeImp.DoomBuilder.Interface
{
public partial class FieldsEditorControl : UserControl
{
// Constants
private const string ADD_FIELD_TEXT = " (click to add custom field)";
// Constructor
public FieldsEditorControl()
{
InitializeComponent();
// Make types list
fieldtype.Items.Clear();
fieldtype.Items.AddRange(Enum.GetNames(typeof(UniversalFieldType)));
}
// This adds a list of fixed fields (in undefined state)
public void ListFixedFields(List<UniversalFieldInfo> list)
{
// Add all fields
foreach(UniversalFieldInfo uf in list)
fieldslist.Rows.Add(new FieldsEditorRow(fieldslist, uf));
// Update new row
SetupNewRowStyle();
}
// This sets up the new row
private void SetupNewRowStyle()
{
// Show text for new row
fieldslist.Rows[fieldslist.NewRowIndex].Cells[0].Value = ADD_FIELD_TEXT;
fieldslist.Rows[fieldslist.NewRowIndex].Cells[0].Style.ForeColor = SystemColors.GrayText;
fieldslist.Rows[fieldslist.NewRowIndex].Cells[0].ReadOnly = false;
// Make sure user can only enter property name in a new row
fieldslist.Rows[fieldslist.NewRowIndex].Cells[1].ReadOnly = true;
fieldslist.Rows[fieldslist.NewRowIndex].Cells[2].ReadOnly = true;
}
// Resized
private void FieldsEditorControl_Resize(object sender, EventArgs e)
{
// Rearrange controls
fieldslist.Size = this.ClientSize;
fieldvalue.Width = fieldslist.ClientRectangle.Width - fieldname.Width - fieldtype.Width - SystemInformation.VerticalScrollBarWidth - 10;
}
// Layout change
private void FieldsEditorControl_Layout(object sender, LayoutEventArgs e)
{
FieldsEditorControl_Resize(sender, EventArgs.Empty);
}
// Cell clicked
private void fieldslist_CellClick(object sender, DataGridViewCellEventArgs e)
{
// Edit immediately
if(fieldslist.SelectedCells.Count > 0) fieldslist.BeginEdit(true);
}
// User deletes a row
private void fieldslist_UserDeletingRow(object sender, DataGridViewRowCancelEventArgs e)
{
// Get the row
FieldsEditorRow row = e.Row as FieldsEditorRow;
// Fixed field?
if(row.IsFixed)
{
// Just undefine the field
row.Undefine();
e.Cancel = true;
}
}
// User selects a cell for editing
private void fieldslist_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
{
// Property cell?
if(e.ColumnIndex == 0)
{
// New row index?
if(e.RowIndex == fieldslist.NewRowIndex)
{
// Remove all text
fieldslist.Rows[e.RowIndex].Cells[0].Style.ForeColor = SystemColors.WindowText;
fieldslist.Rows[e.RowIndex].Cells[0].Value = "";
}
}
}
// Done editing cell contents
private void fieldslist_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
FieldsEditorRow frow = null;
DataGridViewRow row = null;
// Get the row
row = fieldslist.Rows[e.RowIndex];
if(row is FieldsEditorRow) frow = row as FieldsEditorRow;
// Renaming a field?
if(e.ColumnIndex == 0)
{
// Row is a new row?
if(frow == null)
{
// Valid property name given?
if((row.Cells[0].Value != null) && (row.Cells[0].Value.ToString().Trim().Length > 0))
{
// Make new row
frow = new FieldsEditorRow(fieldslist, row.Cells[0].Value.ToString().Trim(), UniversalFieldType.Integer, 0);
frow.Visible = false;
fieldslist.Rows.Insert(e.RowIndex + 1, frow);
}
// Mark the row for delete
row.ReadOnly = true;
deleterowstimer.Start();
}
}
// Changing field value?
if((e.ColumnIndex == 2) && (frow != null))
{
// Defined?
if((row.Cells[2].Value != null) && (!frow.IsFixed || (frow.Info.DefaultStr != row.Cells[2].Value.ToString())))
frow.Define(row.Cells[2].Value);
else if(frow.IsFixed)
frow.Undefine();
}
// Updated
if(frow != null) frow.CellChanged();
// Update button
UpdateBrowseButton();
}
// Time to delete rows
private void deleterowstimer_Tick(object sender, EventArgs e)
{
// Stop timer
deleterowstimer.Stop();
// Delete all rows that must be deleted
for(int i = fieldslist.Rows.Count - 1; i >= 0; i--)
{
if(fieldslist.Rows[i].ReadOnly)
try { fieldslist.Rows.RemoveAt(i); } catch(Exception) { }
else
fieldslist.Rows[i].Visible = true;
}
// Update new row
SetupNewRowStyle();
// Update button
UpdateBrowseButton();
}
// Selection changes
private void fieldslist_SelectionChanged(object sender, EventArgs e)
{
// Update button
UpdateBrowseButton();
}
// This updates the button
private void UpdateBrowseButton()
{
FieldsEditorRow frow = null;
DataGridViewRow row = null;
// Any row selected?
if(fieldslist.SelectedRows.Count > 0)
{
// Get selected row
row = fieldslist.SelectedRows[0];
if(row is FieldsEditorRow) frow = row as FieldsEditorRow;
// Not the new row and FieldsEditorRow available?
if((row.Index < fieldslist.NewRowIndex) && (frow != null))
{
// Browse button available for this type?
if((frow.Type == UniversalFieldType.Flat) ||
(frow.Type == UniversalFieldType.LinedefAction) ||
(frow.Type == UniversalFieldType.SectorEffect) ||
(frow.Type == UniversalFieldType.Texture))
{
Rectangle cellrect = fieldslist.GetCellDisplayRectangle(2, row.Index, false);
// Show button
browsebutton.Location = new Point(cellrect.Right - browsebutton.Width, cellrect.Top);
browsebutton.Height = cellrect.Height;
browsebutton.Visible = true;
// Determine image/text
if((frow.Type == UniversalFieldType.SectorEffect) ||
(frow.Type == UniversalFieldType.LinedefAction))
{
browsebutton.Image = CodeImp.DoomBuilder.Properties.Resources.treeview;
browsebutton.Text = "";
}
else
{
browsebutton.Image = null;
browsebutton.Text = "...";
}
}
else
{
browsebutton.Visible = false;
}
}
else
{
browsebutton.Visible = false;
}
}
else
{
browsebutton.Visible = false;
}
}
}
}

View file

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="fieldname.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="fieldtype.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="fieldvalue.UserAddedColumn" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="deleterowstimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View file

@ -0,0 +1,176 @@
#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.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Diagnostics;
using CodeImp.DoomBuilder.Controls;
using CodeImp.DoomBuilder.Data;
using CodeImp.DoomBuilder.Config;
using CodeImp.DoomBuilder.Rendering;
using SlimDX.Direct3D9;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using CodeImp.DoomBuilder.Map;
#endregion
namespace CodeImp.DoomBuilder.Interface
{
internal class FieldsEditorRow : DataGridViewRow
{
#region ================== Constants
#endregion
#region ================== Variables
// This is true when for a fixed field as defined in the game configuration
// This means that the field cannot be deleted (delete will result in a reset)
// and cannot change type.
private bool isfixed;
// Field information (only for fixed fields)
private UniversalFieldInfo fieldinfo;
// This is true when the field is defined. Cannot be false when this field
// is not fixed, because non-fixed fields are deleted from the list when undefined.
private bool isdefined;
// Type
private UniversalFieldType fieldtype;
#endregion
#region ================== Properties
public bool IsFixed { get { return isfixed; } }
public bool IsDefined { get { return isdefined; } }
public UniversalFieldType Type { get { return fieldtype; } }
public UniversalFieldInfo Info { get { return fieldinfo; } }
#endregion
#region ================== Constructor / Disposer
// Constructor for a fixed, undefined field
public FieldsEditorRow(DataGridView view, UniversalFieldInfo fixedfield)
{
// Undefined
this.DefaultCellStyle.ForeColor = SystemColors.GrayText;
isdefined = false;
// Fixed
this.fieldinfo = fixedfield;
isfixed = true;
// Type
this.fieldtype = fixedfield.Type;
// Make all cells
base.CreateCells(view);
// Setup property cell
this.Cells[0].Value = fixedfield.Name;
this.Cells[0].ReadOnly = true;
// Setup type cell
this.Cells[1].Value = fixedfield.Type.ToString();
this.Cells[1].ReadOnly = true;
// Setup value cell
this.Cells[2].Value = fixedfield.DefaultStr;
// We have no destructor
GC.SuppressFinalize(this);
}
// Constructor for a non-fixed, defined field
public FieldsEditorRow(DataGridView view, string name, UniversalFieldType type, object value)
{
// Defined
this.DefaultCellStyle.ForeColor = SystemColors.WindowText;
isdefined = true;
// Non-fixed
isfixed = false;
// Type
this.fieldtype = type;
// Make all cells
base.CreateCells(view);
// Setup property cell
this.Cells[0].Value = name;
this.Cells[0].ReadOnly = true;
// Setup type cell
this.Cells[1].Value = type.ToString();
this.Cells[1].ReadOnly = false;
// Setup value cell
this.Cells[2].Value = value;
// We have no destructor
GC.SuppressFinalize(this);
}
#endregion
#region ================== Methods
// This is called when a cell is edited
public void CellChanged()
{
// Update type from cell
try { fieldtype = (UniversalFieldType)Enum.Parse(typeof(UniversalFieldType), this.Cells[1].Value.ToString(), true); }
catch(Exception e) { this.Cells[1].Value = fieldtype.ToString(); }
}
// This undefines the field
// ONLY VALID FOR FIXED FIELDS
// You should just delete non-fixed fields
public void Undefine()
{
// Must be fixed!
if(!isfixed) throw new InvalidOperationException();
// Now undefined
this.Cells[2].Value = fieldinfo.DefaultStr;
this.DefaultCellStyle.ForeColor = SystemColors.GrayText;
isdefined = false;
}
// This defines the field
public void Define(object value)
{
// Now defined
this.Cells[2].Value = value;
this.DefaultCellStyle.ForeColor = SystemColors.WindowText;
isdefined = true;
}
#endregion
}
}

View file

@ -83,6 +83,8 @@ namespace CodeImp.DoomBuilder.Interface
this.fronthigh = new CodeImp.DoomBuilder.Interface.TextureSelectorControl();
this.frontoffsety = new CodeImp.DoomBuilder.Interface.NumericTextbox();
this.frontoffsetx = new CodeImp.DoomBuilder.Interface.NumericTextbox();
this.tabPage3 = new System.Windows.Forms.TabPage();
this.fieldslist = new CodeImp.DoomBuilder.Interface.FieldsEditorControl();
label2 = new System.Windows.Forms.Label();
taglabel = new System.Windows.Forms.Label();
label3 = new System.Windows.Forms.Label();
@ -105,6 +107,7 @@ namespace CodeImp.DoomBuilder.Interface
this.tabPage2.SuspendLayout();
this.backgroup.SuspendLayout();
this.frontgroup.SuspendLayout();
this.tabPage3.SuspendLayout();
this.SuspendLayout();
//
// label2
@ -484,6 +487,7 @@ namespace CodeImp.DoomBuilder.Interface
| System.Windows.Forms.AnchorStyles.Right)));
this.tabs.Controls.Add(this.tabPage1);
this.tabs.Controls.Add(this.tabPage2);
this.tabs.Controls.Add(this.tabPage3);
this.tabs.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.tabs.Location = new System.Drawing.Point(10, 10);
this.tabs.Margin = new System.Windows.Forms.Padding(1);
@ -516,7 +520,7 @@ namespace CodeImp.DoomBuilder.Interface
this.tabPage2.Location = new System.Drawing.Point(4, 23);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(5);
this.tabPage2.Size = new System.Drawing.Size(533, 374);
this.tabPage2.Size = new System.Drawing.Size(533, 381);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Sidedefs";
this.tabPage2.UseVisualStyleBackColor = true;
@ -699,6 +703,24 @@ namespace CodeImp.DoomBuilder.Interface
this.frontoffsetx.TabIndex = 8;
this.frontoffsetx.Enter += new System.EventHandler(this.SelectAllText);
//
// tabPage3
//
this.tabPage3.Controls.Add(this.fieldslist);
this.tabPage3.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.tabPage3.Location = new System.Drawing.Point(4, 23);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Size = new System.Drawing.Size(533, 381);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "Custom";
this.tabPage3.UseVisualStyleBackColor = true;
//
// fieldslist
//
this.fieldslist.Location = new System.Drawing.Point(12, 12);
this.fieldslist.Name = "fieldslist";
this.fieldslist.Size = new System.Drawing.Size(508, 357);
this.fieldslist.TabIndex = 0;
//
// LinedefEditForm
//
this.AcceptButton = this.apply;
@ -732,6 +754,7 @@ namespace CodeImp.DoomBuilder.Interface
this.backgroup.PerformLayout();
this.frontgroup.ResumeLayout(false);
this.frontgroup.PerformLayout();
this.tabPage3.ResumeLayout(false);
this.ResumeLayout(false);
}
@ -780,5 +803,7 @@ namespace CodeImp.DoomBuilder.Interface
private System.Windows.Forms.Label arg4label;
private System.Windows.Forms.Label arg2label;
private System.Windows.Forms.Label arg3label;
private System.Windows.Forms.TabPage tabPage3;
private FieldsEditorControl fieldslist;
}
}

View file

@ -53,6 +53,9 @@ namespace CodeImp.DoomBuilder.Interface
// Fill activations list
activation.Items.AddRange(General.Map.Config.LinedefActivates.ToArray());
// Fill universal fields list
fieldslist.ListFixedFields(General.Map.Config.LinedefFields);
// Initialize image selectors
fronthigh.Initialize();
frontmid.Initialize();

View file

@ -72,6 +72,9 @@ namespace CodeImp.DoomBuilder.Map
private int tag;
private byte[] args;
// Additional fields
private SortedList<string, object> fields;
// Selections
private bool selected;
@ -99,6 +102,7 @@ namespace CodeImp.DoomBuilder.Map
public int AngleDeg { get { return (int)(angle * Angle2D.PIDEG); } }
public Rectangle Rect { get { return rect; } }
public byte[] Args { get { return args; } }
public SortedList<string, object> Fields { get { return fields; } }
#endregion
@ -187,6 +191,7 @@ namespace CodeImp.DoomBuilder.Map
l.flags = flags;
l.tag = tag;
l.updateneeded = true;
if(fields != null) l.MakeFields(fields);
}
// This attaches a sidedef on the front
@ -275,6 +280,23 @@ namespace CodeImp.DoomBuilder.Map
if(back != null) back.Sector.UpdateNeeded = true;
}
#endregion
#region ================== Fields
// This makes new fields
public void MakeFields()
{
if(fields != null) fields = new SortedList<string, object>();
}
// This makes fields from another list of fields
public void MakeFields(SortedList<string, object> copyfrom)
{
if(fields != null) fields = new SortedList<string, object>();
foreach(KeyValuePair<string, object> f in copyfrom) fields[f.Key] = f.Value;
}
#endregion
#region ================== Methods

View file

@ -69,6 +69,9 @@ namespace CodeImp.DoomBuilder.Map
// Triangulation
private bool updateneeded;
private TriangleList triangles;
// Additional fields
private SortedList<string, object> fields;
// Disposing
private bool isdisposed = false;
@ -95,6 +98,7 @@ namespace CodeImp.DoomBuilder.Map
public bool UpdateNeeded { get { return updateneeded; } set { updateneeded |= value; } }
public Sector Clone { get { return clone; } set { clone = value; } }
public TriangleList Triangles { get { return triangles; } set { triangles = value; } }
public SortedList<string, object> Fields { get { return fields; } }
#endregion
@ -160,6 +164,7 @@ namespace CodeImp.DoomBuilder.Map
s.effect = effect;
s.tag = tag;
s.brightness = brightness;
if(fields != null) s.MakeFields(fields);
}
// This attaches a sidedef and returns the listitem
@ -210,6 +215,23 @@ namespace CodeImp.DoomBuilder.Map
#endregion
#region ================== Fields
// This makes new fields
public void MakeFields()
{
if(fields != null) fields = new SortedList<string, object>();
}
// This makes fields from another list of fields
public void MakeFields(SortedList<string, object> copyfrom)
{
if(fields != null) fields = new SortedList<string, object>();
foreach(KeyValuePair<string, object> f in copyfrom) fields[f.Key] = f.Value;
}
#endregion
#region ================== Changes
// This updates all properties

View file

@ -58,6 +58,9 @@ namespace CodeImp.DoomBuilder.Map
private long longtexnamehigh;
private long longtexnamemid;
private long longtexnamelow;
// Additional fields
private SortedList<string, object> fields;
// Disposing
private bool isdisposed = false;
@ -81,6 +84,7 @@ namespace CodeImp.DoomBuilder.Map
public long LongHighTexture { get { return longtexnamehigh; } }
public long LongMiddleTexture { get { return longtexnamemid; } }
public long LongLowTexture { get { return longtexnamelow; } }
public SortedList<string, object> Fields { get { return fields; } }
#endregion
@ -151,6 +155,7 @@ namespace CodeImp.DoomBuilder.Map
s.longtexnamehigh = longtexnamehigh;
s.longtexnamemid = longtexnamemid;
s.longtexnamelow = longtexnamelow;
if(fields != null) s.MakeFields(fields);
}
// This copies textures to another sidedef
@ -204,6 +209,23 @@ namespace CodeImp.DoomBuilder.Map
}
}
#endregion
#region ================== Fields
// This makes new fields
public void MakeFields()
{
if(fields != null) fields = new SortedList<string, object>();
}
// This makes fields from another list of fields
public void MakeFields(SortedList<string, object> copyfrom)
{
if(fields != null) fields = new SortedList<string, object>();
foreach(KeyValuePair<string, object> f in copyfrom) fields[f.Key] = f.Value;
}
#endregion
#region ================== Methods

View file

@ -68,6 +68,9 @@ namespace CodeImp.DoomBuilder.Map
// Selections
private bool selected;
// Additional fields
private SortedList<string, object> fields;
// Disposing
private bool isdisposed = false;
@ -94,6 +97,7 @@ namespace CodeImp.DoomBuilder.Map
public int ZOffset { get { return zoffset; } }
public int Tag { get { return tag; } set { tag = value; if((tag < 0) || (tag > MapSet.HIGHEST_TAG)) throw new ArgumentOutOfRangeException("Tag", "Invalid tag number"); } }
public Sector Sector { get { return sector; } }
public SortedList<string, object> Fields { get { return fields; } }
#endregion
@ -155,6 +159,7 @@ namespace CodeImp.DoomBuilder.Map
t.color = color;
t.iconoffset = iconoffset;
args.CopyTo(t.args, 0);
if(fields != null) t.MakeFields(fields);
}
// This determines which sector the thing is in and links it
@ -198,6 +203,23 @@ namespace CodeImp.DoomBuilder.Map
}
}
#endregion
#region ================== Fields
// This makes new fields
public void MakeFields()
{
if(fields != null) fields = new SortedList<string, object>();
}
// This makes fields from another list of fields
public void MakeFields(SortedList<string, object> copyfrom)
{
if(fields != null) fields = new SortedList<string, object>();
foreach(KeyValuePair<string, object> f in copyfrom) fields[f.Key] = f.Value;
}
#endregion
#region ================== Changes

View file

@ -59,6 +59,9 @@ namespace CodeImp.DoomBuilder.Map
// Cloning
private Vertex clone;
// Additional fields
private SortedList<string, object> fields;
// Disposing
private bool isdisposed = false;
@ -75,6 +78,7 @@ namespace CodeImp.DoomBuilder.Map
public bool IsDisposed { get { return isdisposed; } }
public bool Selected { get { return selected; } set { selected = value; } }
public Vertex Clone { get { return clone; } set { clone = value; } }
public SortedList<string, object> Fields { get { return fields; } }
#endregion
@ -145,8 +149,35 @@ namespace CodeImp.DoomBuilder.Map
#endregion
#region ================== Fields
// This makes new fields
public void MakeFields()
{
if(fields != null) fields = new SortedList<string, object>();
}
// This makes fields from another list of fields
public void MakeFields(SortedList<string, object> copyfrom)
{
if(fields != null) fields = new SortedList<string, object>();
foreach(KeyValuePair<string, object> f in copyfrom) fields[f.Key] = f.Value;
}
#endregion
#region ================== Methods
// This copies all properties to another thing
public void CopyPropertiesTo(Vertex v)
{
// Copy properties
v.x = x;
v.y = y;
v.pos = pos;
if(fields != null) v.MakeFields(fields);
}
// This returns the distance from given coordinates
public float DistanceToSq(Vector2D p)
{