mirror of
https://git.do.srb2.org/STJr/ZoneBuilder.git
synced 2024-11-10 06:41:49 +00:00
Improved associations
This commit is contained in:
parent
f8e048b1c1
commit
e4b8a6ba2b
7 changed files with 795 additions and 337 deletions
46
Source/Core/Windows/PreferencesForm.Designer.cs
generated
46
Source/Core/Windows/PreferencesForm.Designer.cs
generated
|
@ -232,6 +232,9 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
this.pasteoptions = new CodeImp.DoomBuilder.Controls.PasteOptionsControl();
|
this.pasteoptions = new CodeImp.DoomBuilder.Controls.PasteOptionsControl();
|
||||||
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
|
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
|
||||||
this.browseScreenshotsFolderDialog = new System.Windows.Forms.FolderBrowserDialog();
|
this.browseScreenshotsFolderDialog = new System.Windows.Forms.FolderBrowserDialog();
|
||||||
|
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||||
|
this.eventlinelabelvisibility = new System.Windows.Forms.ComboBox();
|
||||||
|
this.eventlinelabelstyle = new System.Windows.Forms.ComboBox();
|
||||||
label7 = new System.Windows.Forms.Label();
|
label7 = new System.Windows.Forms.Label();
|
||||||
label5 = new System.Windows.Forms.Label();
|
label5 = new System.Windows.Forms.Label();
|
||||||
groupBox1 = new System.Windows.Forms.GroupBox();
|
groupBox1 = new System.Windows.Forms.GroupBox();
|
||||||
|
@ -257,6 +260,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
this.groupBox5.SuspendLayout();
|
this.groupBox5.SuspendLayout();
|
||||||
this.groupBox4.SuspendLayout();
|
this.groupBox4.SuspendLayout();
|
||||||
this.groupBox2.SuspendLayout();
|
this.groupBox2.SuspendLayout();
|
||||||
|
this.groupBox1.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.vertexScale3D)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.vertexScale3D)).BeginInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.viewdistance)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.viewdistance)).BeginInit();
|
||||||
((System.ComponentModel.ISupportInitialize)(this.movespeed)).BeginInit();
|
((System.ComponentModel.ISupportInitialize)(this.movespeed)).BeginInit();
|
||||||
|
@ -2651,6 +2655,44 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
// browseScreenshotsFolderDialog
|
// browseScreenshotsFolderDialog
|
||||||
//
|
//
|
||||||
this.browseScreenshotsFolderDialog.Description = "Select a Folder to Save Screenshots Into";
|
this.browseScreenshotsFolderDialog.Description = "Select a Folder to Save Screenshots Into";
|
||||||
|
//
|
||||||
|
// groupBox1
|
||||||
|
//
|
||||||
|
this.groupBox1.Controls.Add(this.eventlinelabelstyle);
|
||||||
|
this.groupBox1.Controls.Add(this.eventlinelabelvisibility);
|
||||||
|
this.groupBox1.Location = new System.Drawing.Point(6, 445);
|
||||||
|
this.groupBox1.Name = "groupBox5";
|
||||||
|
this.groupBox1.Size = new System.Drawing.Size(272, 54);
|
||||||
|
this.groupBox1.TabIndex = 4;
|
||||||
|
this.groupBox1.TabStop = false;
|
||||||
|
this.groupBox1.Text = "Event line labels";
|
||||||
|
//
|
||||||
|
// eventlinelabelvisibility
|
||||||
|
//
|
||||||
|
this.eventlinelabelvisibility.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
this.eventlinelabelvisibility.FormattingEnabled = true;
|
||||||
|
this.eventlinelabelvisibility.Items.AddRange(new object[] {
|
||||||
|
"Never show",
|
||||||
|
"Forward only",
|
||||||
|
"Reverse only",
|
||||||
|
"Forward + Reverse"});
|
||||||
|
this.eventlinelabelvisibility.Location = new System.Drawing.Point(6, 19);
|
||||||
|
this.eventlinelabelvisibility.Name = "eventlinelabelvisibility";
|
||||||
|
this.eventlinelabelvisibility.Size = new System.Drawing.Size(121, 21);
|
||||||
|
this.eventlinelabelvisibility.TabIndex = 0;
|
||||||
|
//
|
||||||
|
// eventlinelabelstyle
|
||||||
|
//
|
||||||
|
this.eventlinelabelstyle.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||||
|
this.eventlinelabelstyle.FormattingEnabled = true;
|
||||||
|
this.eventlinelabelstyle.Items.AddRange(new object[] {
|
||||||
|
"Action only",
|
||||||
|
"Action + short arguments",
|
||||||
|
"Action + full arguments"});
|
||||||
|
this.eventlinelabelstyle.Location = new System.Drawing.Point(133, 19);
|
||||||
|
this.eventlinelabelstyle.Name = "eventlinelabelstyle";
|
||||||
|
this.eventlinelabelstyle.Size = new System.Drawing.Size(133, 21);
|
||||||
|
this.eventlinelabelstyle.TabIndex = 1;
|
||||||
//
|
//
|
||||||
// PreferencesForm
|
// PreferencesForm
|
||||||
//
|
//
|
||||||
|
@ -2726,6 +2768,7 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
this.groupBox6.ResumeLayout(false);
|
this.groupBox6.ResumeLayout(false);
|
||||||
this.groupBox6.PerformLayout();
|
this.groupBox6.PerformLayout();
|
||||||
this.tabpasting.ResumeLayout(false);
|
this.tabpasting.ResumeLayout(false);
|
||||||
|
this.groupBox1.ResumeLayout(false);
|
||||||
this.ResumeLayout(false);
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2923,5 +2966,8 @@ namespace CodeImp.DoomBuilder.Windows
|
||||||
private System.Windows.Forms.ComboBox textlabelfontsize;
|
private System.Windows.Forms.ComboBox textlabelfontsize;
|
||||||
private CodeImp.DoomBuilder.Controls.ColorControl colorguidelines;
|
private CodeImp.DoomBuilder.Controls.ColorControl colorguidelines;
|
||||||
private System.Windows.Forms.CheckBox autolaunchontest;
|
private System.Windows.Forms.CheckBox autolaunchontest;
|
||||||
|
private System.Windows.Forms.GroupBox groupBox1;
|
||||||
|
private System.Windows.Forms.ComboBox eventlinelabelvisibility;
|
||||||
|
private System.Windows.Forms.ComboBox eventlinelabelstyle;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -57,8 +57,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
// Highlighted item
|
// Highlighted item
|
||||||
private Linedef highlighted;
|
private Linedef highlighted;
|
||||||
private readonly Association[] association = new Association[Linedef.NUM_ARGS];
|
private readonly Association highlightasso;
|
||||||
private readonly Association highlightasso = new Association();
|
|
||||||
private Vector2D insertpreview = new Vector2D(float.NaN, float.NaN); //mxd
|
private Vector2D insertpreview = new Vector2D(float.NaN, float.NaN); //mxd
|
||||||
|
|
||||||
//mxd. Text labels
|
//mxd. Text labels
|
||||||
|
@ -86,8 +85,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
public LinedefsMode()
|
public LinedefsMode()
|
||||||
{
|
{
|
||||||
//mxd. Associations now requre initializing...
|
//mxd. Associations now requre initializing...
|
||||||
for(int i = 0; i < association.Length; i++) association[i] = new Association();
|
highlightasso = new Association(renderer);
|
||||||
|
|
||||||
textlabelsizecache = new Dictionary<string, float>();
|
textlabelsizecache = new Dictionary<string, float>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,9 +150,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
labels[highlighted].Color = General.Colors.Highlight;
|
labels[highlighted].Color = General.Colors.Highlight;
|
||||||
completeredraw = true;
|
completeredraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Previous association highlights something?
|
// Previous association highlights something?
|
||||||
if(highlighted.Tag != 0) completeredraw = true;
|
if (!highlightasso.IsEmpty) completeredraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set highlight association
|
// Set highlight association
|
||||||
|
@ -168,57 +166,18 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
}
|
}
|
||||||
|
|
||||||
// New association highlights something?
|
// New association highlights something?
|
||||||
if(l.Tag != 0)
|
highlightasso.Set(l);
|
||||||
{
|
|
||||||
highlightasso.Set(new Vector2D((l.Start.Position + l.End.Position) / 2), l.Tags, UniversalType.LinedefTag);
|
// Only need a complete redraw if the association contains elements
|
||||||
completeredraw = true;
|
if (!highlightasso.IsEmpty) completeredraw = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
highlightasso.Set(new Vector2D(), 0, 0);
|
// Only need a complete redraw if the old association wasn't empty
|
||||||
|
if (!highlightasso.IsEmpty) completeredraw = true;
|
||||||
|
highlightasso.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the line tag to highlight sectors (Doom style)
|
|
||||||
if(General.Map.Config.LineTagIndicatesSectors)
|
|
||||||
{
|
|
||||||
if(l != null)
|
|
||||||
association[0].Set(new Vector2D((l.Start.Position + l.End.Position)/2), l.Tags, UniversalType.SectorTag);
|
|
||||||
else
|
|
||||||
association[0].Set(new Vector2D(), 0, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LinedefActionInfo action = null;
|
|
||||||
|
|
||||||
if(l != null)
|
|
||||||
{
|
|
||||||
// Check if we can find the linedefs action
|
|
||||||
if((l.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(l.Action))
|
|
||||||
action = General.Map.Config.LinedefActions[l.Action];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine linedef associations
|
|
||||||
for(int i = 0; i < Linedef.NUM_ARGS; i++)
|
|
||||||
{
|
|
||||||
// Previous association highlights something?
|
|
||||||
if((association[i].Type == UniversalType.SectorTag) ||
|
|
||||||
(association[i].Type == UniversalType.LinedefTag) ||
|
|
||||||
(association[i].Type == UniversalType.ThingTag)) completeredraw = true;
|
|
||||||
|
|
||||||
// Make new association
|
|
||||||
if(action != null)
|
|
||||||
association[i].Set(new Vector2D((l.Start.Position + l.End.Position)/2), l.Args[i], action.Args[i].Type);
|
|
||||||
else
|
|
||||||
association[i].Set(new Vector2D(), 0, 0);
|
|
||||||
|
|
||||||
// New association highlights something?
|
|
||||||
if((association[i].Type == UniversalType.SectorTag) ||
|
|
||||||
(association[i].Type == UniversalType.LinedefTag) ||
|
|
||||||
(association[i].Type == UniversalType.ThingTag)) completeredraw = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're changing associations, then we
|
// If we're changing associations, then we
|
||||||
// need to redraw the entire display
|
// need to redraw the entire display
|
||||||
if(completeredraw)
|
if(completeredraw)
|
||||||
|
@ -702,11 +661,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
if(renderer.StartPlotter(true))
|
if(renderer.StartPlotter(true))
|
||||||
{
|
{
|
||||||
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
|
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
|
||||||
for(int i = 0; i < Linedef.NUM_ARGS; i++) BuilderPlug.PlotAssociations(renderer, association[i], eventlines);
|
|
||||||
|
|
||||||
if((highlighted != null) && !highlighted.IsDisposed)
|
if((highlighted != null) && !highlighted.IsDisposed)
|
||||||
{
|
{
|
||||||
BuilderPlug.PlotReverseAssociations(renderer, highlightasso, eventlines);
|
//BuilderPlug.PlotReverseAssociations(renderer, highlightasso, eventlines);
|
||||||
|
highlightasso.Plot();
|
||||||
renderer.PlotLinedef(highlighted, General.Colors.Highlight);
|
renderer.PlotLinedef(highlighted, General.Colors.Highlight);
|
||||||
}
|
}
|
||||||
renderer.PlotVerticesSet(General.Map.Map.Vertices);
|
renderer.PlotVerticesSet(General.Map.Map.Vertices);
|
||||||
|
@ -727,8 +686,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
{
|
{
|
||||||
if(!selecting) //mxd
|
if(!selecting) //mxd
|
||||||
{
|
{
|
||||||
for(int i = 0; i < Linedef.NUM_ARGS; i++) BuilderPlug.RenderAssociations(renderer, association[i], eventlines);
|
if ((highlighted != null) && !highlighted.IsDisposed) highlightasso.Render(); //mxd
|
||||||
if((highlighted != null) && !highlighted.IsDisposed) BuilderPlug.RenderReverseAssociations(renderer, highlightasso, eventlines); //mxd
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -744,8 +702,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
renderer.RenderRectangleFilled(new RectangleF(insertpreview.x - vsize, insertpreview.y - vsize, vsize * 2.0f, vsize * 2.0f), General.Colors.InfoLine.WithAlpha(alpha), true);
|
renderer.RenderRectangleFilled(new RectangleF(insertpreview.x - vsize, insertpreview.y - vsize, vsize * 2.0f, vsize * 2.0f), General.Colors.InfoLine.WithAlpha(alpha), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.RenderArrows(eventlines); //mxd
|
|
||||||
|
|
||||||
//mxd. Render sector tag labels
|
//mxd. Render sector tag labels
|
||||||
if(BuilderPlug.Me.ViewSelectionEffects)
|
if(BuilderPlug.Me.ViewSelectionEffects)
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,7 +56,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
// Highlighted item
|
// Highlighted item
|
||||||
private Sector highlighted;
|
private Sector highlighted;
|
||||||
private readonly Association highlightasso = new Association();
|
private readonly Association highlightasso;
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
private bool editpressed;
|
private bool editpressed;
|
||||||
|
@ -93,6 +93,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Constructor
|
// Constructor
|
||||||
public SectorsMode()
|
public SectorsMode()
|
||||||
{
|
{
|
||||||
|
highlightasso = new Association(renderer);
|
||||||
|
|
||||||
textlabelsizecache = new Dictionary<string, float>();
|
textlabelsizecache = new Dictionary<string, float>();
|
||||||
|
|
||||||
//mxd
|
//mxd
|
||||||
|
@ -444,12 +446,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Set highlight association
|
// Set highlight association
|
||||||
if(s != null && s.Tag != 0)
|
if(s != null && s.Tag != 0)
|
||||||
{
|
{
|
||||||
Vector2D center = (s.Labels.Count > 0 ? s.Labels[0].position : new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2));
|
highlightasso.Set(s);
|
||||||
highlightasso.Set(center, s.Tags, UniversalType.SectorTag);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
highlightasso.Set(new Vector2D(), 0, 0);
|
highlightasso.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// New association highlights something?
|
// New association highlights something?
|
||||||
|
@ -920,7 +921,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
if((highlighted != null) && !highlighted.IsDisposed)
|
if((highlighted != null) && !highlighted.IsDisposed)
|
||||||
{
|
{
|
||||||
renderer.PlotSector(highlighted, General.Colors.Highlight);
|
renderer.PlotSector(highlighted, General.Colors.Highlight);
|
||||||
BuilderPlug.PlotReverseAssociations(renderer, highlightasso, eventlines);
|
highlightasso.Plot();
|
||||||
}
|
}
|
||||||
renderer.Finish();
|
renderer.Finish();
|
||||||
}
|
}
|
||||||
|
@ -940,9 +941,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Render selection
|
// Render selection
|
||||||
if(renderer.StartOverlay(false))
|
if(renderer.StartOverlay(false))
|
||||||
{
|
{
|
||||||
if(highlighted != null && !highlighted.IsDisposed) BuilderPlug.RenderReverseAssociations(renderer, highlightasso, eventlines); //mxd
|
if (highlighted != null && !highlighted.IsDisposed) highlightasso.Render();
|
||||||
if(selecting) RenderMultiSelection();
|
if (selecting) RenderMultiSelection();
|
||||||
renderer.RenderArrows(eventlines); //mxd
|
|
||||||
renderer.Finish();
|
renderer.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,9 +56,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
|
|
||||||
// Highlighted item
|
// Highlighted item
|
||||||
private Thing highlighted;
|
private Thing highlighted;
|
||||||
private readonly Association[] association = new Association[Thing.NUM_ARGS];
|
private readonly Association highlightasso;
|
||||||
private readonly Association directasso = new Association();
|
|
||||||
private readonly Association highlightasso = new Association();
|
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
private bool editpressed;
|
private bool editpressed;
|
||||||
|
@ -90,8 +88,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
public ThingsMode()
|
public ThingsMode()
|
||||||
{
|
{
|
||||||
//mxd. Associations now requre initializing...
|
//mxd. Associations now requre initializing...
|
||||||
for(int i = 0; i < association.Length; i++) association[i] = new Association();
|
highlightasso = new Association(renderer);
|
||||||
directasso = new Association();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd
|
//mxd
|
||||||
|
@ -241,8 +238,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
|
renderer.PlotLinedefSet(General.Map.Map.Linedefs);
|
||||||
renderer.PlotVerticesSet(General.Map.Map.Vertices);
|
renderer.PlotVerticesSet(General.Map.Map.Vertices);
|
||||||
|
|
||||||
for(int i = 0; i < Thing.NUM_ARGS; i++) BuilderPlug.PlotAssociations(renderer, association[i], eventlines);
|
if (highlighted != null && !highlighted.IsDisposed) highlightasso.Plot();
|
||||||
if((highlighted != null) && !highlighted.IsDisposed) BuilderPlug.PlotReverseAssociations(renderer, highlightasso, eventlines);
|
|
||||||
|
|
||||||
renderer.Finish();
|
renderer.Finish();
|
||||||
}
|
}
|
||||||
|
@ -254,13 +250,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, General.Settings.HiddenThingsAlpha);
|
renderer.RenderThingSet(General.Map.ThingsFilter.HiddenThings, General.Settings.HiddenThingsAlpha);
|
||||||
renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, alpha);
|
renderer.RenderThingSet(General.Map.ThingsFilter.VisibleThings, alpha);
|
||||||
renderer.RenderNiGHTSPath();
|
renderer.RenderNiGHTSPath();
|
||||||
for (int i = 0; i < Thing.NUM_ARGS; i++) BuilderPlug.RenderAssociations(renderer, association[i], eventlines);
|
|
||||||
BuilderPlug.RenderAssociations(renderer, directasso, eventlines);
|
|
||||||
|
|
||||||
if((highlighted != null) && !highlighted.IsDisposed)
|
if((highlighted != null) && !highlighted.IsDisposed)
|
||||||
{
|
{
|
||||||
renderer.RenderThing(highlighted, General.Colors.Highlight, alpha);
|
renderer.RenderThing(highlighted, General.Colors.Highlight, alpha);
|
||||||
BuilderPlug.RenderReverseAssociations(renderer, highlightasso, eventlines); //mxd
|
highlightasso.Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. Event lines
|
//mxd. Event lines
|
||||||
|
@ -363,11 +357,11 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
linktype = ti.ThingLink;
|
linktype = ti.ThingLink;
|
||||||
|
|
||||||
// New association highlights something?
|
// New association highlights something?
|
||||||
if(t.Tag != 0) highlightasso.Set(t.Position, t.Tag, UniversalType.ThingTag, linktype);
|
highlightasso.Set(t);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
highlightasso.Set(new Vector2D(), 0, 0);
|
highlightasso.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(highlighted != null) //mxd
|
if(highlighted != null) //mxd
|
||||||
|
@ -378,46 +372,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
highlighted.Highlighted = false;
|
highlighted.Highlighted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. Determine thing associations
|
|
||||||
bool clearassociations = true; //mxd
|
|
||||||
if(t != null)
|
|
||||||
{
|
|
||||||
t.Highlighted = true; //mxd
|
|
||||||
|
|
||||||
// Check if we can find the linedefs action
|
|
||||||
if((t.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(t.Action))
|
|
||||||
{
|
|
||||||
clearassociations = false;
|
|
||||||
LinedefActionInfo action = General.Map.Config.LinedefActions[t.Action];
|
|
||||||
for(int i = 0; i < Thing.NUM_ARGS; i++)
|
|
||||||
association[i].Set(t.Position, t.Args[i], action.Args[i].Type);
|
|
||||||
|
|
||||||
//Some things, such as Patrol and Interpolation specials, are associated via a shared tag rather than an argument
|
|
||||||
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
|
|
||||||
if (ti != null && ti.ThingLink < 0)
|
|
||||||
directasso.Set(t.Position, t.Tag, (int)UniversalType.ThingTag);
|
|
||||||
}
|
|
||||||
//mxd. Check if we can use thing arguments
|
|
||||||
else if(t.Action == 0)
|
|
||||||
{
|
|
||||||
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
|
|
||||||
if(ti != null)
|
|
||||||
{
|
|
||||||
clearassociations = false;
|
|
||||||
for(int i = 0; i < Thing.NUM_ARGS; i++)
|
|
||||||
association[i].Set(t.Position, t.Args[i], ti.Args[i].Type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mxd. Clear associations?
|
|
||||||
if(clearassociations)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < Thing.NUM_ARGS; i++)
|
|
||||||
association[i].Set(new Vector2D(), 0, 0);
|
|
||||||
directasso.Set(new Vector2D(), 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set new highlight and redraw display
|
// Set new highlight and redraw display
|
||||||
highlighted = t;
|
highlighted = t;
|
||||||
General.Interface.RedrawDisplay();
|
General.Interface.RedrawDisplay();
|
||||||
|
|
|
@ -16,9 +16,16 @@
|
||||||
|
|
||||||
#region ================== Namespaces
|
#region ================== Namespaces
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Linq;
|
||||||
|
using CodeImp.DoomBuilder.Config;
|
||||||
using CodeImp.DoomBuilder.Geometry;
|
using CodeImp.DoomBuilder.Geometry;
|
||||||
|
using CodeImp.DoomBuilder.Map;
|
||||||
|
using CodeImp.DoomBuilder.Rendering;
|
||||||
using CodeImp.DoomBuilder.Types;
|
using CodeImp.DoomBuilder.Types;
|
||||||
|
using CodeImp.DoomBuilder.Windows;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
@ -30,97 +37,748 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
private Vector2D center;
|
private Vector2D center;
|
||||||
private UniversalType type;
|
private UniversalType type;
|
||||||
private int directlinktype;
|
private int directlinktype;
|
||||||
|
private int directlinktype;
|
||||||
|
private Dictionary<string, List<Line3D>> eventlines;
|
||||||
|
private IRenderer2D renderer;
|
||||||
|
private SelectableElement element;
|
||||||
|
private List<PixelColor> distinctcolors;
|
||||||
|
private Font font;
|
||||||
|
private Dictionary<string, Vector2D> textwidths;
|
||||||
|
private Dictionary<string, List<TextLabel>> textlabels;
|
||||||
|
|
||||||
|
// Map elements that are associated
|
||||||
|
private List<Thing> things;
|
||||||
|
private List<Sector> sectors;
|
||||||
|
private List<Linedef> linedefs;
|
||||||
|
|
||||||
public HashSet<int> Tags { get { return tags; } }
|
public HashSet<int> Tags { get { return tags; } }
|
||||||
public Vector2D Center { get { return center; } }
|
public Vector2D Center { get { return center; } }
|
||||||
public UniversalType Type { get { return type; } }
|
public UniversalType Type { get { return type; } }
|
||||||
public int DirectLinkType { get { return directlinktype; } }
|
public int DirectLinkType { get { return directlinktype; } }
|
||||||
|
public List<Thing> Things { get { return things; } }
|
||||||
|
public List<Sector> Sectors { get { return sectors; } }
|
||||||
|
public List<Linedef> Linedefs { get { return linedefs; } }
|
||||||
|
public bool IsEmpty { get { return things.Count == 0 && sectors.Count == 0 && linedefs.Count == 0; } }
|
||||||
|
|
||||||
//mxd. This sets up the association
|
//mxd. This sets up the association
|
||||||
public Association()
|
public Association(IRenderer2D renderer)
|
||||||
{
|
{
|
||||||
this.tags = new HashSet<int> { 0 };
|
this.tags = new HashSet<int> { 0 };
|
||||||
|
this.renderer = renderer;
|
||||||
|
|
||||||
|
things = new List<Thing>();
|
||||||
|
sectors = new List<Sector>();
|
||||||
|
linedefs = new List<Linedef>();
|
||||||
|
eventlines = new Dictionary<string, List<Line3D>>();
|
||||||
|
|
||||||
|
font = new Font(new FontFamily(General.Settings.TextLabelFontName), General.Settings.TextLabelFontSize, (General.Settings.TextLabelFontBold ? FontStyle.Bold : FontStyle.Regular));
|
||||||
|
|
||||||
|
distinctcolors = new List<PixelColor>
|
||||||
|
{
|
||||||
|
General.Colors.InfoLine,
|
||||||
|
PixelColor.FromInt(0x84d5a4).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0xc059cb).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0xd0533d).WithAlpha(255),
|
||||||
|
// PixelColor.FromInt(0x415354).WithAlpha(255), // too dark
|
||||||
|
PixelColor.FromInt(0xcea953).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0x91d44b).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0xcd5b89).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0xa8b6c0).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0x797ecb).WithAlpha(255),
|
||||||
|
// PixelColor.FromInt(0x567539).WithAlpha(255), // too dark
|
||||||
|
// PixelColor.FromInt(0x72422f).WithAlpha(255), // too dark
|
||||||
|
// PixelColor.FromInt(0x5d3762).WithAlpha(255), // too dark
|
||||||
|
PixelColor.FromInt(0xffed6f).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0xccebc5).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0xbc80bd).WithAlpha(255),
|
||||||
|
// PixelColor.FromInt(0xd9d9d9).WithAlpha(255), // too gray
|
||||||
|
PixelColor.FromInt(0xfccde5).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0x80b1d3).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0xfdb462).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0xb3de69).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0xfb8072).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0xbebada).WithAlpha(255), // too blue/gray?
|
||||||
|
PixelColor.FromInt(0xffffb3).WithAlpha(255),
|
||||||
|
PixelColor.FromInt(0x8dd3c7).WithAlpha(255),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// This sets up the association
|
/// <summary>
|
||||||
public Association(Vector2D center, int tag, int type)
|
/// Sets the association to a map element. Only works with an instance of Thing, Sector, or Linedef.
|
||||||
|
/// Also gets the forward and reverse associations
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="element">An instance of Thing, Sector, or Linedef</param>
|
||||||
|
public void Set(SelectableElement element)
|
||||||
{
|
{
|
||||||
this.tags = new HashSet<int> { tag }; //mxd
|
this.element = element;
|
||||||
this.type = (UniversalType)type;
|
things = new List<Thing>();
|
||||||
this.center = center;
|
sectors = new List<Sector>();
|
||||||
|
linedefs = new List<Linedef>();
|
||||||
|
eventlines = new Dictionary<string, List<Line3D>>();
|
||||||
|
|
||||||
|
if (element is Sector)
|
||||||
|
{
|
||||||
|
Sector s = element as Sector;
|
||||||
|
center = (s.Labels.Count > 0 ? s.Labels[0].position : new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2));
|
||||||
|
|
||||||
|
type = UniversalType.SectorTag;
|
||||||
|
tags = new HashSet<int>(s.Tags);
|
||||||
|
}
|
||||||
|
else if(element is Linedef)
|
||||||
|
{
|
||||||
|
Linedef ld = element as Linedef;
|
||||||
|
center = ld.GetCenterPoint();
|
||||||
|
|
||||||
|
type = UniversalType.LinedefTag;
|
||||||
|
tags = new HashSet<int>(ld.Tags);
|
||||||
|
}
|
||||||
|
else if(element is Thing)
|
||||||
|
{
|
||||||
|
Thing t = element as Thing;
|
||||||
|
center = t.Position;
|
||||||
|
|
||||||
|
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
|
||||||
|
directlinktype = ti.ThingLink;
|
||||||
|
|
||||||
|
type = UniversalType.ThingTag;
|
||||||
|
tags = new HashSet<int>(new int[] { t.Tag });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the tag 0, because nothing sensible will come from it
|
||||||
|
tags.Remove(0);
|
||||||
|
|
||||||
|
// Get forward and reverse associations
|
||||||
|
GetAssociations();
|
||||||
|
|
||||||
|
// Cache width of label text and generate the labels
|
||||||
|
textwidths = new Dictionary<string, Vector2D>(eventlines.Count);
|
||||||
|
textlabels = new Dictionary<string, List<TextLabel>>(eventlines.Count);
|
||||||
|
|
||||||
|
foreach(KeyValuePair<string, List<Line3D>> kvp in eventlines)
|
||||||
|
{
|
||||||
|
SizeF size = General.Interface.MeasureString(kvp.Key, font);
|
||||||
|
textwidths[kvp.Key] = new Vector2D(size.Width, size.Height);
|
||||||
|
|
||||||
|
// Create one label for each line. We might not need them all, but better
|
||||||
|
// to have them all at the beginning than to generate them later
|
||||||
|
textlabels[kvp.Key] = new List<TextLabel>(kvp.Value.Count);
|
||||||
|
|
||||||
|
for (int i = 0; i < kvp.Value.Count; i++)
|
||||||
|
{
|
||||||
|
// We don't need to set the position here, since it'll be done on the fly later
|
||||||
|
TextLabel l = new TextLabel();
|
||||||
|
l.AlignX = TextAlignmentX.Center;
|
||||||
|
l.AlignY = TextAlignmentY.Middle;
|
||||||
|
l.TransformCoords = true;
|
||||||
|
l.Text = kvp.Key;
|
||||||
|
|
||||||
|
textlabels[kvp.Key].Add(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
textwidths[kvp.Key] = new Vector2D(textlabels[kvp.Key][0].TextSize.Width, textlabels[kvp.Key][0].TextSize.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetEventLineColors();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This sets up the association
|
/// <summary>
|
||||||
public Association(Vector2D center, int tag, UniversalType type)
|
/// Clears out all lists so that the association appears empty
|
||||||
|
/// </summary>
|
||||||
|
public void Clear()
|
||||||
{
|
{
|
||||||
this.tags = new HashSet<int> { tag }; //mxd
|
tags = new HashSet<int>();
|
||||||
this.type = type;
|
things = new List<Thing>();
|
||||||
this.center = center;
|
sectors = new List<Sector>();
|
||||||
|
linedefs = new List<Linedef>();
|
||||||
|
eventlines = new Dictionary<string, List<Line3D>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. This also sets up the association
|
/// <summary>
|
||||||
public Association(Vector2D center, IEnumerable<int> tags, int type)
|
/// Get the forward and reverse associations between the element and other map elements
|
||||||
|
/// </summary>
|
||||||
|
private void GetAssociations()
|
||||||
{
|
{
|
||||||
this.tags = new HashSet<int>(tags); //mxd
|
Dictionary<int, HashSet<int>> actiontags = new Dictionary<int, HashSet<int>>();
|
||||||
this.type = (UniversalType)type;
|
bool showforwardlabel = BuilderPlug.Me.EventLineLabelVisibility == 1 || BuilderPlug.Me.EventLineLabelVisibility == 3;
|
||||||
this.center = center;
|
bool showreverselabel = BuilderPlug.Me.EventLineLabelVisibility == 2 || BuilderPlug.Me.EventLineLabelVisibility == 3;
|
||||||
|
|
||||||
|
// Special handling for Doom format maps where there the linedef's tag references sectors
|
||||||
|
if (General.Map.Config.LineTagIndicatesSectors)
|
||||||
|
{
|
||||||
|
if (tags.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Forward association from linedef to sector
|
||||||
|
if (element is Linedef)
|
||||||
|
{
|
||||||
|
foreach (Sector s in General.Map.Map.Sectors)
|
||||||
|
{
|
||||||
|
if (tags.Contains(s.Tag))
|
||||||
|
{
|
||||||
|
Vector2D sectorcenter = (s.Labels.Count > 0 ? s.Labels[0].position : new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2));
|
||||||
|
|
||||||
|
sectors.Add(s);
|
||||||
|
|
||||||
|
AddLineToAction(showforwardlabel ? GetActionDescription(element) : string.Empty, center, sectorcenter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(element is Sector)
|
||||||
|
{
|
||||||
|
foreach(Linedef ld in General.Map.Map.Linedefs)
|
||||||
|
{
|
||||||
|
if(tags.Contains(ld.Tag))
|
||||||
|
{
|
||||||
|
linedefs.Add(ld);
|
||||||
|
|
||||||
|
AddLineToAction(showreverselabel ? GetActionDescription(ld) : string.Empty, ld.GetCenterPoint(), center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get tags of map elements the element is referencing. This is used for the forward associations
|
||||||
|
if (element is Linedef || element is Thing)
|
||||||
|
actiontags = GetTagsByType();
|
||||||
|
|
||||||
|
// Store presence of different types once, so that we don't have to do a lookup for each map element
|
||||||
|
bool hassectortags = actiontags.ContainsKey((int)UniversalType.SectorTag);
|
||||||
|
bool haslinedeftags = actiontags.ContainsKey((int)UniversalType.LinedefTag);
|
||||||
|
bool hasthingtag = actiontags.ContainsKey((int)UniversalType.ThingTag);
|
||||||
|
|
||||||
|
// Process all sectors in the map
|
||||||
|
foreach (Sector s in General.Map.Map.Sectors)
|
||||||
|
{
|
||||||
|
bool addforward = false;
|
||||||
|
bool addreverse = false;
|
||||||
|
|
||||||
|
// Check for forward association (from the element to the sector)
|
||||||
|
if (hassectortags && actiontags[(int)UniversalType.SectorTag].Overlaps(s.Tags))
|
||||||
|
addforward = true;
|
||||||
|
|
||||||
|
// Check the reverse association (from the sector to the element)
|
||||||
|
// Nothing here yet
|
||||||
|
|
||||||
|
if (addforward || addreverse)
|
||||||
|
{
|
||||||
|
Vector2D sectorcenter = (s.Labels.Count > 0 ? s.Labels[0].position : new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2));
|
||||||
|
|
||||||
|
sectors.Add(s);
|
||||||
|
|
||||||
|
if (addforward)
|
||||||
|
AddLineToAction(showforwardlabel ? GetActionDescription(element) : string.Empty, center, sectorcenter);
|
||||||
|
|
||||||
|
if (addreverse)
|
||||||
|
AddLineToAction(showreverselabel ? GetActionDescription(element) : string.Empty, sectorcenter, center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process all linedefs in the map
|
||||||
|
foreach(Linedef ld in General.Map.Map.Linedefs)
|
||||||
|
{
|
||||||
|
bool addforward = false;
|
||||||
|
bool addreverse = false;
|
||||||
|
|
||||||
|
// Check the forward association (from the element to the linedef)
|
||||||
|
if (haslinedeftags && actiontags[(int)UniversalType.LinedefTag].Overlaps(ld.Tags))
|
||||||
|
addforward = true;
|
||||||
|
|
||||||
|
// Check the reverse association (from the linedef to the element)
|
||||||
|
if (IsAssociatedToLinedef(ld))
|
||||||
|
addreverse = true;
|
||||||
|
|
||||||
|
if (addforward || addreverse)
|
||||||
|
{
|
||||||
|
linedefs.Add(ld);
|
||||||
|
|
||||||
|
if (addforward)
|
||||||
|
AddLineToAction(showforwardlabel ? GetActionDescription(element) : string.Empty, center, ld.GetCenterPoint());
|
||||||
|
|
||||||
|
if (addreverse)
|
||||||
|
AddLineToAction(showreverselabel ? GetActionDescription(ld) : string.Empty, ld.GetCenterPoint(), center);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Doom format only knows associations between linedefs and sectors, but not thing, so stop here
|
||||||
|
if (General.Map.DOOM)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Process all things in the map
|
||||||
|
foreach(Thing t in General.Map.Map.Things)
|
||||||
|
{
|
||||||
|
bool addforward = false;
|
||||||
|
bool addreverse = false;
|
||||||
|
|
||||||
|
// Check the forward association (from the element to the thing)
|
||||||
|
if (hasthingtag && actiontags[(int)UniversalType.ThingTag].Contains(t.Tag))
|
||||||
|
addforward = true;
|
||||||
|
|
||||||
|
// Check the reverse association (from the thing to the element). Only works for Hexen and UDMF,
|
||||||
|
// as Doom format doesn't have any way to reference other map elements
|
||||||
|
if (IsAssociatedToThing(t))
|
||||||
|
addreverse = true;
|
||||||
|
|
||||||
|
if (addforward || addreverse)
|
||||||
|
{
|
||||||
|
things.Add(t);
|
||||||
|
|
||||||
|
if (addforward)
|
||||||
|
AddLineToAction(showforwardlabel ? GetActionDescription(element) : string.Empty, center, t.Position);
|
||||||
|
|
||||||
|
if (addreverse)
|
||||||
|
AddLineToAction(showreverselabel ? GetActionDescription(t) : string.Empty, t.Position, center);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. This also sets up the association
|
/// <summary>
|
||||||
public Association(Vector2D center, IEnumerable<int> tags, UniversalType type)
|
/// Gets a dictionary of sector tags, linedef tags, and thing tags, grouped by their type, that the map element is referencing
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Dictionary of sector tags, linedef tags, and thing tags that the map element is referencing</returns>
|
||||||
|
private Dictionary<int, HashSet<int>> GetTagsByType()
|
||||||
{
|
{
|
||||||
this.tags = new HashSet<int>(tags); //mxd
|
LinedefActionInfo action = null;
|
||||||
this.type = type;
|
int[] actionargs = new int[5];
|
||||||
this.center = center;
|
Dictionary<int, HashSet<int>> actiontags = new Dictionary<int, HashSet<int>>();
|
||||||
|
|
||||||
|
// Get the action and its arguments from a linedef or a thing, if they have them
|
||||||
|
if (element is Linedef)
|
||||||
|
{
|
||||||
|
Linedef ld = element as Linedef;
|
||||||
|
|
||||||
|
if (ld.Action > 0 && General.Map.Config.LinedefActions.ContainsKey(ld.Action))
|
||||||
|
action = General.Map.Config.LinedefActions[ld.Action];
|
||||||
|
|
||||||
|
actionargs = ld.Args;
|
||||||
|
}
|
||||||
|
else if (element is Thing)
|
||||||
|
{
|
||||||
|
Thing t = element as Thing;
|
||||||
|
|
||||||
|
if (t.Action > 0 && General.Map.Config.LinedefActions.ContainsKey(t.Action))
|
||||||
|
action = General.Map.Config.LinedefActions[t.Action];
|
||||||
|
|
||||||
|
actionargs = t.Args;
|
||||||
|
}
|
||||||
|
else // element is a Sector
|
||||||
|
{
|
||||||
|
return actiontags;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action != null)
|
||||||
|
{
|
||||||
|
// Collect what map element the action arguments are referencing. Ignore the argument if it's 0, so that they
|
||||||
|
// are not associated to everything untagged
|
||||||
|
for (int i = 0; i < Linedef.NUM_ARGS; i++)
|
||||||
|
{
|
||||||
|
if ((action.Args[i].Type == (int)UniversalType.SectorTag ||
|
||||||
|
action.Args[i].Type == (int)UniversalType.LinedefTag ||
|
||||||
|
action.Args[i].Type == (int)UniversalType.ThingTag) &&
|
||||||
|
actionargs[i] > 0)
|
||||||
|
{
|
||||||
|
if (!actiontags.ContainsKey(action.Args[i].Type))
|
||||||
|
actiontags[action.Args[i].Type] = new HashSet<int>();
|
||||||
|
|
||||||
|
actiontags[action.Args[i].Type].Add(actionargs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (element is Thing && directlinktype >= 0 && Math.Abs(directlinktype) != ((Thing)element).Type)
|
||||||
|
{
|
||||||
|
// The direct link shenanigans if the thing doesn't have an action, but still reference something through
|
||||||
|
// the action parameters
|
||||||
|
Thing t = element as Thing;
|
||||||
|
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
|
||||||
|
|
||||||
|
if (ti != null && directlinktype >= 0 && Math.Abs(directlinktype) != t.Type)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Linedef.NUM_ARGS; i++)
|
||||||
|
{
|
||||||
|
if ((ti.Args[i].Type == (int)UniversalType.SectorTag ||
|
||||||
|
ti.Args[i].Type == (int)UniversalType.LinedefTag ||
|
||||||
|
ti.Args[i].Type == (int)UniversalType.ThingTag))
|
||||||
|
{
|
||||||
|
if (!actiontags.ContainsKey(ti.Args[i].Type))
|
||||||
|
actiontags[ti.Args[i].Type] = new HashSet<int>();
|
||||||
|
|
||||||
|
actiontags[ti.Args[i].Type].Add(actionargs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return actiontags;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This sets up the association
|
/// <summary>
|
||||||
public void Set(Vector2D center, int tag, int type)
|
/// Checks if there's an association between the element and a Linedef
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="linedef">Linedef to check the association against</param>
|
||||||
|
/// <returns>true if the Linedef and the element are associated, false if not</returns>
|
||||||
|
private bool IsAssociatedToLinedef(Linedef linedef)
|
||||||
{
|
{
|
||||||
this.Set(center, tag, type, 0);
|
// Doom style reference from linedef to sector?
|
||||||
|
if (General.Map.Config.LineTagIndicatesSectors && element is Sector)
|
||||||
|
{
|
||||||
|
if (linedef.Action > 0 && tags.Overlaps(linedef.Tags))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Known action on this line?
|
||||||
|
if ((linedef.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(linedef.Action))
|
||||||
|
{
|
||||||
|
LinedefActionInfo action = General.Map.Config.LinedefActions[linedef.Action];
|
||||||
|
if (((action.Args[0].Type == (int)type) && (linedef.Args[0] != 0) && (tags.Contains(linedef.Args[0]))) ||
|
||||||
|
((action.Args[1].Type == (int)type) && (linedef.Args[1] != 0) && (tags.Contains(linedef.Args[1]))) ||
|
||||||
|
((action.Args[2].Type == (int)type) && (linedef.Args[2] != 0) && (tags.Contains(linedef.Args[2]))) ||
|
||||||
|
((action.Args[3].Type == (int)type) && (linedef.Args[3] != 0) && (tags.Contains(linedef.Args[3]))) ||
|
||||||
|
((action.Args[4].Type == (int)type) && (linedef.Args[4] != 0) && (tags.Contains(linedef.Args[4]))))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Set(Vector2D center, int tag, int type, int directlinktype)
|
/// <summary>
|
||||||
|
/// Checks if there's an association between the element and a Thing
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="thing">Thing to check the association against</param>
|
||||||
|
/// <returns>true if the Thing and the element are associated, false if not</returns>
|
||||||
|
private bool IsAssociatedToThing(Thing thing)
|
||||||
{
|
{
|
||||||
this.tags = new HashSet<int> { tag }; //mxd
|
// Get the thing type info
|
||||||
this.type = (UniversalType)type;
|
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(thing.Type);
|
||||||
this.center = center;
|
|
||||||
this.directlinktype = directlinktype;
|
// Known action on this thing?
|
||||||
|
if ((thing.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(thing.Action))
|
||||||
|
{
|
||||||
|
//Do not draw the association if this is a child link.
|
||||||
|
// This prevents a reverse link to a thing via an argument, when it should be a direct tag-to-tag link instead.
|
||||||
|
if (ti != null && directlinktype < 0 && directlinktype != -thing.Type)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
LinedefActionInfo action = General.Map.Config.LinedefActions[thing.Action];
|
||||||
|
if (((action.Args[0].Type == (int)type) && (tags.Contains(thing.Args[0]))) ||
|
||||||
|
((action.Args[1].Type == (int)type) && (tags.Contains(thing.Args[1]))) ||
|
||||||
|
((action.Args[2].Type == (int)type) && (tags.Contains(thing.Args[2]))) ||
|
||||||
|
((action.Args[3].Type == (int)type) && (tags.Contains(thing.Args[3]))) ||
|
||||||
|
((action.Args[4].Type == (int)type) && (tags.Contains(thing.Args[4]))))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If there is a link setup on this thing, and it matches the association, then draw a direct link to any matching tag
|
||||||
|
if (ti != null && directlinktype == thing.Type && tags.Contains(thing.Tag))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//mxd. Thing action on this thing?
|
||||||
|
else if (thing.Action == 0)
|
||||||
|
{
|
||||||
|
// Gets the association, unless it is a child link.
|
||||||
|
// This prevents a reverse link to a thing via an argument, when it should be a direct tag-to-tag link instead.
|
||||||
|
if (ti != null && directlinktype >= 0 && Math.Abs(directlinktype) != thing.Type)
|
||||||
|
{
|
||||||
|
if (((ti.Args[0].Type == (int)type) && (tags.Contains(thing.Args[0]))) ||
|
||||||
|
((ti.Args[1].Type == (int)type) && (tags.Contains(thing.Args[1]))) ||
|
||||||
|
((ti.Args[2].Type == (int)type) && (tags.Contains(thing.Args[2]))) ||
|
||||||
|
((ti.Args[3].Type == (int)type) && (tags.Contains(thing.Args[3]))) ||
|
||||||
|
((ti.Args[4].Type == (int)type) && (tags.Contains(thing.Args[4]))))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This sets up the association
|
/// <summary>
|
||||||
public void Set(Vector2D center, int tag, UniversalType type)
|
/// Returns a string that contains the description of the action and its arguments, based on the given Linedef or Thing
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="se">An instance of Thing or Linedef</param>
|
||||||
|
/// <returns>String that contains the description of the action and its arguments for a given Linedef or Thing</returns>
|
||||||
|
private string GetActionDescription(SelectableElement se)
|
||||||
{
|
{
|
||||||
this.Set(center, tag, type, 0);
|
int action = 0;
|
||||||
|
int[] actionargs = new int[5];
|
||||||
|
|
||||||
|
if (se is Thing)
|
||||||
|
{
|
||||||
|
action = ((Thing)se).Action;
|
||||||
|
actionargs = ((Thing)se).Args;
|
||||||
|
}
|
||||||
|
else if(se is Linedef)
|
||||||
|
{
|
||||||
|
action = ((Linedef)se).Action;
|
||||||
|
actionargs = ((Linedef)se).Args;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (action > 0)
|
||||||
|
{
|
||||||
|
LinedefActionInfo lai = General.Map.Config.GetLinedefActionInfo(action);
|
||||||
|
List<string> argdescription = new List<string>();
|
||||||
|
|
||||||
|
string description = lai.Index + ": " + lai.Title;
|
||||||
|
|
||||||
|
// Label style: only action, or if the element can't have any parameters
|
||||||
|
if (BuilderPlug.Me.EventLineLabelStyle == 0 || General.Map.Config.LineTagIndicatesSectors)
|
||||||
|
return description;
|
||||||
|
|
||||||
|
for (int i=0; i < 5; i++)
|
||||||
|
{
|
||||||
|
if(lai.Args[i].Used)
|
||||||
|
{
|
||||||
|
string argstring = "";
|
||||||
|
|
||||||
|
if(BuilderPlug.Me.EventLineLabelStyle == 2) // Label style: full arguments
|
||||||
|
argstring = lai.Args[i].Title + ": ";
|
||||||
|
|
||||||
|
EnumItem ei = lai.Args[i].Enum.GetByEnumIndex(actionargs[i].ToString());
|
||||||
|
|
||||||
|
if (ei != null && BuilderPlug.Me.EventLineLabelStyle == 2) // Label style: full arguments
|
||||||
|
argstring += ei.ToString();
|
||||||
|
else // Argument has no EnumItem or label style: short arguments
|
||||||
|
argstring += actionargs[i].ToString();
|
||||||
|
|
||||||
|
argdescription.Add(argstring);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
description += " (" + string.Join(", ", argdescription) + ")";
|
||||||
|
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Set(Vector2D center, int tag, UniversalType type, int directlinktype)
|
/// <summary>
|
||||||
|
/// Sets a different color for each event
|
||||||
|
/// </summary>
|
||||||
|
private void SetEventLineColors()
|
||||||
{
|
{
|
||||||
this.tags = new HashSet<int> { tag }; //mxd
|
int colorindex = 0;
|
||||||
this.type = type;
|
|
||||||
this.center = center;
|
foreach(KeyValuePair<string, List<TextLabel>> kvp in textlabels)
|
||||||
this.directlinktype = directlinktype;
|
{
|
||||||
|
foreach (Line3D l in eventlines[kvp.Key])
|
||||||
|
l.Color = distinctcolors[colorindex];
|
||||||
|
|
||||||
|
foreach (TextLabel l in kvp.Value)
|
||||||
|
l.Color = distinctcolors[colorindex];
|
||||||
|
|
||||||
|
if(BuilderPlug.Me.EventLineDistinctColors)
|
||||||
|
if (++colorindex >= distinctcolors.Count)
|
||||||
|
colorindex = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. This also sets up the association
|
/// <summary>
|
||||||
public void Set(Vector2D center, IEnumerable<int> tags, int type)
|
/// Adds a line to an action
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="action">Name of the action</param>
|
||||||
|
/// <param name="start">Start of the line</param>
|
||||||
|
/// <param name="end">End of the line</param>
|
||||||
|
private void AddLineToAction(string action, Vector2D start, Vector2D end)
|
||||||
{
|
{
|
||||||
this.Set(center, tags, (UniversalType)type, 0);
|
if (action == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!eventlines.ContainsKey(action))
|
||||||
|
eventlines[action] = new List<Line3D>();
|
||||||
|
|
||||||
|
eventlines[action].Add(new Line3D(start, end, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. This also sets up the association
|
/// <summary>
|
||||||
public void Set(Vector2D center, IEnumerable<int> tags, UniversalType type)
|
/// Generates a label position given a start and end point of a line. Taken (with modifications) from LineLengthLabel.Move()
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="start">Start of the line</param>
|
||||||
|
/// <param name="end">End of the line</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private Vector2D GetLabelPosition(Vector2D start, Vector2D end)
|
||||||
{
|
{
|
||||||
this.Set(center, tags, type, 0);
|
// Check if start/end point is on screen...
|
||||||
|
Vector2D lt = General.Map.Renderer2D.DisplayToMap(new Vector2D(0.0, General.Interface.Display.Size.Height));
|
||||||
|
Vector2D rb = General.Map.Renderer2D.DisplayToMap(new Vector2D(General.Interface.Display.Size.Width, 0.0));
|
||||||
|
RectangleF viewport = new RectangleF((float)lt.x, (float)lt.y, (float)(rb.x - lt.x), (float)(rb.y - lt.y));
|
||||||
|
bool startvisible = viewport.Contains((float)start.x, (float)start.y);
|
||||||
|
bool endvisible = viewport.Contains((float)end.x, (float)end.y);
|
||||||
|
|
||||||
|
// Do this only when one point is visible, an the other isn't
|
||||||
|
if ((!startvisible && endvisible) || (startvisible && !endvisible))
|
||||||
|
{
|
||||||
|
Line2D drawnline = new Line2D(start, end);
|
||||||
|
Line2D[] viewportsides = new[] {
|
||||||
|
new Line2D(lt, rb.x, lt.y), // top
|
||||||
|
new Line2D(lt.x, rb.y, rb.x, rb.y), // bottom
|
||||||
|
new Line2D(lt, lt.x, rb.y), // left
|
||||||
|
new Line2D(rb.x, lt.y, rb.x, rb.y), // right
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (Line2D side in viewportsides)
|
||||||
|
{
|
||||||
|
// Modify the start point so it stays on screen
|
||||||
|
double u;
|
||||||
|
if (!startvisible && side.GetIntersection(drawnline, out u))
|
||||||
|
{
|
||||||
|
start = drawnline.GetCoordinatesAt(u);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify the end point so it stays on screen
|
||||||
|
if (!endvisible && side.GetIntersection(drawnline, out u))
|
||||||
|
{
|
||||||
|
end = drawnline.GetCoordinatesAt(u);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create position
|
||||||
|
Vector2D delta = end - start;
|
||||||
|
return new Vector2D(start.x + delta.x * 0.5, start.y + delta.y * 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
//mxd. This also sets up the association
|
/// <summary>
|
||||||
public void Set(Vector2D center, IEnumerable<int> tags, UniversalType type, int directlinktype)
|
/// Merges label positions based on a merge distance
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="positions">Positions to merge</param>
|
||||||
|
/// <param name="distance">Distance to merge positions at</param>
|
||||||
|
/// <returns>List of new positions</returns>
|
||||||
|
List<Vector2D> MergePositions(List<Vector2D> positions, Vector2D distance)
|
||||||
{
|
{
|
||||||
this.tags = new HashSet<int>(tags); //mxd
|
List<Vector2D> allpositions = positions.OrderBy(o => o.x).ToList();
|
||||||
this.type = type;
|
List<Vector2D> newpositions = new List<Vector2D>(positions.Count);
|
||||||
this.center = center;
|
Vector2D mergedistance = distance / renderer.Scale * 1.5;
|
||||||
this.directlinktype = directlinktype;
|
|
||||||
|
// Keep going while we have positions me might want to merge
|
||||||
|
while (allpositions.Count > 0)
|
||||||
|
{
|
||||||
|
Vector2D curposition = allpositions[0];
|
||||||
|
allpositions.RemoveAt(0);
|
||||||
|
|
||||||
|
bool hasclosepositions = true;
|
||||||
|
|
||||||
|
// Keep merging as long as there are close positions nearby
|
||||||
|
while(hasclosepositions)
|
||||||
|
{
|
||||||
|
// Get all positions that are close to the current position
|
||||||
|
List<Vector2D> closepositions = allpositions.Where(o => Math.Abs(curposition.x - o.x) < mergedistance.x && Math.Abs(curposition.y - o.y) < mergedistance.y).ToList();
|
||||||
|
|
||||||
|
if (closepositions.Count > 0)
|
||||||
|
{
|
||||||
|
Vector2D tl = curposition;
|
||||||
|
Vector2D br = curposition;
|
||||||
|
|
||||||
|
// Get the max dimensions of the positions...
|
||||||
|
foreach (Vector2D v in closepositions)
|
||||||
|
{
|
||||||
|
if (v.x < tl.x) tl.x = v.x;
|
||||||
|
if (v.x > br.x) br.x = v.x;
|
||||||
|
if (v.y > tl.y) tl.y = v.y;
|
||||||
|
if (v.y < br.y) br.y = v.y;
|
||||||
|
|
||||||
|
// Remove the position from the list so that it doesn't get checked again
|
||||||
|
allpositions.Remove(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... and set the current position to the center of that
|
||||||
|
curposition.x = tl.x + (br.x - tl.x) / 2.0;
|
||||||
|
curposition.y = tl.y + (br.y - tl.y) / 2.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The current position is a new final position
|
||||||
|
newpositions.Add(curposition);
|
||||||
|
hasclosepositions = false;
|
||||||
|
allpositions.Reverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newpositions;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Renders associated things and sectors in the indication color.
|
||||||
|
/// Also renders event lines, if that option is enabled
|
||||||
|
/// </summary>
|
||||||
|
public void Render()
|
||||||
|
{
|
||||||
|
bool showlabels = BuilderPlug.Me.EventLineLabelVisibility > 0; // Show labels at all?
|
||||||
|
|
||||||
|
foreach (Thing t in things)
|
||||||
|
renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
|
||||||
|
|
||||||
|
// There must be a better way to do this
|
||||||
|
foreach(Sector s in sectors)
|
||||||
|
{
|
||||||
|
int highlightedColor = General.Colors.Highlight.WithAlpha(128).ToInt();
|
||||||
|
FlatVertex[] verts = new FlatVertex[s.FlatVertices.Length];
|
||||||
|
s.FlatVertices.CopyTo(verts, 0);
|
||||||
|
for (int i = 0; i < verts.Length; i++) verts[i].c = highlightedColor;
|
||||||
|
renderer.RenderGeometry(verts, null, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (General.Settings.GZShowEventLines)
|
||||||
|
{
|
||||||
|
List<Line3D> lines = new List<Line3D>(eventlines.Count);
|
||||||
|
List<ITextLabel> labels = new List<ITextLabel>(eventlines.Count);
|
||||||
|
|
||||||
|
foreach(KeyValuePair<string, List<Line3D>> kvp in eventlines)
|
||||||
|
{
|
||||||
|
bool emptylabel = string.IsNullOrEmpty(kvp.Key); // Can be true if only either forward or reverse labels are shown
|
||||||
|
List<Vector2D> allpositions = new List<Vector2D>(kvp.Value.Count);
|
||||||
|
|
||||||
|
foreach (Line3D line in kvp.Value)
|
||||||
|
{
|
||||||
|
if (showlabels && !emptylabel)
|
||||||
|
allpositions.Add(GetLabelPosition(line.Start, line.End));
|
||||||
|
|
||||||
|
lines.Add(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showlabels && !emptylabel)
|
||||||
|
{
|
||||||
|
List<Vector2D> positions = MergePositions(allpositions, textwidths[kvp.Key]);
|
||||||
|
int labelcounter = 0;
|
||||||
|
|
||||||
|
// Set the position of the pre-generated labels. Only add the labels that are needed
|
||||||
|
foreach (Vector2D pos in positions)
|
||||||
|
{
|
||||||
|
textlabels[kvp.Key][labelcounter].Location = pos;
|
||||||
|
labels.Add(textlabels[kvp.Key][labelcounter]);
|
||||||
|
labelcounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderer.RenderArrows(lines);
|
||||||
|
|
||||||
|
if (showlabels)
|
||||||
|
renderer.RenderText(labels);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Plots associated linedefs and sectors
|
||||||
|
/// </summary>
|
||||||
|
public void Plot()
|
||||||
|
{
|
||||||
|
foreach(Linedef ld in linedefs)
|
||||||
|
renderer.PlotLinedef(ld, General.Colors.Indication);
|
||||||
|
|
||||||
|
foreach (Sector s in sectors)
|
||||||
|
renderer.PlotSector(s, General.Colors.Indication);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This compares an association
|
// This compares an association
|
||||||
|
|
|
@ -135,6 +135,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
private bool lockSectorTextureOffsetsWhileDragging; //mxd
|
private bool lockSectorTextureOffsetsWhileDragging; //mxd
|
||||||
private bool syncthingedit; //mxd
|
private bool syncthingedit; //mxd
|
||||||
private bool alphabasedtexturehighlighting; //mxd
|
private bool alphabasedtexturehighlighting; //mxd
|
||||||
|
private int eventlinelabelvisibility; // 0 = never show, 1 = forward only, 2 = reverse only, 3 = forward + reverse
|
||||||
|
private int eventlinelabelstyle; // 0 = Action only, 1 = Action + short arguments, 2 = action + full arguments
|
||||||
|
private bool eventlinedistinctcolors;
|
||||||
private bool selectchangedafterundoredo;
|
private bool selectchangedafterundoredo;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -192,6 +195,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
public bool LockSectorTextureOffsetsWhileDragging { get { return lockSectorTextureOffsetsWhileDragging; } internal set { lockSectorTextureOffsetsWhileDragging = value; } } //mxd
|
public bool LockSectorTextureOffsetsWhileDragging { get { return lockSectorTextureOffsetsWhileDragging; } internal set { lockSectorTextureOffsetsWhileDragging = value; } } //mxd
|
||||||
public bool SyncronizeThingEdit { get { return syncthingedit; } internal set { syncthingedit = value; } } //mxd
|
public bool SyncronizeThingEdit { get { return syncthingedit; } internal set { syncthingedit = value; } } //mxd
|
||||||
public bool AlphaBasedTextureHighlighting { get { return alphabasedtexturehighlighting; } internal set { alphabasedtexturehighlighting = value; } } //mxd
|
public bool AlphaBasedTextureHighlighting { get { return alphabasedtexturehighlighting; } internal set { alphabasedtexturehighlighting = value; } } //mxd
|
||||||
|
public int EventLineLabelVisibility { get { return eventlinelabelvisibility; } internal set { eventlinelabelvisibility = value; } }
|
||||||
|
public int EventLineLabelStyle { get { return eventlinelabelstyle; } internal set { eventlinelabelstyle = value; } }
|
||||||
|
public bool EventLineDistinctColors { get { return eventlinedistinctcolors; } internal set { eventlinedistinctcolors = value; } }
|
||||||
public bool SelectChangedafterUndoRedo { get { return selectchangedafterundoredo; } internal set { selectchangedafterundoredo = value; } }
|
public bool SelectChangedafterUndoRedo { get { return selectchangedafterundoredo; } internal set { selectchangedafterundoredo = value; } }
|
||||||
|
|
||||||
//mxd. "Make Door" action persistent settings
|
//mxd. "Make Door" action persistent settings
|
||||||
|
@ -317,6 +323,9 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
autoAlignTextureOffsetsOnCreate = General.Settings.ReadPluginSetting("autoaligntextureoffsetsoncreate", false); //mxd
|
autoAlignTextureOffsetsOnCreate = General.Settings.ReadPluginSetting("autoaligntextureoffsetsoncreate", false); //mxd
|
||||||
dontMoveGeometryOutsideMapBoundary = General.Settings.ReadPluginSetting("dontmovegeometryoutsidemapboundary", false); //mxd
|
dontMoveGeometryOutsideMapBoundary = General.Settings.ReadPluginSetting("dontmovegeometryoutsidemapboundary", false); //mxd
|
||||||
syncSelection = General.Settings.ReadPluginSetting("syncselection", false); //mxd
|
syncSelection = General.Settings.ReadPluginSetting("syncselection", false); //mxd
|
||||||
|
eventlinelabelvisibility = General.Settings.ReadPluginSetting("eventlinelabelvisibility", 3);
|
||||||
|
eventlinelabelstyle = General.Settings.ReadPluginSetting("eventlinelabelstyle", 2);
|
||||||
|
eventlinedistinctcolors = General.Settings.ReadPluginSetting("eventlinedistinctcolors", true);
|
||||||
selectchangedafterundoredo = General.Settings.ReadPluginSetting("selectchangedafterundoredo", false);
|
selectchangedafterundoredo = General.Settings.ReadPluginSetting("selectchangedafterundoredo", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,176 +707,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
// Return list
|
// Return list
|
||||||
return found.ToArray();
|
return found.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This renders the associated sectors/linedefs with the indication color
|
|
||||||
public static void PlotAssociations(IRenderer2D renderer, Association asso, List<Line3D> eventlines)
|
|
||||||
{
|
|
||||||
// Tag must be above zero
|
|
||||||
if(General.GetByIndex(asso.Tags, 0) < 1) return;
|
|
||||||
|
|
||||||
// Sectors?
|
|
||||||
switch(asso.Type)
|
|
||||||
{
|
|
||||||
case UniversalType.SectorTag: {
|
|
||||||
foreach(Sector s in General.Map.Map.Sectors)
|
|
||||||
{
|
|
||||||
if(!asso.Tags.Overlaps(s.Tags))continue;
|
|
||||||
renderer.PlotSector(s, General.Colors.Indication);
|
|
||||||
|
|
||||||
if(!General.Settings.GZShowEventLines) continue;
|
|
||||||
Vector2D end = (s.Labels.Count > 0 ? s.Labels[0].position : new Vector2D(s.BBox.X + s.BBox.Width / 2, s.BBox.Y + s.BBox.Height / 2));
|
|
||||||
eventlines.Add(new Line3D(asso.Center, end)); //mxd
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case UniversalType.LinedefTag: {
|
|
||||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
|
||||||
{
|
|
||||||
if(!asso.Tags.Overlaps(l.Tags)) continue;
|
|
||||||
renderer.PlotLinedef(l, General.Colors.Indication);
|
|
||||||
if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(asso.Center, l.GetCenterPoint())); //mxd
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This renders the associated things with the indication color
|
|
||||||
public static void RenderAssociations(IRenderer2D renderer, Association asso, List<Line3D> eventlines)
|
|
||||||
{
|
|
||||||
// Tag must be above zero
|
|
||||||
if(General.GetByIndex(asso.Tags, 0) < 1) return;
|
|
||||||
|
|
||||||
// Things?
|
|
||||||
switch(asso.Type)
|
|
||||||
{
|
|
||||||
case UniversalType.ThingTag:
|
|
||||||
foreach(Thing t in General.Map.Map.Things)
|
|
||||||
{
|
|
||||||
if(!asso.Tags.Contains(t.Tag)) continue;
|
|
||||||
|
|
||||||
//Do not draw the association if the user is hovering over a child link
|
|
||||||
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
|
|
||||||
if (ti != null && ti.ThingLink < 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
|
|
||||||
if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(asso.Center, t.Position)); //mxd
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case UniversalType.SectorTag:
|
|
||||||
foreach(Sector s in General.Map.Map.Sectors)
|
|
||||||
{
|
|
||||||
if(!asso.Tags.Overlaps(s.Tags)) continue;
|
|
||||||
int highlightedColor = General.Colors.Highlight.WithAlpha(128).ToInt();
|
|
||||||
FlatVertex[] verts = new FlatVertex[s.FlatVertices.Length];
|
|
||||||
s.FlatVertices.CopyTo(verts, 0);
|
|
||||||
for(int i = 0; i < verts.Length; i++) verts[i].c = highlightedColor;
|
|
||||||
renderer.RenderGeometry(verts, null, true);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This renders the associated sectors/linedefs with the indication color
|
|
||||||
public static void PlotReverseAssociations(IRenderer2D renderer, Association asso, List<Line3D> eventlines)
|
|
||||||
{
|
|
||||||
// Tag must be above zero
|
|
||||||
if(General.GetByIndex(asso.Tags, 0) < 1) return;
|
|
||||||
|
|
||||||
// Doom style referencing to sectors?
|
|
||||||
if(General.Map.Config.LineTagIndicatesSectors && (asso.Type == UniversalType.SectorTag))
|
|
||||||
{
|
|
||||||
// Linedefs
|
|
||||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
|
||||||
{
|
|
||||||
// Any action on this line?
|
|
||||||
if(l.Action <= 0 || !asso.Tags.Overlaps(l.Tags)) continue;
|
|
||||||
renderer.PlotLinedef(l, General.Colors.Indication);
|
|
||||||
if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(l.GetCenterPoint(), asso.Center)); //mxd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Linedefs
|
|
||||||
foreach(Linedef l in General.Map.Map.Linedefs)
|
|
||||||
{
|
|
||||||
// Known action on this line?
|
|
||||||
if((l.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(l.Action))
|
|
||||||
{
|
|
||||||
LinedefActionInfo action = General.Map.Config.LinedefActions[l.Action];
|
|
||||||
if( ((action.Args[0].Type == (int)asso.Type) && (asso.Tags.Contains(l.Args[0]))) ||
|
|
||||||
((action.Args[1].Type == (int)asso.Type) && (asso.Tags.Contains(l.Args[1]))) ||
|
|
||||||
((action.Args[2].Type == (int)asso.Type) && (asso.Tags.Contains(l.Args[2]))) ||
|
|
||||||
((action.Args[3].Type == (int)asso.Type) && (asso.Tags.Contains(l.Args[3]))) ||
|
|
||||||
((action.Args[4].Type == (int)asso.Type) && (asso.Tags.Contains(l.Args[4]))))
|
|
||||||
{
|
|
||||||
renderer.PlotLinedef(l, General.Colors.Indication);
|
|
||||||
if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(l.GetCenterPoint(), asso.Center)); //mxd
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This renders the associated things with the indication color
|
|
||||||
public static void RenderReverseAssociations(IRenderer2D renderer, Association asso, List<Line3D> eventlines)
|
|
||||||
{
|
|
||||||
// Tag must be above zero
|
|
||||||
if(General.GetByIndex(asso.Tags, 0) < 1) return;
|
|
||||||
|
|
||||||
// Things
|
|
||||||
foreach(Thing t in General.Map.Map.Things)
|
|
||||||
{
|
|
||||||
// Get the thing type info
|
|
||||||
ThingTypeInfo ti = General.Map.Data.GetThingInfoEx(t.Type);
|
|
||||||
|
|
||||||
// Known action on this thing?
|
|
||||||
if((t.Action > 0) && General.Map.Config.LinedefActions.ContainsKey(t.Action))
|
|
||||||
{
|
|
||||||
//Do not draw the association if this is a child link.
|
|
||||||
// This prevents a reverse link to a thing via an argument, when it should be a direct tag-to-tag link instead.
|
|
||||||
if(ti != null && asso.DirectLinkType < 0 && asso.DirectLinkType != -t.Type)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
LinedefActionInfo action = General.Map.Config.LinedefActions[t.Action];
|
|
||||||
if( ((action.Args[0].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[0]))) ||
|
|
||||||
((action.Args[1].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[1]))) ||
|
|
||||||
((action.Args[2].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[2]))) ||
|
|
||||||
((action.Args[3].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[3]))) ||
|
|
||||||
((action.Args[4].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[4]))))
|
|
||||||
{
|
|
||||||
renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
|
|
||||||
if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(t.Position, asso.Center)); //mxd
|
|
||||||
}
|
|
||||||
|
|
||||||
//If there is a link setup on this thing, and it matches the association, then draw a direct link to any matching tag
|
|
||||||
if(ti != null && asso.DirectLinkType == t.Type && asso.Tags.Contains(t.Tag))
|
|
||||||
{
|
|
||||||
renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
|
|
||||||
if (General.Settings.GZShowEventLines) eventlines.Add(new Line3D(t.Position, asso.Center));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//mxd. Thing action on this thing?
|
|
||||||
else if(t.Action == 0)
|
|
||||||
{
|
|
||||||
//Draw the association, unless it is a child link.
|
|
||||||
// This prevents a reverse link to a thing via an argument, when it should be a direct tag-to-tag link instead.
|
|
||||||
if(ti != null && asso.DirectLinkType >= 0 && Math.Abs(asso.DirectLinkType) != t.Type)
|
|
||||||
{
|
|
||||||
if( ((ti.Args[0].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[0]))) ||
|
|
||||||
((ti.Args[1].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[1]))) ||
|
|
||||||
((ti.Args[2].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[2]))) ||
|
|
||||||
((ti.Args[3].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[3]))) ||
|
|
||||||
((ti.Args[4].Type == (int)asso.Type) && (asso.Tags.Contains(t.Args[4]))))
|
|
||||||
{
|
|
||||||
renderer.RenderThing(t, General.Colors.Indication, General.Settings.ActiveThingsAlpha);
|
|
||||||
if(General.Settings.GZShowEventLines) eventlines.Add(new Line3D(t.Position, asso.Center));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
defaultbrightness.Text = General.Settings.DefaultBrightness.ToString(); //mxd
|
defaultbrightness.Text = General.Settings.DefaultBrightness.ToString(); //mxd
|
||||||
defaultceilheight.Text = General.Settings.DefaultCeilingHeight.ToString();//mxd
|
defaultceilheight.Text = General.Settings.DefaultCeilingHeight.ToString();//mxd
|
||||||
defaultfloorheight.Text = General.Settings.DefaultFloorHeight.ToString(); //mxd
|
defaultfloorheight.Text = General.Settings.DefaultFloorHeight.ToString(); //mxd
|
||||||
|
eventlinelabelvisibility.SelectedIndex = General.Settings.ReadPluginSetting("eventlinelabelvisibility", 3);
|
||||||
|
eventlinelabelstyle.SelectedIndex = General.Settings.ReadPluginSetting("eventlinelabelstyle", 2);
|
||||||
selectafterundoredo.Checked = General.Settings.ReadPluginSetting("selectchangedafterundoredo", false);
|
selectafterundoredo.Checked = General.Settings.ReadPluginSetting("selectchangedafterundoredo", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +94,8 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
||||||
General.Settings.WritePluginSetting("autoaligntextureoffsetsoncreate", autoaligntexturesoncreate.Checked);//mxd
|
General.Settings.WritePluginSetting("autoaligntextureoffsetsoncreate", autoaligntexturesoncreate.Checked);//mxd
|
||||||
General.Settings.WritePluginSetting("dontmovegeometryoutsidemapboundary", dontMoveGeometryOutsideBounds.Checked);//mxd
|
General.Settings.WritePluginSetting("dontmovegeometryoutsidemapboundary", dontMoveGeometryOutsideBounds.Checked);//mxd
|
||||||
General.Settings.WritePluginSetting("syncselection", syncSelection.Checked);//mxd
|
General.Settings.WritePluginSetting("syncselection", syncSelection.Checked);//mxd
|
||||||
|
General.Settings.WritePluginSetting("eventlinelabelvisibility", eventlinelabelvisibility.SelectedIndex);
|
||||||
|
General.Settings.WritePluginSetting("eventlinelabelstyle", eventlinelabelstyle.SelectedIndex);
|
||||||
General.Settings.WritePluginSetting("selectchangedafterundoredo", selectafterundoredo.Checked);
|
General.Settings.WritePluginSetting("selectchangedafterundoredo", selectafterundoredo.Checked);
|
||||||
General.Settings.SwitchViewModes = switchviewmodes.Checked; //mxd
|
General.Settings.SwitchViewModes = switchviewmodes.Checked; //mxd
|
||||||
General.Settings.SplitLineBehavior = (SplitLineBehavior)splitbehavior.SelectedIndex;//mxd
|
General.Settings.SplitLineBehavior = (SplitLineBehavior)splitbehavior.SelectedIndex;//mxd
|
||||||
|
|
Loading…
Reference in a new issue