This commit is contained in:
codeimp 2007-12-01 01:32:56 +00:00
parent 59ce633329
commit 4f8cfec1c1
21 changed files with 1093 additions and 541 deletions

BIN
Resources/Icons/Grid3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

BIN
Resources/Icons/Grid4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 B

View file

@ -45,6 +45,7 @@
-->
<ItemGroup>
<Compile Include="Config\GameConfiguration.cs" />
<Compile Include="Config\ProgramConfiguration.cs" />
<Compile Include="Config\ThingCategory.cs" />
<Compile Include="Config\ThingTypeInfo.cs" />
<Compile Include="Controls\ActionAttribute.cs" />
@ -284,6 +285,7 @@
</ItemGroup>
<ItemGroup>
<Content Include="Resources\Builder.ico" />
<None Include="Resources\Grid4.png" />
<None Include="Resources\Redo.png" />
<None Include="Resources\Undo.png" />
<None Include="Resources\Grid2.png" />

View file

@ -74,7 +74,7 @@ namespace CodeImp.DoomBuilder.Config
this.nodebuilder3d = General.Settings.ReadSetting("configurations." + settingskey + ".nodebuilder3d", "");
this.testprogram = General.Settings.ReadSetting("configurations." + settingskey + ".testprogram", "");
this.testparameters = General.Settings.ReadSetting("configurations." + settingskey + ".testparameters", "");
this.resources = new DataLocationList(General.Settings, "configurations." + settingskey + ".resources");
this.resources = new DataLocationList(General.Settings.Config, "configurations." + settingskey + ".resources");
}
// Constructor
@ -102,7 +102,7 @@ namespace CodeImp.DoomBuilder.Config
General.Settings.WriteSetting("configurations." + settingskey + ".nodebuilder3d", nodebuilder3d);
General.Settings.WriteSetting("configurations." + settingskey + ".testprogram", testprogram);
General.Settings.WriteSetting("configurations." + settingskey + ".testparameters", testparameters);
resources.WriteToConfig(General.Settings, "configurations." + settingskey + ".resources");
resources.WriteToConfig(General.Settings.Config, "configurations." + settingskey + ".resources");
}
// String representation

View file

@ -0,0 +1,175 @@
#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 class ProgramConfiguration
{
#region ================== Constants
#endregion
#region ================== Variables
// Original configuration
private Configuration cfg;
// Cached variables
private bool blackbrowsers;
private float stitchdistance;
#endregion
#region ================== Properties
public Configuration Config { get { return cfg; } }
public bool BlackBrowsers { get { return blackbrowsers; } set { blackbrowsers = value; } }
public float StitchDistance { get { return stitchdistance; } set { stitchdistance = value; } }
#endregion
#region ================== Constructor / Disposer
// Constructor
public ProgramConfiguration()
{
// We have no destructor
GC.SuppressFinalize(this);
}
#endregion
#region ================== Loading / Saving
// This loads the program configuration
public bool Load(string cfgfilepathname, string defaultfilepathname)
{
// First parse it
if(Read(cfgfilepathname, defaultfilepathname))
{
// Read the cache variables
blackbrowsers = cfg.ReadSetting("blackbrowsers", false);
stitchdistance = cfg.ReadSetting("stitchdistance", 2.0f);
// Success
return true;
}
else
{
// Failed
return false;
}
}
// This saves the program configuration
public void Save(string filepathname)
{
// Write the cache variables
cfg.WriteSetting("blackbrowsers", blackbrowsers);
cfg.WriteSetting("stitchdistance", stitchdistance);
// Save settings configuration
General.WriteLogLine("Saving program configuration...");
cfg.SaveConfiguration(filepathname);
}
// This reads the configuration
private bool Read(string cfgfilepathname, string defaultfilepathname)
{
DialogResult result;
// Check if no config for this user exists yet
if(!File.Exists(cfgfilepathname))
{
// Copy new configuration
General.WriteLogLine("Local user program configuration is missing!");
File.Copy(defaultfilepathname, cfgfilepathname);
General.WriteLogLine("New program configuration copied for local user");
}
// Load it
cfg = new Configuration(cfgfilepathname, true);
if(cfg.ErrorResult != 0)
{
// Error in configuration
// Ask user for a new copy
result = General.ShowErrorMessage("Error in program configuration near line " + cfg.ErrorLine + ": " + cfg.ErrorDescription, MessageBoxButtons.YesNoCancel);
if(result == DialogResult.Yes)
{
// Remove old configuration and make a new copy
General.WriteLogLine("User requested a new copy of the program configuration");
File.Delete(cfgfilepathname);
File.Copy(defaultfilepathname, cfgfilepathname);
General.WriteLogLine("New program configuration copied for local user");
// Load it
cfg = new Configuration(cfgfilepathname, true);
if(cfg.ErrorResult != 0)
{
// Error in configuration
General.WriteLogLine("Error in program configuration near line " + cfg.ErrorLine + ": " + cfg.ErrorDescription);
General.ShowErrorMessage("Default program configuration is corrupted. Please re-install Doom Builder.", MessageBoxButtons.OK);
return false;
}
}
else if(result == DialogResult.Cancel)
{
// User requested to cancel startup
General.WriteLogLine("User cancelled startup");
return false;
}
}
// Success
return true;
}
#endregion
#region ================== Methods
// ReadSetting
public string ReadSetting(string setting, string defaultsetting) { return cfg.ReadSetting(setting, defaultsetting); }
public int ReadSetting(string setting, int defaultsetting) { return cfg.ReadSetting(setting, defaultsetting); }
public float ReadSetting(string setting, float defaultsetting) { return cfg.ReadSetting(setting, defaultsetting); }
public short ReadSetting(string setting, short defaultsetting) { return cfg.ReadSetting(setting, defaultsetting); }
public long ReadSetting(string setting, long defaultsetting) { return cfg.ReadSetting(setting, defaultsetting); }
public bool ReadSetting(string setting, bool defaultsetting) { return cfg.ReadSetting(setting, defaultsetting); }
public byte ReadSetting(string setting, byte defaultsetting) { return cfg.ReadSetting(setting, defaultsetting); }
public IDictionary ReadSetting(string setting, IDictionary defaultsetting) { return cfg.ReadSetting(setting, defaultsetting); }
// WriteSetting
public bool WriteSetting(string setting, object settingvalue) { return cfg.WriteSetting(setting, settingvalue); }
public bool WriteSetting(string setting, object settingvalue, string pathseperator) { return cfg.WriteSetting(setting, settingvalue, pathseperator); }
#endregion
}
}

View file

@ -230,11 +230,15 @@ namespace CodeImp.DoomBuilder.Editing
// Go for all vertices
foreach(Vertex v in General.Map.Map.Vertices)
{
// Adjust boundaries by vertices
if(v.Position.x < left) left = v.Position.x;
if(v.Position.x > right) right = v.Position.x;
if(v.Position.y < top) top = v.Position.y;
if(v.Position.y > bottom) bottom = v.Position.y;
// Vertex used?
if(v.Linedefs.Count > 0)
{
// Adjust boundaries by vertices
if(v.Position.x < left) left = v.Position.x;
if(v.Position.x > right) right = v.Position.x;
if(v.Position.y < top) top = v.Position.y;
if(v.Position.y > bottom) bottom = v.Position.y;
}
}
// Calculate width/height

View file

@ -57,10 +57,13 @@ namespace CodeImp.DoomBuilder.Editing
private List<Vector2D> oldpositions;
// List of non-selected items
private List<Vertex> others;
private ICollection<Vertex> unselectedverts;
// List of unstable lines
private ICollection<Linedef> unstablelines;
// Options
private bool snaptogrid; // SHIFT to disable
private bool snaptogrid; // SHIFT to toggle
private bool snaptonearest; // CTRL to enable
#endregion
@ -78,6 +81,8 @@ namespace CodeImp.DoomBuilder.Editing
this.dragitem = dragitem;
this.dragstartmappos = dragstartmappos;
Cursor.Current = Cursors.AppStarting;
// Make old positions list
// We will use this as reference to move the vertices, or to move them back on cancel
oldpositions = new List<Vector2D>(General.Map.Selection.Vertices.Count);
@ -88,9 +93,14 @@ namespace CodeImp.DoomBuilder.Editing
// Make list of non-selected vertices
// This will be used for snapping to nearest items
others = new List<Vertex>(General.Map.Map.Vertices.Count);
foreach(Vertex v in General.Map.Map.Vertices) if(v.Selected == 0) others.Add(v);
unselectedverts = General.Map.Map.InvertedCollection(General.Map.Selection.Vertices);
// Make list of unstable lines only
// These will have their length displayed during the drag
unstablelines = General.Map.Map.LinedefsFromSelectedVertices(false, true);
Cursor.Current = Cursors.Default;
// We have no destructor
GC.SuppressFinalize(this);
}
@ -124,7 +134,7 @@ namespace CodeImp.DoomBuilder.Editing
if(snapnearest)
{
// Find nearest unselected item within selection range
nearest = MapSet.NearestVertexSquareRange(others, mousemappos, VerticesMode.VERTEX_HIGHLIGHT_RANGE / renderer.Scale);
nearest = MapSet.NearestVertexSquareRange(unselectedverts, mousemappos, VerticesMode.VERTEX_HIGHLIGHT_RANGE / renderer.Scale);
if(nearest != null)
{
// Move the dragged item
@ -181,6 +191,9 @@ namespace CodeImp.DoomBuilder.Editing
// Move geometry back to original position
MoveGeometryRelative(new Vector2D(0f, 0f), false, false);
// If only a single vertex was selected, deselect it now
if(General.Map.Selection.Vertices.Count == 1) General.Map.Selection.ClearVertices();
// Update cached values
General.Map.Map.Update();
@ -203,6 +216,11 @@ namespace CodeImp.DoomBuilder.Editing
// Disenagaging
public override void Disengage()
{
ICollection<Linedef> movinglines;
ICollection<Linedef> fixedlines;
int stitches = 0;
int stitchundo;
base.Disengage();
Cursor.Current = Cursors.WaitCursor;
@ -212,16 +230,47 @@ namespace CodeImp.DoomBuilder.Editing
// Move geometry back to original position
MoveGeometryRelative(new Vector2D(0f, 0f), false, false);
// Make undo
// Make undo for the dragging
General.Map.UndoRedo.CreateUndo("drag vertices", UndoGroup.None, 0, false);
// Move selected geometry to final position
MoveGeometryRelative(mousemappos - dragstartmappos, snaptogrid, snaptonearest);
// ===== BEGIN GEOMETRY STITCHING
// TODO: Merge geometry
// Make undo for the stitching
stitchundo = General.Map.UndoRedo.CreateUndo("stitch geometry", UndoGroup.None, 0, false);
// Find lines that moved during the drag
movinglines = General.Map.Map.LinedefsFromSelectedVertices(true, true);
// Find all non-moving lines (inverse of movinglines)
fixedlines = General.Map.Map.InvertedCollection(movinglines);
// Join nearby vertices
stitches += MapSet.JoinVertices(unselectedverts, General.Map.Selection.Vertices, true, General.Settings.StitchDistance);
// Update cached values
General.Map.Map.Update();
// Split moving lines with unselected vertices
stitches += MapSet.SplitLinesByVertices(movinglines, unselectedverts, General.Settings.StitchDistance);
// Split non-moving lines with selected vertices
stitches += MapSet.SplitLinesByVertices(fixedlines, General.Map.Selection.Vertices, General.Settings.StitchDistance);
// TODO: Join overlapping lines and remove looped lines
// No stitching done? then withdraw undo
if(stitches == 0) General.Map.UndoRedo.WithdrawUndo(stitchundo);
// ===== END GEOMETRY STITCHING
// If only a single vertex was selected, deselect it now
if(General.Map.Selection.Vertices.Count == 1) General.Map.Selection.ClearVertices();
// Update cached values
General.Map.Map.Update();
@ -260,7 +309,7 @@ namespace CodeImp.DoomBuilder.Editing
// This updates the dragging
private void Update()
{
snaptogrid = !General.MainWindow.ShiftState;
snaptogrid = General.MainWindow.ShiftState ^ General.MainWindow.SnapToGrid;
snaptonearest = General.MainWindow.CtrlState;
// Move selected geometry
@ -298,7 +347,7 @@ namespace CodeImp.DoomBuilder.Editing
public override void KeyUp(KeyEventArgs e)
{
base.KeyUp(e);
if(snaptogrid != !General.MainWindow.ShiftState) Update();
if(snaptogrid != General.MainWindow.ShiftState ^ General.MainWindow.SnapToGrid) Update();
if(snaptonearest != General.MainWindow.CtrlState) Update();
}
@ -306,7 +355,7 @@ namespace CodeImp.DoomBuilder.Editing
public override void KeyDown(KeyEventArgs e)
{
base.KeyDown(e);
if(snaptogrid != !General.MainWindow.ShiftState) Update();
if(snaptogrid != General.MainWindow.ShiftState ^ General.MainWindow.SnapToGrid) Update();
if(snaptonearest != General.MainWindow.CtrlState) Update();
}

View file

@ -99,7 +99,7 @@ namespace CodeImp.DoomBuilder
// Main objects
private static Assembly thisasm;
private static MainForm mainwindow;
private static Configuration settings;
private static ProgramConfiguration settings;
private static MapManager map;
private static ActionManager actions;
private static ColorCollection colors;
@ -120,7 +120,7 @@ namespace CodeImp.DoomBuilder
public static string ConfigsPath { get { return configspath; } }
public static string CompilersPath { get { return compilerspath; } }
public static MainForm MainWindow { get { return mainwindow; } }
public static Configuration Settings { get { return settings; } }
public static ProgramConfiguration Settings { get { return settings; } }
public static ColorCollection Colors { get { return colors; } }
public static List<ConfigurationInfo> Configs { get { return configs; } }
public static List<NodebuilderInfo> Nodebuilders { get { return nodebuilders; } }
@ -404,7 +404,9 @@ namespace CodeImp.DoomBuilder
// Load configuration
General.WriteLogLine("Loading program configuration...");
if(LoadProgramConfiguration())
settings = new ProgramConfiguration();
if(settings.Load(Path.Combine(settingspath, SETTINGS_FILE),
Path.Combine(apppath, SETTINGS_FILE)))
{
// Create action manager
actions = new ActionManager();
@ -440,7 +442,7 @@ namespace CodeImp.DoomBuilder
// Load color settings
General.WriteLogLine("Loading color settings...");
colors = new ColorCollection(settings);
colors = new ColorCollection(settings.Config);
// Create application clock
General.WriteLogLine("Creating application clock...");
@ -458,57 +460,6 @@ namespace CodeImp.DoomBuilder
}
}
// Program configuration
private static bool LoadProgramConfiguration()
{
DialogResult result;
// Check if no config for this user exists yet
if(!File.Exists(Path.Combine(settingspath, SETTINGS_FILE)))
{
// Copy new configuration
General.WriteLogLine("Local user program configuration is missing!");
File.Copy(Path.Combine(apppath, SETTINGS_FILE), Path.Combine(settingspath, SETTINGS_FILE));
General.WriteLogLine("New program configuration copied for local user");
}
// Load it
settings = new Configuration(Path.Combine(settingspath, SETTINGS_FILE), true);
if(settings.ErrorResult != 0)
{
// Error in configuration
// Ask user for a new copy
result = ShowErrorMessage("Error in program configuration near line " + settings.ErrorLine + ": " + settings.ErrorDescription, MessageBoxButtons.YesNoCancel);
if(result == DialogResult.Yes)
{
// Remove old configuration and make a new copy
General.WriteLogLine("User requested a new copy of the program configuration");
File.Delete(Path.Combine(settingspath, SETTINGS_FILE));
File.Copy(Path.Combine(apppath, SETTINGS_FILE), Path.Combine(settingspath, SETTINGS_FILE));
General.WriteLogLine("New program configuration copied for local user");
// Load it
settings = new Configuration(Path.Combine(settingspath, SETTINGS_FILE), true);
if(settings.ErrorResult != 0)
{
// Error in configuration
General.WriteLogLine("Error in program configuration near line " + settings.ErrorLine + ": " + settings.ErrorDescription);
ShowErrorMessage("Default program configuration is corrupted. Please re-install Doom Builder.", MessageBoxButtons.OK);
return false;
}
}
else if(result == DialogResult.Cancel)
{
// User requested to cancel startup
General.WriteLogLine("User cancelled startup");
return false;
}
}
// Done
return true;
}
#endregion
#region ================== Terminate
@ -533,7 +484,7 @@ namespace CodeImp.DoomBuilder
Direct3D.Terminate();
// Save colors
colors.SaveColors(settings);
colors.SaveColors(settings.Config);
// Save action controls
actions.SaveSettings();
@ -543,7 +494,7 @@ namespace CodeImp.DoomBuilder
// Save settings configuration
General.WriteLogLine("Saving program configuration...");
settings.SaveConfiguration(Path.Combine(settingspath, SETTINGS_FILE));
settings.Save(Path.Combine(settingspath, SETTINGS_FILE));
// Application ends here and now
General.WriteLogLine("Termination done");

View file

@ -891,6 +891,17 @@ namespace CodeImp.DoomBuilder
#region ================== Methods
// This clears the selection
[Action("clearselection")]
public void ClearSelection()
{
// Clear selection
selection.ClearAll();
// Redraw
General.MainWindow.RedrawDisplay();
}
// This sets a new mapset for editing
public void ChangeMapSet(MapSet newmap)
{

View file

@ -80,7 +80,7 @@ namespace CodeImp.DoomBuilder.Interface
public void ApplyColorSettings()
{
// Force black background?
if(General.Settings.ReadSetting("blackbrowsers", false))
if(General.Settings.BlackBrowsers)
{
list.BackColor = Color.Black;
list.ForeColor = Color.White;

File diff suppressed because it is too large Load diff

View file

@ -76,6 +76,7 @@ namespace CodeImp.DoomBuilder.Interface
public bool AltState { get { return alt; } }
public bool MouseInDisplay { get { return mouseinside; } }
public RenderTargetControl Display { get { return display; } }
public bool SnapToGrid { get { return buttonsnaptogrid.Checked; } }
#endregion
@ -876,6 +877,7 @@ namespace CodeImp.DoomBuilder.Interface
itemlinedefsmode.Enabled = (General.Map != null);
itemsectorsmode.Enabled = (General.Map != null);
itemthingsmode.Enabled = (General.Map != null);
itemsnaptogrid.Enabled = (General.Map != null);
itemundo.Enabled = (General.Map != null) && (General.Map.UndoRedo.NextUndo != null);
itemredo.Enabled = (General.Map != null) && (General.Map.UndoRedo.NextRedo != null);
@ -901,6 +903,15 @@ namespace CodeImp.DoomBuilder.Interface
buttonredo.Enabled = itemredo.Enabled;
buttonundo.ToolTipText = itemundo.Text;
buttonredo.ToolTipText = itemredo.Text;
buttonsnaptogrid.Enabled = (General.Map != null);
}
// Action to toggle snap to grid
[Action("togglesnap")]
public void ToggleSnapToGrid()
{
buttonsnaptogrid.Checked = !buttonsnaptogrid.Checked;
itemsnaptogrid.Checked = buttonsnaptogrid.Checked;
}
#endregion

View file

@ -150,6 +150,18 @@
<metadata name="toolStripMenuItem5.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="toolStripSeparator10.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="toolStripMenuItem4.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="toolStripSeparator2.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="toolStripSeparator11.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="menumain.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
@ -162,21 +174,12 @@
<metadata name="toolbar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>121, 17</value>
</metadata>
<metadata name="toolStripSeparator10.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="statusbar.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="statusbar.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>207, 17</value>
</metadata>
<metadata name="toolStripMenuItem4.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="toolStripSeparator2.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
<metadata name="panelinfo.Locked" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>

View file

@ -111,7 +111,7 @@ namespace CodeImp.DoomBuilder.Interface
colorkeywords.Color = General.Colors.Keywords;
colorliterals.Color = General.Colors.Literals;
colorconstants.Color = General.Colors.Constants;
blackbrowsers.Checked = General.Settings.ReadSetting("blackbrowsers", false);
blackbrowsers.Checked = General.Settings.BlackBrowsers;
// Done
allowapplycontrol = true;
@ -312,7 +312,7 @@ namespace CodeImp.DoomBuilder.Interface
General.Colors.Literals = colorliterals.Color;
General.Colors.Constants = colorconstants.Color;
General.Colors.CreateAssistColors();
General.Settings.WriteSetting("blackbrowsers", blackbrowsers.Checked);
General.Settings.BlackBrowsers = blackbrowsers.Checked;
// Close
this.DialogResult = DialogResult.OK;

View file

@ -158,6 +158,26 @@ namespace CodeImp.DoomBuilder.Map
#region ================== Management
// This sets new start vertex
public void SetStartVertex(Vertex v)
{
// Change start
start.DetachLinedef(startvertexlistitem);
start = v;
startvertexlistitem = start.AttachLinedef(this);
this.updateneeded = true;
}
// This sets new end vertex
public void SetEndVertex(Vertex v)
{
// Change end
end.DetachLinedef(endvertexlistitem);
end = v;
endvertexlistitem = end.AttachLinedef(this);
this.updateneeded = true;
}
// This copies all properties to another line
public void CopyPropertiesTo(Linedef l)
{
@ -313,6 +333,36 @@ namespace CodeImp.DoomBuilder.Map
// Calculate and return side information
return (p.y - v1.y) * (v2.x - v1.x) - (p.x - v1.x) * (v2.y - v1.y);
}
// This splits this line by vertex v
// Returns the new line resulting from the split
public Linedef Split(Vertex v)
{
Linedef nl;
Sidedef nsd;
// Copy linedef and change vertices
nl = map.CreateLinedef(v, end);
CopyPropertiesTo(nl);
SetEndVertex(v);
// Copy front sidedef if exists
if(front != null)
{
nsd = map.CreateSidedef(nl, true, front.Sector);
front.CopyPropertiesTo(nsd);
}
// Copy back sidedef if exists
if(back != null)
{
nsd = map.CreateSidedef(nl, false, back.Sector);
back.CopyPropertiesTo(nsd);
}
// Return result
return nl;
}
#endregion

View file

@ -319,6 +319,129 @@ namespace CodeImp.DoomBuilder.Map
#region ================== Static Tools
// This joins nearby vertices from two collections. This does NOT join vertices
// within the same collection, only if they exist in both collections.
// The vertex from the second collection is moved to match the first vertex.
// When keepsecond is true, the vertex in the second collection is kept,
// otherwise the vertex in the first collection is kept.
// Returns the number of joins made
public static int JoinVertices(ICollection<Vertex> set1, ICollection<Vertex> set2, bool keepsecond, float joindist)
{
float joindist2 = joindist * joindist;
int joinsdone = 0;
bool joined;
do
{
// No joins yet
joined = false;
// Go for all vertices in the first set
foreach(Vertex v1 in set1)
{
// Go for all vertices in the second set
foreach(Vertex v2 in set2)
{
// Check if vertices are close enough
if(v1.DistanceToSq(v2.Position) <= joindist2)
{
// Check if not the same vertex
if(v1 != v2)
{
// Move the second vertex to match the first
v2.Move(v1.Position);
// Check which one to keep
if(keepsecond)
{
// Join the first into the second
// Second is kept, first is removed
v1.Join(v2);
set1.Remove(v1);
set2.Remove(v1);
}
else
{
// Join the second into the first
// First is kept, second is removed
v2.Join(v1);
set1.Remove(v2);
set2.Remove(v2);
}
// Count the join
joinsdone++;
joined = true;
break;
}
}
}
// Will have to restart when joined
if(joined) break;
}
}
while(joined);
// Return result
return joinsdone;
}
// This splits the given lines with the given vertices
// Returns the number of splits made
public static int SplitLinesByVertices(ICollection<Linedef> lines, ICollection<Vertex> verts, float splitdist)
{
float splitdist2 = splitdist * splitdist;
int splitsdone = 0;
bool splitted;
Linedef nl;
do
{
// No split yet
splitted = false;
// Go for all the lines
foreach(Linedef l in lines)
{
// Go for all the vertices
foreach(Vertex v in verts)
{
// Check if v is close enough to l for splitting
if(l.DistanceToSq(v.Position, true) <= splitdist2)
{
// Line is not already referencing v?
if((l.Start != v) && (l.End != v))
{
// Split line l with vertex v
nl = l.Split(v);
// Add the new line to the list
lines.Add(nl);
// Both lines must be updated because their new length
// is relevant for next iterations!
l.Update();
nl.Update();
// Count the split
splitsdone++;
splitted = true;
break;
}
}
}
// Will have to restart when splitted
if(splitted) break;
}
}
while(splitted);
// Return result
return splitsdone;
}
// This finds the line closest to the specified position
public static Linedef NearestLinedef(ICollection<Linedef> selection, Vector2D pos)
{
@ -460,6 +583,52 @@ namespace CodeImp.DoomBuilder.Map
#region ================== Tools
// This makes a list of lines related to vertex selection
// A line is unstable when one vertex is selected and the other isn't.
public ICollection<Linedef> LinedefsFromSelectedVertices(bool includestable, bool includeunstable)
{
List<Linedef> list = new List<Linedef>();
// Go for all lines
foreach(Linedef l in linedefs)
{
// Check if this is to be included
if((includestable && ((l.Start.Selected > 0) && (l.End.Selected > 0))) ||
(includeunstable && ((l.Start.Selected > 0) || (l.End.Selected > 0))) )
{
// Add to list
list.Add(l);
}
}
// Return result
return list;
}
// This returns all vertices not in verts collection
public ICollection<Vertex> InvertedCollection(ICollection<Vertex> verts)
{
List<Vertex> list = new List<Vertex>();
// Go for all vertices
foreach(Vertex v in vertices) if(!verts.Contains(v)) list.Add(v);
// Return result
return list;
}
// This returns all linedefs not in lines collection
public ICollection<Linedef> InvertedCollection(ICollection<Linedef> lines)
{
List<Linedef> list = new List<Linedef>();
// Go for all lines
foreach(Linedef l in linedefs) if(!lines.Contains(l)) list.Add(l);
// Return result
return list;
}
// This finds the line closest to the specified position
public Linedef NearestLinedef(Vector2D pos) { return MapSet.NearestLinedef(linedefs, pos); }
@ -475,6 +644,37 @@ namespace CodeImp.DoomBuilder.Map
// This finds the thing closest to the specified position
public Thing NearestThingSquareRange(Vector2D pos, float maxrange) { return MapSet.NearestThingSquareRange(things, pos, maxrange); }
// This finds the closest unselected linedef that is not connected to the given vertex
public Linedef NearestUnselectedUnreferencedLinedef(Vector2D pos, float maxrange, Vertex v, out float distance)
{
Linedef closest = null;
distance = float.MaxValue;
float maxrangesq = maxrange * maxrange;
float d;
// Go for all linedefs in selection
foreach(Linedef l in linedefs)
{
// Calculate distance and check if closer than previous find
d = l.SafeDistanceToSq(pos, true);
if((d <= maxrangesq) && (d < distance))
{
// Check if not selected
// Check if linedef is not connected to v
if((l.Start != v) && (l.End != v))
{
// This one is closer
closest = l;
distance = d;
}
}
}
// Return result
return closest;
}
// This performs sidedefs compression
public void CompressSidedefs()
{

View file

@ -190,6 +190,36 @@ namespace CodeImp.DoomBuilder.Map
this.Move(General.Map.Grid.SnappedToGrid(pos));
}
// This joins another vertex
// Which means this vertex is removed and the other is kept!
public void Join(Vertex other)
{
LinkedListNode<Linedef> previous;
LinkedListNode<Linedef> current;
// Go for all lines
current = linedefs.Last;
while(current != null)
{
// Get previous
previous = current.Previous;
// Move the start to the other vertex
if(current.Value.Start == this)
current.Value.SetStartVertex(other);
// Move the end to the other vertex
if(current.Value.End == this)
current.Value.SetEndVertex(other);
// Go back one
current = previous;
}
// Remove this vertex
this.Dispose();
}
#endregion
}
}

View file

@ -88,6 +88,13 @@ namespace CodeImp.DoomBuilder.Properties {
}
}
internal static System.Drawing.Bitmap Grid4 {
get {
object obj = ResourceManager.GetObject("Grid4", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
internal static System.Drawing.Bitmap Hourglass {
get {
object obj = ResourceManager.GetObject("Hourglass", resourceCulture);

View file

@ -118,6 +118,9 @@
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Redo" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Redo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Zoom" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Zoom.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
@ -142,6 +145,9 @@
<data name="NewMap" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\NewMap2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="File" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\NewMap.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Undo" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Undo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
@ -157,9 +163,6 @@
<data name="Grid2" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Grid2.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="OpenMap" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\OpenMap.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="ThingsMode" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ThingsMode.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
@ -178,10 +181,10 @@
<data name="Hourglass" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Hourglass.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="File" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\NewMap.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<data name="OpenMap" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\OpenMap.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Redo" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Redo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
<data name="Grid4" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Grid4.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View file

@ -229,3 +229,21 @@ redo
allowmouse = false;
allowscroll = false;
}
togglesnap
{
title = "Edit: Snap to Grid";
description = "Toggles snapping to the grid for things and vertices that are being dragged.";
allowkeys = true;
allowmouse = true;
allowscroll = true;
}
clearselection
{
title = "Edit: Clear Selection";
description = "Deselects all selected elements.";
allowkeys = true;
allowmouse = true;
allowscroll = true;
}

BIN
Source/Resources/Grid4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 B