Added: Tag Explorer now has polyobjects display mode.

Changed, Tag Explorer: several wildcards can now be used at once. For example, entering "#12 $9" will show only map elements with tag 12 and action 9.
Changed, Tag Explorer: you can now filter list by polyobject number by entering "^NN" in the Filter field.
Changed, cosmetic: reduced map resizing caused by UI resizing during map loading.
This commit is contained in:
MaxED 2015-03-11 11:38:25 +00:00
parent 4bac3eb95a
commit 369e39dbc6
6 changed files with 515 additions and 403 deletions

View file

@ -1344,11 +1344,15 @@ namespace CodeImp.DoomBuilder
// All done
mainwindow.SetupInterface();
mainwindow.RedrawDisplay();
//mainwindow.RedrawDisplay();
mainwindow.UpdateThingsFilters();
mainwindow.UpdateInterface();
mainwindow.HideInfo();
mainwindow.AddHintsDocker(); //mxd
//mxd. Center map in screen. Done here to avoid the view jerking around when updating the interface.
if(Editing.Mode is ClassicMode) (Editing.Mode as ClassicMode).CenterInScreen();
mainwindow.RedrawDisplay();
}
else
{

View file

@ -453,7 +453,7 @@ namespace CodeImp.DoomBuilder
General.Settings.SetDefaultThingFlags(config.DefaultThingFlags);
// Center map in screen
if (General.Editing.Mode is ClassicMode) (General.Editing.Mode as ClassicMode).CenterInScreen();
//if (General.Editing.Mode is ClassicMode) (General.Editing.Mode as ClassicMode).CenterInScreen();
// Success
this.changed = false;

View file

@ -21,7 +21,7 @@
this.cbDisplayMode = new System.Windows.Forms.ComboBox();
this.label1 = new System.Windows.Forms.Label();
this.cbSortMode = new System.Windows.Forms.ComboBox();
this.label2 = new System.Windows.Forms.Label();
this.labelsortmode = new System.Windows.Forms.Label();
this.cbCenterOnSelected = new System.Windows.Forms.CheckBox();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.cbCommentsOnly = new System.Windows.Forms.CheckBox();
@ -48,6 +48,7 @@
this.treeView.Location = new System.Drawing.Point(3, 172);
this.treeView.Name = "treeView";
this.treeView.SelectedImageIndex = 0;
this.treeView.ShowNodeToolTips = true;
this.treeView.Size = new System.Drawing.Size(266, 226);
this.treeView.TabIndex = 0;
this.treeView.NodeMouseDoubleClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeView_NodeMouseDoubleClick);
@ -79,7 +80,7 @@
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 16);
this.label1.Location = new System.Drawing.Point(14, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(37, 13);
this.label1.TabIndex = 3;
@ -96,15 +97,15 @@
this.cbSortMode.Size = new System.Drawing.Size(203, 21);
this.cbSortMode.TabIndex = 4;
//
// label2
// labelsortmode
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(21, 43);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(29, 13);
this.label2.TabIndex = 5;
this.label2.Text = "Sort:";
this.label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.labelsortmode.AutoSize = true;
this.labelsortmode.Location = new System.Drawing.Point(22, 43);
this.labelsortmode.Name = "labelsortmode";
this.labelsortmode.Size = new System.Drawing.Size(29, 13);
this.labelsortmode.TabIndex = 5;
this.labelsortmode.Text = "Sort:";
this.labelsortmode.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// cbCenterOnSelected
//
@ -128,7 +129,7 @@
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Controls.Add(this.cbCenterOnSelected);
this.groupBox1.Controls.Add(this.cbDisplayMode);
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Controls.Add(this.labelsortmode);
this.groupBox1.Controls.Add(this.cbSortMode);
this.groupBox1.Location = new System.Drawing.Point(3, 3);
this.groupBox1.Name = "groupBox1";
@ -160,7 +161,9 @@
// labelSearch
//
this.labelSearch.AutoSize = true;
this.labelSearch.Location = new System.Drawing.Point(18, 71);
this.labelSearch.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Underline, System.Drawing.GraphicsUnit.Point, ((byte)(204)));
this.labelSearch.ForeColor = System.Drawing.SystemColors.HotTrack;
this.labelSearch.Location = new System.Drawing.Point(18, 70);
this.labelSearch.Name = "labelSearch";
this.labelSearch.Size = new System.Drawing.Size(32, 13);
this.labelSearch.TabIndex = 9;
@ -189,6 +192,16 @@
this.tbSearch.TabIndex = 7;
this.tbSearch.TextChanged += new System.EventHandler(this.tbSearch_TextChanged);
//
// toolTip1
//
this.toolTip1.AutomaticDelay = 0;
this.toolTip1.AutoPopDelay = 30000;
this.toolTip1.InitialDelay = 10;
this.toolTip1.ReshowDelay = 100;
this.toolTip1.ToolTipTitle = "Supported wildcards:";
this.toolTip1.UseAnimation = false;
this.toolTip1.UseFading = false;
//
// bExportToFile
//
this.bExportToFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
@ -234,7 +247,7 @@
private System.Windows.Forms.ComboBox cbDisplayMode;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.ComboBox cbSortMode;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label labelsortmode;
private System.Windows.Forms.ImageList imageList1;
private System.Windows.Forms.CheckBox cbCenterOnSelected;
private System.Windows.Forms.GroupBox groupBox1;

View file

@ -24,7 +24,8 @@ namespace CodeImp.DoomBuilder.TagExplorer
{
public const string SORT_BY_INDEX = "By Index";
public const string SORT_BY_TAG = "By Tag";
public const string SORT_BY_ACTION = "By Action special";
public const string SORT_BY_ACTION = "By Action Special";
public const string SORT_BY_POLYOBJ_NUMBER = "By Polyobject Number";
public static readonly object[] SORT_MODES = new object[] { SORT_BY_INDEX, SORT_BY_TAG, SORT_BY_ACTION };
}
@ -38,10 +39,11 @@ namespace CodeImp.DoomBuilder.TagExplorer
public sealed partial class TagExplorer : UserControl
{
private const string DISPLAY_TAGS_AND_ACTIONS = "Tags and Action specials";
private const string DISPLAY_TAGS_AND_ACTIONS = "Tags and Action Specials";
private const string DISPLAY_TAGS = "Tags";
private const string DISPLAY_ACTIONS = "Action specials";
private readonly object[] DISPLAY_MODES = new object[] { DISPLAY_TAGS_AND_ACTIONS, DISPLAY_TAGS, DISPLAY_ACTIONS };
private const string DISPLAY_ACTIONS = "Action Specials";
private const string DISPLAY_POLYOBJECTS = "Polyobjects";
private readonly object[] DISPLAY_MODES = new object[] { DISPLAY_TAGS_AND_ACTIONS, DISPLAY_TAGS, DISPLAY_ACTIONS, DISPLAY_POLYOBJECTS };
private string currentDisplayMode;
private string currentSortMode;
@ -52,6 +54,7 @@ namespace CodeImp.DoomBuilder.TagExplorer
private readonly Color commentColor = Color.DarkMagenta;
private SelectedNode selection;
private readonly string nodetooltip;
private static bool udmf;
internal static bool UDMF { get { return udmf; } }
@ -79,17 +82,22 @@ namespace CodeImp.DoomBuilder.TagExplorer
udmf = (General.Map.Config.FormatInterface == "UniversalMapSetIO");
string searchhint = "Enter '#' + tag number to show only specified tag. Example: #667" + Environment.NewLine
+ "Enter '$' + effect number to show only specified effect. Example: $80" + Environment.NewLine
+ "Enter '^' + polyobject number to filter by polyobject number. Example: ^22" + Environment.NewLine
+ "Several wildcards can be combined.";
if (udmf)
{
cbCommentsOnly.Checked = General.Settings.ReadPluginSetting("commentsonly", false);
toolTip1.SetToolTip(tbSearch, "Enter text to find comment\r\nEnter # + tag number to show only specified tag. Example: #667\r\nEnter $ + effect number to show only specified effect. Example: $80");
toolTip1.SetToolTip(treeView, "Double-click item to edit item's comment\r\nRight-click item to open item's Properties");
toolTip1.SetToolTip(labelSearch, "Enter text to find comment" + Environment.NewLine + searchhint);
nodetooltip = "Double-click item to edit item's comment\r\nRight-click item to open item's Properties";
}
else
{
cbCommentsOnly.Enabled = false;
toolTip1.SetToolTip(tbSearch, "Enter # + tag number to show only specified tag. Example: #667\r\nEnter $ + effect number to show only specified effect. Example: $80");
toolTip1.SetToolTip(treeView, "Right-click item to open item's Properties");
toolTip1.SetToolTip(labelSearch, searchhint);
nodetooltip = "Right-click item to open item's Properties";
}
}
@ -136,11 +144,13 @@ namespace CodeImp.DoomBuilder.TagExplorer
string comment = "";
string serachStr = tbSearch.Text.ToLowerInvariant();
int filteredTag = -1;
int filteredAction = -1;
GetSpecialValues(serachStr, ref filteredTag, ref filteredAction);
List<int> filteredtags = new List<int>();
List<int> filteredactions = new List<int>();
List<int> filteredpolyobjects = new List<int>();
GetSpecialValues(serachStr, ref filteredtags, ref filteredactions, ref filteredpolyobjects);
if (!udmf || filteredTag != -1 || filteredAction != -1) serachStr = "";
if(!udmf || filteredtags.Count > 0 || filteredactions.Count > 0 || filteredpolyobjects.Count > 0)
serachStr = "";
TreeNode selectedNode = null;
@ -160,10 +170,12 @@ namespace CodeImp.DoomBuilder.TagExplorer
{
if((showTags && t.Tag != 0) || (showActions && t.Action > 0))
{
if(filteredTag != -1 && t.Tag != filteredTag) continue;
if(filteredAction != -1 && t.Action != filteredAction) continue;
if(filteredtags.Count > 0 && !filteredtags.Contains(t.Tag)) continue;
if(filteredactions.Count > 0 && !filteredactions.Contains(t.Action)) continue;
NodeInfo info = new NodeInfo(t);
if(filteredpolyobjects.Count > 0 && !filteredpolyobjects.Contains(info.PolyobjectNumber)) continue;
string name = info.GetName(ref comment, currentSortMode);
hasComment = comment.Length > 0;
@ -171,8 +183,7 @@ namespace CodeImp.DoomBuilder.TagExplorer
if(!udmf || serachStr.Length == 0 || (hasComment && comment.ToLowerInvariant().IndexOf(serachStr) != -1))
{
TreeNode node = new TreeNode(name, 1, 1);
node.Tag = info;
TreeNode node = new TreeNode(name, 1, 1) { Tag = info, ToolTipText = nodetooltip };
if(hasComment) node.ForeColor = commentColor;
nodes.Add(node);
@ -180,6 +191,16 @@ namespace CodeImp.DoomBuilder.TagExplorer
selectedNode = node;
}
}
else if(currentDisplayMode == DISPLAY_POLYOBJECTS)
{
NodeInfo info = new NodeInfo(t);
if(info.PolyobjectNumber != int.MinValue && (filteredpolyobjects.Count == 0 || filteredpolyobjects.Contains(info.PolyobjectNumber)))
{
string name = info.GetName(ref comment, SortMode.SORT_BY_POLYOBJ_NUMBER);
TreeNode node = new TreeNode(name, 1, 1) { Tag = info, ToolTipText = nodetooltip };
nodes.Add(node);
}
}
}
//sort nodes
@ -188,103 +209,115 @@ namespace CodeImp.DoomBuilder.TagExplorer
//add "things" category
if(nodes.Count > 0)
{
if(currentSortMode == SortMode.SORT_BY_ACTION) //create action categories
{
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noAction = new TreeNode("No Action", 0, 0);
switch(currentSortMode)
{
case SortMode.SORT_BY_ACTION:
{
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noAction = new TreeNode("No Action", 0, 0);
foreach(TreeNode node in nodes)
{
NodeInfo nodeInfo = node.Tag as NodeInfo;
if(nodeInfo.Action == 0)
foreach(TreeNode node in nodes)
{
noAction.Nodes.Add(node);
continue;
NodeInfo nodeInfo = node.Tag as NodeInfo;
if(nodeInfo.Action == 0)
{
noAction.Nodes.Add(node);
continue;
}
LinedefActionInfo lai = General.Map.Config.GetLinedefActionInfo(nodeInfo.Action);
if(!categories.ContainsKey(lai.Index))
categories.Add(lai.Index, new TreeNode(lai.Index + " - " + lai.Name, 0, 0, new[] { node }));
else
categories[lai.Index].Nodes.Add(node);
}
LinedefActionInfo lai = General.Map.Config.GetLinedefActionInfo(nodeInfo.Action);
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
if(!categories.ContainsKey(lai.Index))
categories.Add(lai.Index, new TreeNode(lai.Index + " - " + lai.Name, 0, 0, new TreeNode[] { node }));
TreeNode category = new TreeNode(CAT_THINGS, 0, 0, catNodes);
if(noAction.Nodes.Count > 0) category.Nodes.Add(noAction);
treeView.Nodes.Add(category);
}
break;
case SortMode.SORT_BY_INDEX:
{
if(currentDisplayMode == DISPLAY_POLYOBJECTS)
{
TreeNode category = new TreeNode(CAT_THINGS, 0, 0);
category.Nodes.AddRange(nodes.ToArray());
treeView.Nodes.Add(category);
}
else
categories[lai.Index].Nodes.Add(node);
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
TreeNode category = new TreeNode(CAT_THINGS, 0, 0, catNodes);
if(noAction.Nodes.Count > 0) category.Nodes.Add(noAction);
treeView.Nodes.Add(category);
}
else if(currentSortMode == SortMode.SORT_BY_INDEX) //create thing categories
{
Dictionary<string, TreeNode> categories = new Dictionary<string, TreeNode>(StringComparer.Ordinal);
foreach(TreeNode node in nodes)
{
NodeInfo nodeInfo = node.Tag as NodeInfo;
ThingTypeInfo tti = General.Map.Data.GetThingInfoEx(General.Map.Map.GetThingByIndex(nodeInfo.Index).Type);
if(tti != null)
{
if(!categories.ContainsKey(tti.Category.Title))
categories.Add(tti.Category.Title, new TreeNode(tti.Category.Title, 0, 0, new[] { node }));
else
categories[tti.Category.Title].Nodes.Add(node);
}
else
{
if(!categories.ContainsKey("UNKNOWN"))
categories.Add("UNKNOWN", new TreeNode("UNKNOWN", 0, 0, new[] { node }));
else
categories["UNKNOWN"].Nodes.Add(node);
Dictionary<string, TreeNode> categories = new Dictionary<string, TreeNode>(StringComparer.Ordinal);
foreach (TreeNode node in nodes)
{
NodeInfo nodeInfo = node.Tag as NodeInfo;
ThingTypeInfo tti = General.Map.Data.GetThingInfoEx(General.Map.Map.GetThingByIndex(nodeInfo.Index).Type);
if(tti != null)
{
if(!categories.ContainsKey(tti.Category.Title)) categories.Add(tti.Category.Title, new TreeNode(tti.Category.Title, 0, 0, new[] {node}));
else categories[tti.Category.Title].Nodes.Add(node);
}
else
{
if(!categories.ContainsKey("UNKNOWN")) categories.Add("UNKNOWN", new TreeNode("UNKNOWN", 0, 0, new[] {node}));
else categories["UNKNOWN"].Nodes.Add(node);
}
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
treeView.Nodes.Add(new TreeNode(CAT_THINGS, 0, 0, catNodes));
}
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
break;
treeView.Nodes.Add(new TreeNode(CAT_THINGS, 0, 0, catNodes));
case SortMode.SORT_BY_TAG:
{
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noTag = new TreeNode("No Tag", 0, 0);
}
else //sort by tag
{
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noTag = new TreeNode("No Tag", 0, 0);
foreach(TreeNode node in nodes)
{
NodeInfo nodeInfo = node.Tag as NodeInfo;
if(nodeInfo.Tag == 0)
foreach(TreeNode node in nodes)
{
noTag.Nodes.Add(node);
continue;
NodeInfo nodeInfo = node.Tag as NodeInfo;
if(nodeInfo.Tag == 0)
{
noTag.Nodes.Add(node);
continue;
}
if(!categories.ContainsKey(nodeInfo.Tag))
{
string title = "Tag " + nodeInfo.Tag;
if(General.Map.Options.TagLabels.ContainsKey(nodeInfo.Tag))
title += ": " + General.Map.Options.TagLabels[nodeInfo.Tag];
categories.Add(nodeInfo.Tag, new TreeNode(title, 0, 0, new[] { node }));
}
else
{
categories[nodeInfo.Tag].Nodes.Add(node);
}
}
if(!categories.ContainsKey(nodeInfo.Tag))
{
string title = "Tag " + nodeInfo.Tag;
if(General.Map.Options.TagLabels.ContainsKey(nodeInfo.Tag))
title += ": " + General.Map.Options.TagLabels[nodeInfo.Tag];
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
categories.Add(nodeInfo.Tag, new TreeNode(title, 0, 0, new TreeNode[] { node }));
}
else
{
categories[nodeInfo.Tag].Nodes.Add(node);
}
TreeNode category = new TreeNode(CAT_THINGS, 0, 0, catNodes);
if(noTag.Nodes.Count > 0) category.Nodes.Add(noTag);
treeView.Nodes.Add(category);
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
TreeNode category = new TreeNode(CAT_THINGS, 0, 0, catNodes);
if(noTag.Nodes.Count > 0) category.Nodes.Add(noTag);
treeView.Nodes.Add(category);
break;
}
}
}
@ -294,14 +327,14 @@ namespace CodeImp.DoomBuilder.TagExplorer
nodes = new List<TreeNode>();
ICollection<Sector> sectors = General.Map.Map.Sectors;
if (!(sectors is MapElementCollection<Sector>)) //don't want to enumerate when array is locked
if (currentDisplayMode != DISPLAY_POLYOBJECTS && !(sectors is MapElementCollection<Sector>)) //don't want to enumerate when array is locked
{
foreach (Sector s in sectors)
{
if ((showTags && s.Tag != 0) || (showActions && s.Effect > 0))
{
if (filteredTag != -1 && s.Tag != filteredTag) continue;
if (filteredAction != -1 && s.Effect != filteredAction) continue;
if(filteredtags.Count > 0 && !filteredtags.Contains(s.Tag)) continue;
if(filteredactions.Count > 0 && !filteredactions.Contains(s.Effect)) continue;
NodeInfo info = new NodeInfo(s);
string name = info.GetName(ref comment, currentSortMode);
@ -311,8 +344,7 @@ namespace CodeImp.DoomBuilder.TagExplorer
if (!udmf || serachStr.Length == 0 || (hasComment && comment.ToLowerInvariant().IndexOf(serachStr) != -1))
{
TreeNode node = new TreeNode(name, 3, 3);
node.Tag = info;
TreeNode node = new TreeNode(name, 3, 3) { Tag = info, ToolTipText = nodetooltip };
if (hasComment) node.ForeColor = commentColor;
nodes.Add(node);
@ -328,75 +360,81 @@ namespace CodeImp.DoomBuilder.TagExplorer
//add category
if (nodes.Count > 0)
{
if (currentSortMode == SortMode.SORT_BY_ACTION)
switch(currentSortMode)
{
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noAction = new TreeNode("No Effect", 2, 2);
foreach (TreeNode node in nodes)
case SortMode.SORT_BY_ACTION:
{
NodeInfo nodeInfo = node.Tag as NodeInfo;
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noAction = new TreeNode("No Effect", 2, 2);
if (nodeInfo.Action == 0)
foreach (TreeNode node in nodes)
{
noAction.Nodes.Add(node);
continue;
NodeInfo nodeInfo = node.Tag as NodeInfo;
if (nodeInfo.Action == 0)
{
noAction.Nodes.Add(node);
continue;
}
SectorEffectInfo sei = General.Map.Config.GetSectorEffectInfo(nodeInfo.Action);
if (!categories.ContainsKey(sei.Index))
categories.Add(sei.Index, new TreeNode(sei.Index + " - " + sei.Title, 2, 2, new[] { node }));
else
categories[sei.Index].Nodes.Add(node);
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
SectorEffectInfo sei = General.Map.Config.GetSectorEffectInfo(nodeInfo.Action);
TreeNode category = new TreeNode(CAT_SECTORS, 2, 2, catNodes);
if (noAction.Nodes.Count > 0) category.Nodes.Add(noAction);
if (!categories.ContainsKey(sei.Index))
categories.Add(sei.Index, new TreeNode(sei.Index + " - " + sei.Title, 2, 2, new TreeNode[] { node }));
else
categories[sei.Index].Nodes.Add(node);
treeView.Nodes.Add(category);
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
break;
TreeNode category = new TreeNode(CAT_SECTORS, 2, 2, catNodes);
if (noAction.Nodes.Count > 0) category.Nodes.Add(noAction);
treeView.Nodes.Add(category);
}
else if (currentSortMode == SortMode.SORT_BY_TAG)
{
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noTag = new TreeNode("No Tag", 2, 2);
foreach (TreeNode node in nodes)
case SortMode.SORT_BY_TAG:
{
NodeInfo nodeInfo = node.Tag as NodeInfo;
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noTag = new TreeNode("No Tag", 2, 2);
if (nodeInfo.Tag == 0)
foreach (TreeNode node in nodes)
{
noTag.Nodes.Add(node);
continue;
NodeInfo nodeInfo = node.Tag as NodeInfo;
if (nodeInfo.Tag == 0)
{
noTag.Nodes.Add(node);
continue;
}
if(!categories.ContainsKey(nodeInfo.Tag))
{
string title = "Tag " + nodeInfo.Tag;
if(General.Map.Options.TagLabels.ContainsKey(nodeInfo.Tag))
title += ": " + General.Map.Options.TagLabels[nodeInfo.Tag];
categories.Add(nodeInfo.Tag, new TreeNode(title, 2, 2, new[] { node }));
}
else
{
categories[nodeInfo.Tag].Nodes.Add(node);
}
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
if(!categories.ContainsKey(nodeInfo.Tag))
{
string title = "Tag " + nodeInfo.Tag;
if(General.Map.Options.TagLabels.ContainsKey(nodeInfo.Tag))
title += ": " + General.Map.Options.TagLabels[nodeInfo.Tag];
TreeNode category = new TreeNode(CAT_SECTORS, 2, 2, catNodes);
if (noTag.Nodes.Count > 0) category.Nodes.Add(noTag);
categories.Add(nodeInfo.Tag, new TreeNode(title, 2, 2, new TreeNode[] { node }));
}
else
{
categories[nodeInfo.Tag].Nodes.Add(node);
}
treeView.Nodes.Add(category);
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
break;
TreeNode category = new TreeNode(CAT_SECTORS, 2, 2, catNodes);
if (noTag.Nodes.Count > 0) category.Nodes.Add(noTag);
treeView.Nodes.Add(category);
}
else //just add them as they are
{
treeView.Nodes.Add(new TreeNode(CAT_SECTORS, 2, 2, nodes.ToArray()));
default:
treeView.Nodes.Add(new TreeNode(CAT_SECTORS, 2, 2, nodes.ToArray()));
break;
}
}
}
@ -411,10 +449,13 @@ namespace CodeImp.DoomBuilder.TagExplorer
{
if ((showTags && l.Tag != 0) || (showActions && l.Action > 0))
{
if (filteredTag != -1 && l.Tag != filteredTag) continue;
if (filteredAction != -1 && l.Action != filteredAction) continue;
if(filteredtags.Count > 0 && !filteredtags.Contains(l.Tag)) continue;
if(filteredactions.Count > 0 && !filteredactions.Contains(l.Action)) continue;
NodeInfo info = new NodeInfo(l);
if(filteredpolyobjects.Count > 0 && !filteredpolyobjects.Contains(info.PolyobjectNumber))
continue;
string name = info.GetName(ref comment, currentSortMode);
hasComment = comment.Length > 0;
@ -422,14 +463,23 @@ namespace CodeImp.DoomBuilder.TagExplorer
if (!udmf || serachStr.Length == 0 || (hasComment && comment.ToLowerInvariant().IndexOf(serachStr) != -1))
{
TreeNode node = new TreeNode(name, 5, 5);
node.Tag = info;
TreeNode node = new TreeNode(name, 5, 5) { Tag = info, ToolTipText = nodetooltip };
if (hasComment) node.ForeColor = commentColor;
nodes.Add(node);
if (info.Index == selection.Index && info.Type == selection.Type)
selectedNode = node;
}
}
else if(currentDisplayMode == DISPLAY_POLYOBJECTS)
{
NodeInfo info = new NodeInfo(l);
if(info.PolyobjectNumber != int.MinValue && (filteredpolyobjects.Count == 0 || filteredpolyobjects.Contains(info.PolyobjectNumber)))
{
string name = info.GetName(ref comment, SortMode.SORT_BY_POLYOBJ_NUMBER);
TreeNode node = new TreeNode(name, 1, 1) { Tag = info, ToolTipText = nodetooltip };
nodes.Add(node);
}
}
}
@ -439,76 +489,79 @@ namespace CodeImp.DoomBuilder.TagExplorer
//add category
if (nodes.Count > 0)
{
if (currentSortMode == SortMode.SORT_BY_ACTION)
switch(currentSortMode)
{
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noAction = new TreeNode("No Action", 4, 4);
foreach (TreeNode node in nodes)
case SortMode.SORT_BY_ACTION:
{
NodeInfo nodeInfo = node.Tag as NodeInfo;
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noAction = new TreeNode("No Action", 4, 4);
if (nodeInfo.Action == 0)
foreach (TreeNode node in nodes)
{
noAction.Nodes.Add(node);
continue;
NodeInfo nodeInfo = node.Tag as NodeInfo;
if(nodeInfo.Action == 0)
{
noAction.Nodes.Add(node);
continue;
}
LinedefActionInfo lai = General.Map.Config.GetLinedefActionInfo(nodeInfo.Action);
if(!categories.ContainsKey(lai.Index)) categories.Add(lai.Index, new TreeNode(lai.Index + " - " + lai.Name, 4, 4, new[] { node }));
else categories[lai.Index].Nodes.Add(node);
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
LinedefActionInfo lai = General.Map.Config.GetLinedefActionInfo(nodeInfo.Action);
TreeNode category = new TreeNode(CAT_LINEDEFS, 4, 4, catNodes);
if(noAction.Nodes.Count > 0) category.Nodes.Add(noAction);
if (!categories.ContainsKey(lai.Index))
categories.Add(lai.Index, new TreeNode(lai.Index + " - " + lai.Name, 4, 4, new TreeNode[] { node }));
else
categories[lai.Index].Nodes.Add(node);
treeView.Nodes.Add(category);
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
break;
TreeNode category = new TreeNode(CAT_LINEDEFS, 4, 4, catNodes);
if (noAction.Nodes.Count > 0) category.Nodes.Add(noAction);
treeView.Nodes.Add(category);
}
else if (currentSortMode == SortMode.SORT_BY_TAG)
{
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noTag = new TreeNode("No Tag", 4, 4);
foreach (TreeNode node in nodes)
case SortMode.SORT_BY_TAG:
{
NodeInfo nodeInfo = node.Tag as NodeInfo;
Dictionary<int, TreeNode> categories = new Dictionary<int, TreeNode>();
TreeNode noTag = new TreeNode("No Tag", 4, 4);
if (nodeInfo.Tag == 0)
foreach (TreeNode node in nodes)
{
noTag.Nodes.Add(node);
continue;
NodeInfo nodeInfo = node.Tag as NodeInfo;
if (nodeInfo.Tag == 0)
{
noTag.Nodes.Add(node);
continue;
}
if(!categories.ContainsKey(nodeInfo.Tag))
{
string title = "Tag " + nodeInfo.Tag;
if(General.Map.Options.TagLabels.ContainsKey(nodeInfo.Tag))
title += ": " + General.Map.Options.TagLabels[nodeInfo.Tag];
categories.Add(nodeInfo.Tag, new TreeNode(title, 4, 4, new[] { node }));
}
else
{
categories[nodeInfo.Tag].Nodes.Add(node);
}
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
if(!categories.ContainsKey(nodeInfo.Tag))
{
string title = "Tag " + nodeInfo.Tag;
if(General.Map.Options.TagLabels.ContainsKey(nodeInfo.Tag))
title += ": " + General.Map.Options.TagLabels[nodeInfo.Tag];
TreeNode category = new TreeNode(CAT_LINEDEFS, 4, 4, catNodes);
if (noTag.Nodes.Count > 0) category.Nodes.Add(noTag);
categories.Add(nodeInfo.Tag, new TreeNode(title, 4, 4, new TreeNode[] { node }));
}
else
{
categories[nodeInfo.Tag].Nodes.Add(node);
}
treeView.Nodes.Add(category);
}
TreeNode[] catNodes = new TreeNode[categories.Values.Count];
categories.Values.CopyTo(catNodes, 0);
break;
TreeNode category = new TreeNode(CAT_LINEDEFS, 4, 4, catNodes);
if (noTag.Nodes.Count > 0) category.Nodes.Add(noTag);
treeView.Nodes.Add(category);
}
else //just add them as they are
{
treeView.Nodes.Add(new TreeNode(CAT_LINEDEFS, 4, 4, nodes.ToArray()));
default:
treeView.Nodes.Add(new TreeNode(CAT_LINEDEFS, 4, 4, nodes.ToArray()));
break;
}
}
}
@ -531,25 +584,40 @@ namespace CodeImp.DoomBuilder.TagExplorer
}
//tag/action search
private static void GetSpecialValues(string serachStr, ref int filteredTag, ref int filteredAction)
private static void GetSpecialValues(string serachstr, ref List<int> filteredtags, ref List<int> filteredactions, ref List<int> filteredpolyobjects)
{
if (serachStr.Length == 0) return;
if (serachstr.Length == 0) return;
int pos = serachStr.IndexOf("#");
if (pos != -1) filteredTag = ReadNumber(serachStr, pos+1);
string[] tags = serachstr.Split(new[]{ '#' });
foreach (string tagstr in tags)
{
int tag = ReadNumber(tagstr);
if(tag != int.MinValue) filteredtags.Add(tag);
}
pos = serachStr.IndexOf("$");
if (pos != -1) filteredAction = ReadNumber(serachStr, pos+1);
string[] actions = serachstr.Split(new[] { '$' });
foreach(string actionstr in actions)
{
int action = ReadNumber(actionstr);
if(action != int.MinValue) filteredactions.Add(action);
}
string[] ponums = serachstr.Split(new[] { '^' });
foreach(string postr in ponums)
{
int ponum = ReadNumber(postr);
if(ponum != int.MinValue) filteredpolyobjects.Add(ponum);
}
}
private static int ReadNumber(string serachStr, int startPoition)
private static int ReadNumber(string str)
{
string token = "";
int pos = startPoition;
int pos = 0;
while (pos < serachStr.Length && Configuration.NUMBERS.IndexOf(serachStr[pos]) != -1)
while (pos < str.Length && Configuration.NUMBERS.IndexOf(str[pos]) != -1)
{
token += serachStr[pos];
token += str[pos];
pos++;
}
@ -560,21 +628,35 @@ namespace CodeImp.DoomBuilder.TagExplorer
return result;
}
return -1;
return int.MinValue;
}
#endregion
#region ================== Sorting
private static void Sort(ref List<TreeNode> nodes, string sortMode)
private void Sort(ref List<TreeNode> nodes, string sortMode)
{
if(sortMode == SortMode.SORT_BY_ACTION)
nodes.Sort(SortByAction);
else if (sortMode == SortMode.SORT_BY_TAG)
nodes.Sort(SortByTag);
else
nodes.Sort(SortByIndex);
switch (sortMode)
{
case SortMode.SORT_BY_ACTION:
nodes.Sort(SortByAction);
break;
case SortMode.SORT_BY_TAG:
nodes.Sort(SortByTag);
break;
case SortMode.SORT_BY_INDEX:
if(currentDisplayMode == DISPLAY_POLYOBJECTS)
nodes.Sort(SortByPolyobjectNumber);
else
nodes.Sort(SortByIndex);
break;
default:
throw new NotImplementedException("Tag Explorer: Sort mode '" + sortMode + "' is not implemented!");
}
}
private static int SortByAction(TreeNode t1, TreeNode t2)
@ -582,7 +664,7 @@ namespace CodeImp.DoomBuilder.TagExplorer
NodeInfo i1 = t1.Tag as NodeInfo;
NodeInfo i2 = t2.Tag as NodeInfo;
if (i1.Action == i2.Action) return 0;
if (i1.Action == i2.Action) return SortByTag(t1, t2);
if (i1.Action == 0) return 1; //push items with no action to the end of the list
if (i2.Action == 0) return -1; //push items with no action to the end of the list
if (i1.Action > i2.Action) return 1;
@ -594,7 +676,7 @@ namespace CodeImp.DoomBuilder.TagExplorer
NodeInfo i1 = t1.Tag as NodeInfo;
NodeInfo i2 = t2.Tag as NodeInfo;
if (i1.Tag == i2.Tag) return 0;
if(i1.Tag == i2.Tag) return SortByIndex(t1, t2);
if (i1.Tag == 0) return 1; //push items with no tag to the end of the list
if (i2.Tag == 0) return -1; //push items with no tag to the end of the list
if (i1.Tag > i2.Tag) return 1;
@ -611,6 +693,17 @@ namespace CodeImp.DoomBuilder.TagExplorer
return -1;
}
private static int SortByPolyobjectNumber(TreeNode t1, TreeNode t2)
{
NodeInfo i1 = t1.Tag as NodeInfo;
NodeInfo i2 = t2.Tag as NodeInfo;
if(i1.PolyobjectNumber > i2.PolyobjectNumber) return 1;
if(i1.PolyobjectNumber == i2.PolyobjectNumber)
return String.CompareOrdinal(i1.DefaultName, i2.DefaultName);
return -1;
}
#endregion
#region ================== Events
@ -774,7 +867,7 @@ namespace CodeImp.DoomBuilder.TagExplorer
private void treeView_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
{
//edit comment
if (udmf)
if (udmf && currentDisplayMode != DISPLAY_POLYOBJECTS)
{
NodeInfo info = e.Node.Tag as NodeInfo;
if (info == null) return;
@ -854,7 +947,7 @@ namespace CodeImp.DoomBuilder.TagExplorer
if(n.Nodes.Count == 0) continue;
if(sb.Length > 0) sb.AppendLine(Environment.NewLine);
sb.AppendLine(n.Text.Replace(":", " (" +currentSortMode.ToLowerInvariant()+ "):"));
sb.AppendLine(n.Text.Replace(":", " (" + currentSortMode.ToLowerInvariant() + "):"));
//second level
foreach(TreeNode cn in n.Nodes)
@ -887,5 +980,4 @@ namespace CodeImp.DoomBuilder.TagExplorer
#endregion
}
}
}

View file

@ -124,111 +124,114 @@
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAq
FwAAAk1TRnQBSQFMAgEBBgEAAXgBAAF4AQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABIAMAAQEBAAEgBgABIBYAAxIBGQMSARkDEgEZNAADEgEZAxIBGQMSARmwAAMwAUwBAAE6AecB/wEA
ASYBoQH/AzABTAMSARksAAMwAUwBswFoAR4B/wFyAUIBFAH/AzABTAMSARmsAAEXAVcC/wEPAVEC/wEA
ATMBzgH/AQABJgGhAf8DEgEZLAAB4AGHASYB/wHZAYYBJQH/AZ4BXAEbAf8BcgFCARQB/wMSARmsAAFr
AZsC/wHoAe8C/wEPAVEC/wEAAToB5wH/AxIBGSwAAf4BtAFjAv8B/QHlAf8B2QGGASUB/wGzAWgBHgH/
AxIBGawAAzABTAFrAZsC/wEXAVcC/wOJAf8DPwH/AyMBMygAAzABTAH+AbQBYwH/AeABhwEmAf8BowGJ
AWgB/wM/Af8DIwEzsAADIwEzA7wB/wOBAf8DPwH/AyMBMwgAAyMBMwMjATMDIwEzGAADIwEzA7wB/wOB
Af8DPwH/AyMBMwgAAyMBMwMjATMDIwEznAADIwEzA80B/wOUAf8DPwH/AyMBMwMwAUwDPwH/A5QB/wMj
ATMcAAMjATMDzQH/A5QB/wM/Af8DIwEzAzABTAM/Af8DlAH/AyMBM6AAAyMBMwPNAf8DlAH/Az8B/wM/
Af8DlAH/AyMBMyQAAyMBMwPNAf8DlAH/Az8B/wM/Af8DlAH/AyMBM6gAAyMBMwO4Af8DlAH/A4EB/wMj
ATMsAAMjATMDuAH/A5QB/wOBAf8DIwEzsAADIwEzA88B/wOUAf8DPwH/AyMBMywAAyMBMwPPAf8DlAH/
Az8B/wMjATOwAAMjATMDwwH/A5QB/wM/Af8DIwEzLAADIwEzA8MB/wOUAf8DPwH/AyMBM7AAAyMBMwO8
Af8DlAH/Az8B/wMSARkDEgEZAxIBGSQAAyMBMwO8Af8DlAH/Az8B/wMSARkDEgEZAxIBGagAAyMBMwPZ
Af8DtwH/AQABOgHnAf8BAAEmAaEB/wMwAUwDEgEZJAADIwEzA9kB/wHRAbcBnQH/AbMBaAEeAf8BcgFC
ARQB/wMwAUwDEgEZqAADIwEzARcBVwL/AQ8BUQL/AQABMwHOAf8BAAEmAaEB/wMSARkoAAMjATMB4AGH
ASYB/wHZAYYBJQH/AZ4BXAEbAf8BcgFCARQB/wMSARmsAAFrAZsC/wHoAe8C/wEPAVEC/wEAAToB5wH/
AxIBGSwAAf4BtAFjAv8B/QHlAf8B2QGGASUB/wGzAWgBHgH/AxIBGawAAzABTAFrAZsC/wEXAVcC/wMw
AUwwAAMwAUwB/gG0AWMB/wHgAYcBJgH/AzABTJgAAwgBCwMfAS0DJwE7AycBOwMnATsDHgErAxIBGAMS
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAo
FwAAAk1TRnQBSQFMAgEBBgEAAYABAAGAAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABIAMAAQEBAAEgBgABIBYAAxIBGQMSARkDEgEZNAADEgEZAxIBGQMSARmwAAMwAUwBAAE5AecB/wEA
ASUBoQH/AzABTAMSARksAAMwAUwBswFnAR0B/wFxAUEBEwH/AzABTAMSARmsAAEWAVYC/wEOAVAC/wEA
ATIBzgH/AQABJQGhAf8DEgEZLAAB4AGHASUB/wHZAYYBJAH/AZ4BWwEaAf8BcQFBARMB/wMSARmsAAFq
AZsC/wHoAe8C/wEOAVAC/wEAATkB5wH/AxIBGSwAAf4BtAFiAv8B/QHlAf8B2QGGASQB/wGzAWcBHQH/
AxIBGawAAzABTAFqAZsC/wEWAVYC/wOJAf8DPgH/AyMBMygAAzABTAH+AbQBYgH/AeABhwElAf8BowGJ
AWcB/wM+Af8DIwEzsAADIwEzA7wB/wOBAf8DPgH/AyMBMwgAAyMBMwMjATMDIwEzGAADIwEzA7wB/wOB
Af8DPgH/AyMBMwgAAyMBMwMjATMDIwEznAADIwEzA80B/wOUAf8DPgH/AyMBMwMwAUwDPgH/A5QB/wMj
ATMcAAMjATMDzQH/A5QB/wM+Af8DIwEzAzABTAM+Af8DlAH/AyMBM6AAAyMBMwPNAf8DlAH/Az4B/wM+
Af8DlAH/AyMBMyQAAyMBMwPNAf8DlAH/Az4B/wM+Af8DlAH/AyMBM6gAAyMBMwO4Af8DlAH/A4EB/wMj
ATMsAAMjATMDuAH/A5QB/wOBAf8DIwEzsAADIwEzA88B/wOUAf8DPgH/AyMBMywAAyMBMwPPAf8DlAH/
Az4B/wMjATOwAAMjATMDwwH/A5QB/wM+Af8DIwEzLAADIwEzA8MB/wOUAf8DPgH/AyMBM7AAAyMBMwO8
Af8DlAH/Az4B/wMSARkDEgEZAxIBGSQAAyMBMwO8Af8DlAH/Az4B/wMSARkDEgEZAxIBGagAAyMBMwPZ
Af8DtwH/AQABOQHnAf8BAAElAaEB/wMwAUwDEgEZJAADIwEzA9kB/wHRAbcBnQH/AbMBZwEdAf8BcQFB
ARMB/wMwAUwDEgEZqAADIwEzARYBVgL/AQ4BUAL/AQABMgHOAf8BAAElAaEB/wMSARkoAAMjATMB4AGH
ASUB/wHZAYYBJAH/AZ4BWwEaAf8BcQFBARMB/wMSARmsAAFqAZsC/wHoAe8C/wEOAVAC/wEAATkB5wH/
AxIBGSwAAf4BtAFiAv8B/QHlAf8B2QGGASQB/wGzAWcBHQH/AxIBGawAAzABTAFqAZsC/wEWAVYC/wMw
AUwwAAMwAUwB/gG0AWIB/wHgAYcBJQH/AzABTJgAAwgBCwMfAS0DJwE7AycBOwMnATsDHgErAxIBGAMS
ARggAAMIAQsDHwEtAycBOwMnATsDJwE7Ax4BKwMSARgDEgEYEAADEgEZAxIBGQMSARkgAAMSARkDEgEZ
AxIBGQgAAxIBGQMSARkDEgEZIAADEgEZAxIBGQMSARkUAAM4AVwDXwHoAR0BJQGBAf8BFwEeAWsB/wEW
AR0BaAH/ARUBHAFhAf8CWgFgAeQDOAFcAycBOwMSARgYAAM4AVwDXwHoAYEBUAEdAf8BawFIARcB/wFo
AUYBFgH/AWEBQQEVAf8BYQJaAeQDOAFcAycBOwMSARgIAAMwAUwBHwEuAbIB/wEVASIBcQH/AzABTAMS
ARkDEgEZAxIBGQMSARkDEgEZAxIBGQMSARkDMAFMAR8BLgGyAf8BFQEiAXEB/wMwAUwDEgEZAzABTAGy
AWgBHwH/AXEBQgEVAf8DMAFMAxIBGQMSARkDEgEZAxIBGQMSARkDEgEZAxIBGQMwAUwBsgFoAR8B/wFx
AUIBFQH/AzABTAMSARkMAANaAcUBLQE5AbsB/wErATcBvAH/ASoBNgG6Af8BKQE1AbcB/wEnATEBtAH/
ASUBMAGsAf8BIAEoAZQB/wEWAR4BawH/A1oBvQMnATsDEgEYEAADWgHFAbsBgwEtAf8BvAGCASsB/wG6
AYEBKgH/AbcBgQEpAf8BtAGBAScB/wGsAW4BJQH/AZQBYAEgAf8BawFHARYB/wNaAb0DJwE7AxIBGAQA
ASgBQAHfAf8BJgE6AdgB/wEbAScBnQH/ARUBIgFxAf8DOAH/AzgB/wM4Af8DOAH/AzgB/wM4Af8DOAH/
ASgBQAHfAf8BJgE6AdgB/wEbAScBnQH/ARUBIgFxAf8DEgEZAd8BhwEoAf8B2AGGASYB/wGdAVwBGwH/
AXEBQgEVAf8DOAH/AzgB/wM4Af8DOAH/AzgB/wM4Af8DOAH/Ad8BhwEoAf8B2AGGASYB/wGdAVwBGwH/
AXEBQgEVAf8DEgEZCAADWQG+ATIBPwHTAf8BNwFGAegB/wE7AUkB8wH/AToBSQHwAf8BOQFJAe8B/wE5
AUkB7wH/ATgBRgHtAf8BNQFEAeIB/wErATcBuwH/ARsBIgGBAf8DWgG9AycBOwMSARgIAANZAb4B0wGT
ATIB/wHoAaEBNwH/AfMBqgE7Af8B8AGnAToB/wHvAaUBOQH/Ae8BpQE5Af8B7QGlATgB/wHiAZwBNQH/
AbsBggErAf8BgQFSARsB/wNaAb0DJwE7AxIBGAFkAYEB/QH/AewB5QL/ASYBOgHYAf8BHwEuAbIB/wO4
Af8DuAH/A7gB/wO4Af8DuAH/A6YB/wOYAf8BZAGBAf0B/wHsAeUC/wEmAToB2AH/AR8BLgGyAf8DEgEZ
Af0BtAFkAv8B/QHlAf8B2AGGASYB/wGyAWgBHwH/A7gB/wO4Af8DuAH/A7gB/wO4Af8DpgH/A5gB/wH9
AbQBZAL/Af0B5QH/AdgBhgEmAf8BsgFoAR8B/wMSARkEAAM4AVwBOwFJAeMB/wE6AUgB8QH/ASoBNQGz
Af8BKAEzAasB/wE4AUYB6gH/AT0BTQH6Af8BPAFLAfYB/wE6AUgB8QH/AToBSQHwAf8BNwFFAeoB/wEq
ATUBvgH/ARoBIAGBAf8DOAFcAxIBGAQAAzgBXAHjAaABOwH/AfEBqAE6Af8BswGBASoB/wGrAW8BKAH/
AeoBowE4Af8B+gGuAT0B/wH2AawBPAH/AfEBqAE6Af8B8AGnAToB/wHqAaMBNwH/Ab4BhAEqAf8BgQFR
ARoB/wM4AVwDEgEYAzABTAFkAYEB/QH/ASgBQAHfAf8DMAFMDAADuAH/A04BmQgAAzABTAFkAYEB/QH/
ASgBQAHfAf8DMAFMBAADMAFMAf0BtAFkAf8B3wGHASgB/wMwAUwMAAO4Af8DTgGZCAADMAFMAf0BtAFk
Af8B3wGHASgB/wMwAUwIAANfAdsBSgFYAfYB/wFEAVMC/wEqATUBsQH/AwAB/wEDAQUBHwH/ARgBHwFr
Af8BLwE6AcIB/wE6AUoB8QH/AT0BTQH6Af8BOwFLAfQB/wE0AUIB5AH/ASUBMAGsAf8CXAFkAecDHgEr
BAADXwHbAfYBsQFKAv8BtAFEAf8BsQFzASoB/wMAAf8BHwEUAQMB/wFrAUgBGAH/AcIBiAEvAf8B8QGn
AToB/wH6Aa4BPQH/AfQBqQE7Af8B5AGeATQB/wGsAW4BJQH/AWQBYgFcAecDHgErBAADmAH/Az8B/wMS
ARkMAAOlAf8DTgGZDAADmAH/AzgB/wMSARkIAAOYAf8DPwH/AxIBGQwAA6UB/wNOAZkMAAOYAf8DOAH/
AxIBGQgAAUcBVQL/AV8BbQL/AU4BWwH7Af8BQAFOAegB/wEDAQQBFQH/AwAB/wMAAf8DAAH/AQcBCgEu
Af8BHQElAYQB/wExAT0BzgH/ATkBSAHvAf8BLwE7AcwB/wEeAScBigH/AycBOwQAAf8BtgFHAv8BvgFf
Af8B+wG3AU4B/wHoAaUBQAH/ARUBDgEDAf8DAAH/AwAB/wMAAf8BLgEeAQcB/wGEAVQBHQH/Ac4BkAEx
Af8B7wGmATkB/wHMAY4BLwH/AYoBWAEeAf8DJwE7BAADpgH/Az8B/wMSARkgAAOmAf8DOAH/AxIBGQgA
A6YB/wM/Af8DEgEZIAADpgH/AzgB/wMSARkEAAMjATMBWgFnAv8BcAGEAv8BWAFkAfkB/wFKAVkB/AH/
ARsBIwFwAf8DAAH/AwAB/wMAAf8BAQECAQgB/wEUARsBWgH/ASQBLQGdAf8BNwFEAeQB/wE0AUMB4QH/
ASEBKgGcAf8DJwE7AyMBMwH/Ab0BWgL/AcYBcAH/AfkBugFYAf8B/AG0AUoB/wFwAUwBGwH/AwAB/wMA
Af8DAAH/AQgBBQEBAf8BWgE8ARQB/wGdAWYBJAH/AeQBoAE3Af8B4QGbATQB/wGcAWQBIQH/AycBOwQA
A7AB/wM/Af8DTgGZA04BmRQAA04BmQNOAZkDsAH/AzgB/wMSARkIAAOwAf8DPwH/A04BmQNOAZkUAANO
AZkDTgGZA7AB/wM4Af8DEgEZBAADIwEzAWQBcQL/AYEBjAL/AVkBZwH4Af8BSAFYAfsB/wEwATwBywH/
AwAB/wMAAf8DAAH/AQ0BEQFAAf8BPQFMAfkB/wE9AU0B+gH/AToBSQHwAf8BNAFCAeMB/wEiASwBogH/
AycBOwMjATMB/wHBAWQC/wHKAYEB/wH4AbgBWQH/AfsBsgFIAf8BywGOATAB/wMAAf8DAAH/AwAB/wFA
ASsBDQH/AfkBrgE9Af8B+gGuAT0B/wHwAacBOgH/AeMBnQE0Af8BogFoASIB/wMnATsEAAO4Af8DuAH/
A7gB/wOlAf8UAAOlAf8DuAH/A7gB/wM4Af8DEgEZCAADuAH/A7gB/wO4Af8DpQH/FAADpQH/A7gB/wO4
Af8DOAH/AxIBGQgAAWIBcQL/AY4BlwL/AWEBbAH+Af8BSgFZAfUB/wFAAU4B+AH/AQwBEQFAAf8DAAH/
ARkBIQFvAf8DAAH/ARABFgFPAf8BOgFJAfAB/wE7AUkB8wH/ATIBQAHaAf8BJAEtAZ8B/wMiATEEAAH/
Ab8BYgL/AdABjgH/Af4BwQFhAf8B9QGwAUoB/wH4Aa8BQAH/AUABKgEMAf8DAAH/AW8BSgEZAf8DAAH/
AU8BNAEQAf8B8AGnAToB/wHzAaoBOwH/AdoBlwEyAf8BnwFoASQB/wMiATEEAAO4Af8DPwH/AxIBGSAA
A7gB/wM4Af8DEgEZCAADuAH/Az8B/wMSARkgAAO4Af8DOAH/AxIBGQgAA18B2wGWAaAC/wGGAZAC/wFi
AW8B+QH/AU0BWwH+Af8BJQEvAZ0B/wELARABPAH/AT8BTwL/ASMBLAGYAf8DAAH/ARABFgFPAf8BOQFI
Ae0B/wEyAT8B1QH/A1wB6gMMARAEAANfAdsB/wHSAZYC/wHMAYYB/wH5AbwBYgH/Af4BuAFNAf8BnQFm
ASUB/wE8AScBCwL/AbIBPwH/AZgBYwEjAf8DAAH/AU8BNAEQAf8B7QGlATkB/wHVAZQBMgH/AV0CXAHq
AwwBEAQAA7gB/wM/Af8DEgEZIAADuAH/AzgB/wMSARkIAAO4Af8DPwH/AxIBGSAAA7gB/wM4Af8DEgEZ
CAADOAFcAZgBogL/AZ4BpwL/AWsBgQL/AVcBZAH5Af8BQgFNAeQB/wEzAT4BvgH/AUMBUwH4Af8BRQFT
Af0B/wEsATQBnAH/AwAB/wEpATMBsQH/ATUBQgHeAf8DOAFcCAADOAFcAf8B0wGYAv8B1gGeAv8BxQFr
Af8B+QG5AVcB/wHkAaUBQgH/Ab4BhwEzAf8B+AGuAUMB/wH9AbQBRQH/AZwBaQEsAf8DAAH/AbEBgAEp
Af8B3gGbATUB/wM4AVwIAAO4Af8DPwH/AxIBGQwAA6UB/wNOAZkMAAO4Af8DOAH/AxIBGQgAA7gB/wM/
Af8DEgEZDAADpQH/A04BmQwAA7gB/wM4Af8DEgEZDAADVQGyAagBsQL/AYkBkwL/AXEBgwL/AWgBgAH8
Af8BXQFpAfYB/wFXAWMB9gH/AVYBYgH1Af8BUgFfAfsB/wE1AT8BwgH/ATYBRAHgAf8DWwHGEAADVQGy
Af8B2QGoAv8BzgGJAv8ByAFxAf8B/AHBAWgB/wH2AbkBXQH/AfYBtwFXAf8B9QG2AVYB/wH7AbgBUgH/
AcIBiwE1Af8B4AGcATYB/wNbAcYIAAMwAUwBHwEuAbIB/wEVASIBcQH/AzABTAMSARkDEgEZAxIBGQO4
Af8DTgGZAxIBGQMSARkDMAFMAR8BLgGyAf8BFQEiAXEB/wMwAUwDEgEZAzABTAGyAWgBHwH/AXEBQgEV
Af8DMAFMAxIBGQMSARkDEgEZA7gB/wNOAZkDEgEZAxIBGQMwAUwBsgFoAR8B/wFxAUIBFQH/AzABTAMS
ARkMAANWAbEBnwGpAv8BlwGiAv8BiwGVAv8BbAGCAv8BWgFpAf0B/wFQAV0B+QH/AUQBUwH3Af8BPQFN
AfoB/wNaAb0YAANWAbEB/wHVAZ8C/wHRAZcC/wHPAYsC/wHDAWwB/wH9AboBWgH/AfkBtgFQAf8B9wGv
AUQB/wH6Aa0BPQH/A1oBvQwAASgBQAHfAf8BJgE6AdgB/wEbAScBnQH/ARUBIgFxAf8DPwH/Az8B/wM/
Af8DuAH/Az8B/wM/Af8DPwH/ASgBQAHfAf8BJgE6AdgB/wEbAScBnQH/ARUBIgFxAf8DEgEZAd8BhwEo
Af8B2AGGASYB/wGdAVwBGwH/AXEBQgEVAf8DPwH/Az8B/wM/Af8DuAH/Az8B/wM/Af8DPwH/Ad8BhwEo
Af8B2AGGASYB/wGdAVwBGwH/AXEBQgEVAf8DEgEZEAADOAFcA14B2AFzAYcC/wGDAY0C/wFsAYMC/wFX
AWUC/wNeAdgDOAFcIAADOAFcA14B2AH/AccBcwL/AcwBgwL/AcIBbAL/AbwBVwH/A14B2AM4AVwQAAFk
AYEB/QH/AewB5QL/ASYBOgHYAf8BHwEuAbIB/wO4Af8DuAH/A7gB/wO4Af8DuAH/A6YB/wOYAf8BZAGB
Af0B/wHsAeUC/wEmAToB2AH/AR8BLgGyAf8DEgEZAf0BtAFkAv8B/QHlAf8B2AGGASYB/wGyAWgBHwH/
A7gB/wO4Af8DuAH/A7gB/wO4Af8DpgH/A5gB/wH9AbQBZAL/Af0B5QH/AdgBhgEmAf8BsgFoAR8B/wMS
ARkcAAMjATMDIwEzOAADIwEzAyMBMxwAAzABTAFkAYEB/QH/ASgBQAHfAf8DMAFMHAADMAFMAWQBgQH9
Af8BKAFAAd8B/wMwAUwEAAMwAUwB/QG0AWQB/wHfAYcBKAH/AzABTBwAAzABTAH9AbQBZAH/Ad8BhwEo
Af8DMAFMBAABQgFNAT4HAAE+AwABKAMAAUADAAEgAwABAQEAAQEGAAEBFgAD/wEAAY8B/wGPAf8EAAEH
Af8BBwH/BAABBwH/AQcB/wQAAQcB/wEHAf8EAAEDAf8BAwH/BAABwQGPAcEBjwQAAeABDwHgAQ8EAAHw
AR8B8AEfBAAB+AE/AfgBPwQAAfwBHwH8AR8EAAH+AQ8B/gEPBAAB/wEBAf8BAQQAAf8BgAH/AYAEAAH/
AcAB/wHABAAB/wHgAf8B4AQAAf8B4QH/AeEEAAH4AQcB+AEHAY8B8QGPAfEB8AEDAfABAwQAAeABAQHg
AQEEAAHAAQABwAUAAYABAAGAAQABDgFhAQ4BYQGAAQABgAEAAY4BcQGOAXEBgAEAAYABAAGPAfEBjwHx
BAABhwHBAYcBwQQAAYcBwQGHAcEBgAEAAYABAAGPAfEBjwHxAYABAAGAAQABjwHxAY8B8QGAAQEBgAEB
AY4BcQGOAXEBwAEDAcABAwQAAeABBwHgAQcEAAHwAQ8B8AEPBAAB/gF/Af4BfwEPAeEBDwHhCw==
AxIBGQgAAxIBGQMSARkDEgEZIAADEgEZAxIBGQMSARkUAAM4AVwDXwHoARwBJAGBAf8BFgEdAWoB/wEV
ARwBZwH/ARQBGwFgAf8CWgFgAeQDOAFcAycBOwMSARgYAAM4AVwDXwHoAYEBTwEcAf8BagFHARYB/wFn
AUUBFQH/AWABQAEUAf8BYQJaAeQDOAFcAycBOwMSARgIAAMwAUwBHgEtAbIB/wEUASEBcAH/AzABTAMS
ARkDEgEZAxIBGQMSARkDEgEZAxIBGQMSARkDMAFMAR4BLQGyAf8BFAEhAXAB/wMwAUwDEgEZAzABTAGy
AWcBHgH/AXABQQEUAf8DMAFMAxIBGQMSARkDEgEZAxIBGQMSARkDEgEZAxIBGQMwAUwBsgFnAR4B/wFw
AUEBFAH/AzABTAMSARkMAANaAcUBLAE4AbsB/wEqATYBvAH/ASkBNQG6Af8BKAE0AbcB/wEmATABtAH/
ASQBLwGsAf8BHwEnAZQB/wEVAR0BagH/A1oBvQMnATsDEgEYEAADWgHFAbsBgwEsAf8BvAGCASoB/wG6
AYEBKQH/AbcBgQEoAf8BtAGBASYB/wGsAW0BJAH/AZQBXwEfAf8BagFGARUB/wNaAb0DJwE7AxIBGAQA
AScBPwHfAf8BJQE5AdgB/wEaASYBnQH/ARQBIQFwAf8DNwH/AzcB/wM3Af8DNwH/AzcB/wM3Af8DNwH/
AScBPwHfAf8BJQE5AdgB/wEaASYBnQH/ARQBIQFwAf8DEgEZAd8BhwEnAf8B2AGGASUB/wGdAVsBGgH/
AXABQQEUAf8DNwH/AzcB/wM3Af8DNwH/AzcB/wM3Af8DNwH/Ad8BhwEnAf8B2AGGASUB/wGdAVsBGgH/
AXABQQEUAf8DEgEZCAADWQG+ATEBPgHTAf8BNgFFAegB/wE6AUgB8wH/ATkBSAHwAf8BOAFIAe8B/wE4
AUgB7wH/ATcBRQHtAf8BNAFDAeIB/wEqATYBuwH/ARoBIQGBAf8DWgG9AycBOwMSARgIAANZAb4B0wGT
ATEB/wHoAaEBNgH/AfMBqgE6Af8B8AGnATkB/wHvAaUBOAH/Ae8BpQE4Af8B7QGlATcB/wHiAZwBNAH/
AbsBggEqAf8BgQFRARoB/wNaAb0DJwE7AxIBGAFjAYEB/QH/AewB5QL/ASUBOQHYAf8BHgEtAbIB/wO4
Af8DuAH/A7gB/wO4Af8DuAH/A6YB/wOYAf8BYwGBAf0B/wHsAeUC/wElATkB2AH/AR4BLQGyAf8DEgEZ
Af0BtAFjAv8B/QHlAf8B2AGGASUB/wGyAWcBHgH/A7gB/wO4Af8DuAH/A7gB/wO4Af8DpgH/A5gB/wH9
AbQBYwL/Af0B5QH/AdgBhgElAf8BsgFnAR4B/wMSARkEAAM4AVwBOgFIAeMB/wE5AUcB8QH/ASkBNAGz
Af8BJwEyAasB/wE3AUUB6gH/ATwBTAH6Af8BOwFKAfYB/wE5AUcB8QH/ATkBSAHwAf8BNgFEAeoB/wEp
ATQBvgH/ARkBHwGBAf8DOAFcAxIBGAQAAzgBXAHjAaABOgH/AfEBqAE5Af8BswGBASkB/wGrAW4BJwH/
AeoBowE3Af8B+gGuATwB/wH2AawBOwH/AfEBqAE5Af8B8AGnATkB/wHqAaMBNgH/Ab4BhAEpAf8BgQFQ
ARkB/wM4AVwDEgEYAzABTAFjAYEB/QH/AScBPwHfAf8DMAFMDAADuAH/A04BmQgAAzABTAFjAYEB/QH/
AScBPwHfAf8DMAFMBAADMAFMAf0BtAFjAf8B3wGHAScB/wMwAUwMAAO4Af8DTgGZCAADMAFMAf0BtAFj
Af8B3wGHAScB/wMwAUwIAANfAdsBSQFXAfYB/wFDAVIC/wEpATQBsQH/AwAB/wECAQQBHgH/ARcBHgFq
Af8BLgE5AcIB/wE5AUkB8QH/ATwBTAH6Af8BOgFKAfQB/wEzAUEB5AH/ASQBLwGsAf8CXAFkAecDHgEr
BAADXwHbAfYBsQFJAv8BtAFDAf8BsQFyASkB/wMAAf8BHgETAQIB/wFqAUcBFwH/AcIBiAEuAf8B8QGn
ATkB/wH6Aa4BPAH/AfQBqQE6Af8B5AGeATMB/wGsAW0BJAH/AWQBYgFcAecDHgErBAADmAH/Az4B/wMS
ARkMAAOlAf8DTgGZDAADmAH/AzcB/wMSARkIAAOYAf8DPgH/AxIBGQwAA6UB/wNOAZkMAAOYAf8DNwH/
AxIBGQgAAUYBVAL/AV4BbAL/AU0BWgH7Af8BPwFNAegB/wECAQMBFAH/AwAB/wMAAf8DAAH/AQYBCQEt
Af8BHAEkAYQB/wEwATwBzgH/ATgBRwHvAf8BLgE6AcwB/wEdASYBigH/AycBOwQAAf8BtgFGAv8BvgFe
Af8B+wG3AU0B/wHoAaUBPwH/ARQBDQECAf8DAAH/AwAB/wMAAf8BLQEdAQYB/wGEAVMBHAH/Ac4BkAEw
Af8B7wGmATgB/wHMAY4BLgH/AYoBVwEdAf8DJwE7BAADpgH/Az4B/wMSARkgAAOmAf8DNwH/AxIBGQgA
A6YB/wM+Af8DEgEZIAADpgH/AzcB/wMSARkEAAMjATMBWQFmAv8BbwGEAv8BVwFjAfkB/wFJAVgB/AH/
ARoBIgFvAf8DAAH/AwAB/wMAAf8BAAEBAQcB/wETARoBWQH/ASMBLAGdAf8BNgFDAeQB/wEzAUIB4QH/
ASABKQGcAf8DJwE7AyMBMwH/Ab0BWQL/AcYBbwH/AfkBugFXAf8B/AG0AUkB/wFvAUsBGgH/AwAB/wMA
Af8DAAH/AQcBBAEAAf8BWQE7ARMB/wGdAWUBIwH/AeQBoAE2Af8B4QGbATMB/wGcAWMBIAH/AycBOwQA
A7AB/wM+Af8DTgGZA04BmRQAA04BmQNOAZkDsAH/AzcB/wMSARkIAAOwAf8DPgH/A04BmQNOAZkUAANO
AZkDTgGZA7AB/wM3Af8DEgEZBAADIwEzAWMBcAL/AYEBjAL/AVgBZgH4Af8BRwFXAfsB/wEvATsBywH/
AwAB/wMAAf8DAAH/AQwBEAE/Af8BPAFLAfkB/wE8AUwB+gH/ATkBSAHwAf8BMwFBAeMB/wEhASsBogH/
AycBOwMjATMB/wHBAWMC/wHKAYEB/wH4AbgBWAH/AfsBsgFHAf8BywGOAS8B/wMAAf8DAAH/AwAB/wE/
ASoBDAH/AfkBrgE8Af8B+gGuATwB/wHwAacBOQH/AeMBnQEzAf8BogFnASEB/wMnATsEAAO4Af8DuAH/
A7gB/wOlAf8UAAOlAf8DuAH/A7gB/wM3Af8DEgEZCAADuAH/A7gB/wO4Af8DpQH/FAADpQH/A7gB/wO4
Af8DNwH/AxIBGQgAAWEBcAL/AY4BlwL/AWABawH+Af8BSQFYAfUB/wE/AU0B+AH/AQsBEAE/Af8DAAH/
ARgBIAFuAf8DAAH/AQ8BFQFOAf8BOQFIAfAB/wE6AUgB8wH/ATEBPwHaAf8BIwEsAZ8B/wMiATEEAAH/
Ab8BYQL/AdABjgH/Af4BwQFgAf8B9QGwAUkB/wH4Aa8BPwH/AT8BKQELAf8DAAH/AW4BSQEYAf8DAAH/
AU4BMwEPAf8B8AGnATkB/wHzAaoBOgH/AdoBlwExAf8BnwFnASMB/wMiATEEAAO4Af8DPgH/AxIBGSAA
A7gB/wM3Af8DEgEZCAADuAH/Az4B/wMSARkgAAO4Af8DNwH/AxIBGQgAA18B2wGWAaAC/wGGAZAC/wFh
AW4B+QH/AUwBWgH+Af8BJAEuAZ0B/wEKAQ8BOwH/AT4BTgL/ASIBKwGYAf8DAAH/AQ8BFQFOAf8BOAFH
Ae0B/wExAT4B1QH/A1wB6gMMARAEAANfAdsB/wHSAZYC/wHMAYYB/wH5AbwBYQH/Af4BuAFMAf8BnQFl
ASQB/wE7ASYBCgL/AbIBPgH/AZgBYgEiAf8DAAH/AU4BMwEPAf8B7QGlATgB/wHVAZQBMQH/A1wB6gMM
ARAEAAO4Af8DPgH/AxIBGSAAA7gB/wM3Af8DEgEZCAADuAH/Az4B/wMSARkgAAO4Af8DNwH/AxIBGQgA
AzgBXAGYAaIC/wGeAacC/wFqAYEC/wFWAWMB+QH/AUEBTAHkAf8BMgE9Ab4B/wFCAVIB+AH/AUQBUgH9
Af8BKwEzAZwB/wMAAf8BKAEyAbEB/wE0AUEB3gH/AzgBXAgAAzgBXAH/AdMBmAL/AdYBngL/AcUBagH/
AfkBuQFWAf8B5AGlAUEB/wG+AYcBMgH/AfgBrgFCAf8B/QG0AUQB/wGcAWgBKwH/AwAB/wGxAYABKAH/
Ad4BmwE0Af8DOAFcCAADuAH/Az4B/wMSARkMAAOlAf8DTgGZDAADuAH/AzcB/wMSARkIAAO4Af8DPgH/
AxIBGQwAA6UB/wNOAZkMAAO4Af8DNwH/AxIBGQwAA1UBsgGoAbEC/wGJAZMC/wFwAYMC/wFnAYAB/AH/
AVwBaAH2Af8BVgFiAfYB/wFVAWEB9QH/AVEBXgH7Af8BNAE+AcIB/wE1AUMB4AH/A1sBxhAAA1UBsgH/
AdkBqAL/Ac4BiQL/AcgBcAH/AfwBwQFnAf8B9gG5AVwB/wH2AbcBVgH/AfUBtgFVAf8B+wG4AVEB/wHC
AYsBNAH/AeABnAE1Af8DWwHGCAADMAFMAR4BLQGyAf8BFAEhAXAB/wMwAUwDEgEZAxIBGQMSARkDuAH/
A04BmQMSARkDEgEZAzABTAEeAS0BsgH/ARQBIQFwAf8DMAFMAxIBGQMwAUwBsgFnAR4B/wFwAUEBFAH/
AzABTAMSARkDEgEZAxIBGQO4Af8DTgGZAxIBGQMSARkDMAFMAbIBZwEeAf8BcAFBARQB/wMwAUwDEgEZ
DAADVgGxAZ8BqQL/AZcBogL/AYsBlQL/AWsBggL/AVkBaAH9Af8BTwFcAfkB/wFDAVIB9wH/ATwBTAH6
Af8DWgG9GAADVgGxAf8B1QGfAv8B0QGXAv8BzwGLAv8BwwFrAf8B/QG6AVkB/wH5AbYBTwH/AfcBrwFD
Af8B+gGtATwB/wNaAb0MAAEnAT8B3wH/ASUBOQHYAf8BGgEmAZ0B/wEUASEBcAH/Az4B/wM+Af8DPgH/
A7gB/wM+Af8DPgH/Az4B/wEnAT8B3wH/ASUBOQHYAf8BGgEmAZ0B/wEUASEBcAH/AxIBGQHfAYcBJwH/
AdgBhgElAf8BnQFbARoB/wFwAUEBFAH/Az4B/wM+Af8DPgH/A7gB/wM+Af8DPgH/Az4B/wHfAYcBJwH/
AdgBhgElAf8BnQFbARoB/wFwAUEBFAH/AxIBGRAAAzgBXANeAdgBcgGHAv8BgwGNAv8BawGDAv8BVgFk
Av8DXgHYAzgBXCAAAzgBXANeAdgB/wHHAXIC/wHMAYMC/wHCAWsC/wG8AVYB/wNeAdgDOAFcEAABYwGB
Af0B/wHsAeUC/wElATkB2AH/AR4BLQGyAf8DuAH/A7gB/wO4Af8DuAH/A7gB/wOmAf8DmAH/AWMBgQH9
Af8B7AHlAv8BJQE5AdgB/wEeAS0BsgH/AxIBGQH9AbQBYwL/Af0B5QH/AdgBhgElAf8BsgFnAR4B/wO4
Af8DuAH/A7gB/wO4Af8DuAH/A6YB/wOYAf8B/QG0AWMC/wH9AeUB/wHYAYYBJQH/AbIBZwEeAf8DEgEZ
HAADIwEzAyMBMzgAAyMBMwMjATMcAAMwAUwBYwGBAf0B/wEnAT8B3wH/AzABTBwAAzABTAFjAYEB/QH/
AScBPwHfAf8DMAFMBAADMAFMAf0BtAFjAf8B3wGHAScB/wMwAUwcAAMwAUwB/QG0AWMB/wHfAYcBJwH/
AzABTAQAAUIBTQE+BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYAA/8BAAGPAf8BjwH/BAABBwH/
AQcB/wQAAQcB/wEHAf8EAAEHAf8BBwH/BAABAwH/AQMB/wQAAcEBjwHBAY8EAAHgAQ8B4AEPBAAB8AEf
AfABHwQAAfgBPwH4AT8EAAH8AR8B/AEfBAAB/gEPAf4BDwQAAf8BAQH/AQEEAAH/AYAB/wGABAAB/wHA
Af8BwAQAAf8B4AH/AeAEAAH/AeEB/wHhBAAB+AEHAfgBBwGPAfEBjwHxAfABAwHwAQMEAAHgAQEB4AEB
BAABwAEAAcAFAAGAAQABgAEAAQ4BYQEOAWEBgAEAAYABAAGOAXEBjgFxAYABAAGAAQABjwHxAY8B8QQA
AYcBwQGHAcEEAAGHAcEBhwHBAYABAAGAAQABjwHxAY8B8QGAAQABgAEAAY8B8QGPAfEBgAEBAYABAQGO
AXEBjgFxAcABAwHAAQMEAAHgAQcB4AEHBAAB8AEPAfABDwQAAf4BfwH+AX8BDwHhAQ8B4Qs=
</value>
</data>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>122, 17</value>
</metadata>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>122, 17</value>
</metadata>
<metadata name="updatetimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>219, 17</value>
</metadata>

View file

@ -6,16 +6,19 @@ namespace CodeImp.DoomBuilder.TagExplorer
{
internal sealed class NodeInfo
{
private NodeInfoType type;
private readonly NodeInfoType type;
private int index;
private int action;
private int tag;
private string defaultName;
private readonly int index;
private readonly int action;
private readonly int tag;
private readonly int polyobjnumber;
private readonly string defaultName;
public int Index { get { return index; } }
public int Tag { get { return tag; } }
public int PolyobjectNumber { get { return polyobjnumber; } }
public int Action { get { return action; } }
public string DefaultName { get { return defaultName; } }
public NodeInfoType Type { get { return type; } }
public string Comment { get { return GetComment(); } set { SetComment(value); } }
@ -26,8 +29,9 @@ namespace CodeImp.DoomBuilder.TagExplorer
index = t.Index;
action = t.Action;
tag = t.Tag;
polyobjnumber = ((t.Type > 9299 && t.Type < 9304) ? t.AngleDoom : int.MinValue);
ThingTypeInfo tti = General.Map.Data.GetThingInfoEx(t.Type);
defaultName = (tti != null ? tti.Title : NodeInfoDefaultName.THING);
defaultName = (tti != null ? tti.Title : "Thing");
}
public NodeInfo(Sector s)
@ -36,6 +40,15 @@ namespace CodeImp.DoomBuilder.TagExplorer
index = s.Index;
action = s.Effect;
tag = s.Tag;
if(General.Map.Config.SectorEffects.ContainsKey(action))
{
defaultName = General.Map.Config.SectorEffects[action].Title;
}
else
{
defaultName = "Sector";
}
}
public NodeInfo(Linedef l)
@ -44,6 +57,16 @@ namespace CodeImp.DoomBuilder.TagExplorer
index = l.Index;
action = l.Action;
tag = l.Tag;
polyobjnumber = ((l.Action > 0 && l.Action < 9) ? l.Args[0] : int.MinValue);
if(General.Map.Config.LinedefActions.ContainsKey(l.Action))
{
defaultName = General.Map.Config.LinedefActions[l.Action].Title;
}
else
{
defaultName = "Linedef";
}
}
//methods
@ -52,20 +75,17 @@ namespace CodeImp.DoomBuilder.TagExplorer
if (type == NodeInfoType.THING)
{
Thing t = General.Map.Map.GetThingByIndex(index);
if (t == null) return null;
return t.Fields;
return (t == null ? null : t.Fields);
}
if (type == NodeInfoType.SECTOR)
{
Sector s = General.Map.Map.GetSectorByIndex(index);
if (s == null) return null;
return s.Fields;
return (s == null ? null : s.Fields);
}
Linedef l = General.Map.Map.GetLinedefByIndex(index);
if (l == null) return null;
return l.Fields;
return (l == null ? null : l.Fields);
}
//comment
@ -124,54 +144,42 @@ namespace CodeImp.DoomBuilder.TagExplorer
return GetLinedefName(l, ref comment, sortMode);
}
private string GetThingName(Thing t, ref string comment, string sortMode)
private string GetThingName(Thing t, ref string comment, string sortmode)
{
bool isDefaultName = true;
comment = "";
if (TagExplorer.UDMF && t.Fields.ContainsKey("comment"))
{
comment = t.Fields["comment"].Value.ToString();
isDefaultName = false;
}
return CombineName(comment.Length == 0 ? defaultName : comment, t.Tag, t.Action, t.Index, sortMode, isDefaultName);
comment = ((TagExplorer.UDMF && t.Fields.ContainsKey("comment")) ? t.Fields["comment"].Value.ToString() : string.Empty);
return CombineName(comment, sortmode);
}
private static string GetSectorName(Sector s, ref string comment, string sortMode)
private string GetSectorName(Sector s, ref string comment, string sortmode)
{
bool isDefaultName = true;
comment = "";
if (TagExplorer.UDMF && s.Fields.ContainsKey("comment"))
{
comment = s.Fields["comment"].Value.ToString();
isDefaultName = false;
}
return CombineName(comment.Length == 0 ? NodeInfoDefaultName.SECTOR : comment, s.Tag, s.Effect, s.Index, sortMode, isDefaultName);
comment = ((TagExplorer.UDMF && s.Fields.ContainsKey("comment")) ? s.Fields["comment"].Value.ToString() : string.Empty);
return CombineName(comment, sortmode);
}
private static string GetLinedefName(Linedef l, ref string comment, string sortMode)
private string GetLinedefName(Linedef l, ref string comment, string sortmode)
{
bool isDefaultName = true;
comment = "";
if (TagExplorer.UDMF && l.Fields.ContainsKey("comment"))
{
comment = l.Fields["comment"].Value.ToString();
isDefaultName = false;
}
return CombineName(comment.Length == 0 ? NodeInfoDefaultName.LINEDEF : comment, l.Tag, l.Action, l.Index, sortMode, isDefaultName);
if(polyobjnumber != int.MinValue) return CombineName(string.Empty, sortmode);
comment = ((TagExplorer.UDMF && l.Fields.ContainsKey("comment")) ? l.Fields["comment"].Value.ToString() : string.Empty);
return CombineName(comment, sortmode);
}
private static string CombineName(string name, int tag, int action, int index, string sortMode, bool isDefaultName)
private string CombineName(string comment, string sortmode)
{
switch (sortMode)
string name = (!string.IsNullOrEmpty(comment) ? comment : defaultName);
switch(sortmode)
{
case SortMode.SORT_BY_ACTION:
return (tag > 0 ? "Tag:" + tag + "; " : "") + name + (isDefaultName ? " " + index : "");
case SortMode.SORT_BY_ACTION: //action name is already shown as category name, so we'll show tag here
return (tag > 0 ? "Tag " + tag + ": " : "") + name + ", Index " + index;
case SortMode.SORT_BY_INDEX:
return index + (tag > 0 ? ": Tag:" + tag + "; " : ": ") + (action > 0 ? "Action:" + action + "; " : "") + name;
return index + ": " + name + (tag > 0 ? ", Tag " + tag : "") + (action > 0 ? ", Action " + action : "");
case SortMode.SORT_BY_TAG:
return (action > 0 ? "Action:" + action + "; " : "") + name + (isDefaultName ? " " + index : "");
case SortMode.SORT_BY_TAG: //tag is already shown as category name, so we'll show action here
return (action > 0 ? "Action " + action + ": " : "") + name + ", Index " + index;
case SortMode.SORT_BY_POLYOBJ_NUMBER:
return "PO " + polyobjnumber + ": " + defaultName + ", Index " + index;
default:
return name;
@ -185,12 +193,4 @@ namespace CodeImp.DoomBuilder.TagExplorer
SECTOR,
LINEDEF
}
internal struct NodeInfoDefaultName
{
public const string THING = "Thing";
public const string SECTOR = "Sector";
public const string LINEDEF = "Linedef";
}
}