mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-01-31 04:40:55 +00:00
Visual mode, "Lower/Raise Floor/Ceiling to adjacent sector" actions: you can now hold Ctrl to lower/raise sectors to lowest/highest sector inside selection.
Visual mode: added "Align Textures X and Y" action (default key is Ctrl-A). Preferences Form: Actions can now be filtered.
This commit is contained in:
parent
b104e88a1d
commit
d582d9b9a1
5 changed files with 323 additions and 100 deletions
60
Source/Core/Windows/PreferencesForm.Designer.cs
generated
60
Source/Core/Windows/PreferencesForm.Designer.cs
generated
|
@ -111,6 +111,9 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
this.fieldofviewlabel = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.tabkeys = new System.Windows.Forms.TabPage();
|
||||
this.bClearActionFilter = new System.Windows.Forms.Button();
|
||||
this.tbFilterActions = new System.Windows.Forms.TextBox();
|
||||
this.label24 = new System.Windows.Forms.Label();
|
||||
this.listactions = new System.Windows.Forms.ListView();
|
||||
this.columncontrolaction = new System.Windows.Forms.ColumnHeader();
|
||||
this.columncontrolkey = new System.Windows.Forms.ColumnHeader();
|
||||
|
@ -1108,6 +1111,9 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
//
|
||||
// tabkeys
|
||||
//
|
||||
this.tabkeys.Controls.Add(this.bClearActionFilter);
|
||||
this.tabkeys.Controls.Add(this.tbFilterActions);
|
||||
this.tabkeys.Controls.Add(this.label24);
|
||||
this.tabkeys.Controls.Add(this.listactions);
|
||||
this.tabkeys.Controls.Add(this.actioncontrolpanel);
|
||||
this.tabkeys.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
|
@ -1119,6 +1125,36 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
this.tabkeys.Text = "Controls";
|
||||
this.tabkeys.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// bClearActionFilter
|
||||
//
|
||||
this.bClearActionFilter.Image = global::CodeImp.DoomBuilder.Properties.Resources.SearchClear;
|
||||
this.bClearActionFilter.Location = new System.Drawing.Point(227, 10);
|
||||
this.bClearActionFilter.Name = "bClearActionFilter";
|
||||
this.bClearActionFilter.Size = new System.Drawing.Size(26, 25);
|
||||
this.bClearActionFilter.TabIndex = 12;
|
||||
this.bClearActionFilter.TabStop = false;
|
||||
this.bClearActionFilter.UseVisualStyleBackColor = true;
|
||||
this.bClearActionFilter.Click += new System.EventHandler(this.bClearActionFilter_Click);
|
||||
//
|
||||
// tbFilterActions
|
||||
//
|
||||
this.tbFilterActions.Location = new System.Drawing.Point(55, 13);
|
||||
this.tbFilterActions.Name = "tbFilterActions";
|
||||
this.tbFilterActions.Size = new System.Drawing.Size(166, 20);
|
||||
this.tbFilterActions.TabIndex = 11;
|
||||
this.tbFilterActions.TabStop = false;
|
||||
this.tbFilterActions.TextChanged += new System.EventHandler(this.tbFilterActions_TextChanged);
|
||||
//
|
||||
// label24
|
||||
//
|
||||
this.label24.AutoSize = true;
|
||||
this.label24.Font = new System.Drawing.Font("Arial", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.label24.Location = new System.Drawing.Point(11, 16);
|
||||
this.label24.Name = "label24";
|
||||
this.label24.Size = new System.Drawing.Size(38, 14);
|
||||
this.label24.TabIndex = 10;
|
||||
this.label24.Text = "Filter:";
|
||||
//
|
||||
// listactions
|
||||
//
|
||||
this.listactions.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
|
@ -1130,11 +1166,11 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
this.listactions.FullRowSelect = true;
|
||||
this.listactions.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.Nonclickable;
|
||||
this.listactions.HideSelection = false;
|
||||
this.listactions.Location = new System.Drawing.Point(11, 12);
|
||||
this.listactions.Location = new System.Drawing.Point(11, 42);
|
||||
this.listactions.Margin = new System.Windows.Forms.Padding(8, 9, 8, 9);
|
||||
this.listactions.MultiSelect = false;
|
||||
this.listactions.Name = "listactions";
|
||||
this.listactions.Size = new System.Drawing.Size(352, 462);
|
||||
this.listactions.Size = new System.Drawing.Size(352, 458);
|
||||
this.listactions.Sorting = System.Windows.Forms.SortOrder.Ascending;
|
||||
this.listactions.TabIndex = 0;
|
||||
this.listactions.TabStop = false;
|
||||
|
@ -1147,7 +1183,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
// columncontrolaction
|
||||
//
|
||||
this.columncontrolaction.Text = "Action";
|
||||
this.columncontrolaction.Width = 179;
|
||||
this.columncontrolaction.Width = 200;
|
||||
//
|
||||
// columncontrolkey
|
||||
//
|
||||
|
@ -1173,7 +1209,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
this.actioncontrolpanel.Location = new System.Drawing.Point(377, 12);
|
||||
this.actioncontrolpanel.Margin = new System.Windows.Forms.Padding(6);
|
||||
this.actioncontrolpanel.Name = "actioncontrolpanel";
|
||||
this.actioncontrolpanel.Size = new System.Drawing.Size(282, 462);
|
||||
this.actioncontrolpanel.Size = new System.Drawing.Size(282, 488);
|
||||
this.actioncontrolpanel.TabIndex = 9;
|
||||
this.actioncontrolpanel.TabStop = false;
|
||||
this.actioncontrolpanel.Text = " Action control ";
|
||||
|
@ -1185,10 +1221,10 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
this.keyusedlist.FormattingEnabled = true;
|
||||
this.keyusedlist.IntegralHeight = false;
|
||||
this.keyusedlist.ItemHeight = 14;
|
||||
this.keyusedlist.Location = new System.Drawing.Point(33, 307);
|
||||
this.keyusedlist.Location = new System.Drawing.Point(23, 307);
|
||||
this.keyusedlist.Name = "keyusedlist";
|
||||
this.keyusedlist.SelectionMode = System.Windows.Forms.SelectionMode.None;
|
||||
this.keyusedlist.Size = new System.Drawing.Size(232, 115);
|
||||
this.keyusedlist.Size = new System.Drawing.Size(233, 115);
|
||||
this.keyusedlist.Sorted = true;
|
||||
this.keyusedlist.TabIndex = 11;
|
||||
this.keyusedlist.Visible = false;
|
||||
|
@ -1212,7 +1248,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
this.actioncontrol.ImeMode = System.Windows.Forms.ImeMode.Off;
|
||||
this.actioncontrol.Location = new System.Drawing.Point(23, 190);
|
||||
this.actioncontrol.Name = "actioncontrol";
|
||||
this.actioncontrol.Size = new System.Drawing.Size(197, 22);
|
||||
this.actioncontrol.Size = new System.Drawing.Size(233, 22);
|
||||
this.actioncontrol.TabIndex = 8;
|
||||
this.actioncontrol.TabStop = false;
|
||||
this.actioncontrol.SelectedIndexChanged += new System.EventHandler(this.actioncontrol_SelectedIndexChanged);
|
||||
|
@ -1230,12 +1266,12 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
//
|
||||
// actioncontrolclear
|
||||
//
|
||||
this.actioncontrolclear.Location = new System.Drawing.Point(193, 138);
|
||||
this.actioncontrolclear.Image = global::CodeImp.DoomBuilder.Properties.Resources.SearchClear;
|
||||
this.actioncontrolclear.Location = new System.Drawing.Point(193, 137);
|
||||
this.actioncontrolclear.Name = "actioncontrolclear";
|
||||
this.actioncontrolclear.Size = new System.Drawing.Size(63, 25);
|
||||
this.actioncontrolclear.Size = new System.Drawing.Size(26, 25);
|
||||
this.actioncontrolclear.TabIndex = 6;
|
||||
this.actioncontrolclear.TabStop = false;
|
||||
this.actioncontrolclear.Text = "Clear";
|
||||
this.actioncontrolclear.UseVisualStyleBackColor = true;
|
||||
this.actioncontrolclear.Click += new System.EventHandler(this.actioncontrolclear_Click);
|
||||
//
|
||||
|
@ -1760,6 +1796,7 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
((System.ComponentModel.ISupportInitialize)(this.mousespeed)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.fieldofview)).EndInit();
|
||||
this.tabkeys.ResumeLayout(false);
|
||||
this.tabkeys.PerformLayout();
|
||||
this.actioncontrolpanel.ResumeLayout(false);
|
||||
this.actioncontrolpanel.PerformLayout();
|
||||
this.tabcolors.ResumeLayout(false);
|
||||
|
@ -1901,5 +1938,8 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
private System.Windows.Forms.Label label23;
|
||||
private System.Windows.Forms.Label numSectorsLabel;
|
||||
private Dotnetrix.Controls.TrackBar tbNumSectors;
|
||||
private System.Windows.Forms.Button bClearActionFilter;
|
||||
private System.Windows.Forms.TextBox tbFilterActions;
|
||||
private System.Windows.Forms.Label label24;
|
||||
}
|
||||
}
|
|
@ -42,6 +42,8 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
private bool allowapplycontrol = false;
|
||||
private bool disregardshift = false;
|
||||
private bool disregardcontrol = false;
|
||||
private List<ListViewItem> actionListItems; //mxd
|
||||
private List<int> actionListItemsGroupIndices; //mxd
|
||||
|
||||
private bool reloadresources = false;
|
||||
|
||||
|
@ -137,6 +139,8 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
|
||||
// Fill list of actions
|
||||
actions = General.Actions.GetAllActions();
|
||||
actionListItems = new List<ListViewItem>(); //mxd
|
||||
actionListItemsGroupIndices = new List<int>(); //mxd
|
||||
foreach(Actions.Action a in actions)
|
||||
{
|
||||
// Create item
|
||||
|
@ -145,8 +149,14 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
item.SubItems[1].Tag = a.ShortcutKey;
|
||||
|
||||
// Put in category, if the category exists
|
||||
if(General.Actions.Categories.ContainsKey(a.Category))
|
||||
if(General.Actions.Categories.ContainsKey(a.Category)) {
|
||||
item.Group = listactions.Groups[a.Category];
|
||||
actionListItemsGroupIndices.Add(listactions.Groups.IndexOf(item.Group));
|
||||
}else{ //mxd
|
||||
actionListItemsGroupIndices.Add(-1);
|
||||
}
|
||||
|
||||
actionListItems.Add(item); //mxd
|
||||
}
|
||||
|
||||
// Set the colors
|
||||
|
@ -245,7 +255,8 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
General.Settings.ScriptFontSize = fontsize;
|
||||
|
||||
// Apply control keys to actions
|
||||
foreach(ListViewItem item in listactions.Items)
|
||||
//foreach(ListViewItem item in listactions.Items)
|
||||
foreach(ListViewItem item in actionListItems) //mxd
|
||||
General.Actions[item.Name].SetShortcutKey((int)item.SubItems[1].Tag);
|
||||
|
||||
// Apply the colors
|
||||
|
@ -764,6 +775,50 @@ namespace CodeImp.DoomBuilder.Windows
|
|||
allowapplycontrol = true;
|
||||
}
|
||||
|
||||
//mxd
|
||||
private void bClearActionFilter_Click(object sender, EventArgs e) {
|
||||
tbFilterActions.Clear();
|
||||
}
|
||||
|
||||
//mxd
|
||||
private void tbFilterActions_TextChanged(object sender, EventArgs e) {
|
||||
listactions.BeginUpdate();
|
||||
|
||||
//restore everything
|
||||
if(string.IsNullOrEmpty(tbFilterActions.Text)) {
|
||||
//restore items
|
||||
listactions.Items.Clear();
|
||||
listactions.Items.AddRange(actionListItems.ToArray());
|
||||
|
||||
//restore groups
|
||||
for(int i = 0; i < actionListItems.Count; i++) {
|
||||
if(actionListItemsGroupIndices[i] != -1)
|
||||
actionListItems[i].Group = listactions.Groups[actionListItemsGroupIndices[i]];
|
||||
}
|
||||
} else { //apply filtering
|
||||
string match = tbFilterActions.Text.ToUpperInvariant();
|
||||
|
||||
for(int i = 0; i < actionListItems.Count; i++) {
|
||||
if(actionListItems[i].Text.ToUpperInvariant().Contains(match)) {
|
||||
//ensure visible
|
||||
if(!listactions.Items.Contains(actionListItems[i])) {
|
||||
listactions.Items.Add(actionListItems[i]);
|
||||
|
||||
//restore group
|
||||
if(actionListItemsGroupIndices[i] != -1)
|
||||
actionListItems[i].Group = listactions.Groups[actionListItemsGroupIndices[i]];
|
||||
}
|
||||
} else if(listactions.Items.Contains(actionListItems[i])) {
|
||||
//ensure invisible
|
||||
listactions.Items.Remove(actionListItems[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
listactions.Sort();
|
||||
listactions.EndUpdate();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region ================== Colors Panel
|
||||
|
|
|
@ -144,4 +144,7 @@
|
|||
<metadata name="label21.GenerateMember" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
|
@ -499,10 +499,11 @@ lowersectortonearest
|
|||
{
|
||||
title = "Lower Floor/Ceiling to adjacent sector";
|
||||
category = "visual";
|
||||
description = "Lowers the targeted or selected floors/ceilings to match the height of adjacent sector. Also drops selected things to floor.";
|
||||
description = "Lowers the targeted or selected floors/ceilings to match the height of adjacent sector. Hold Ctrl to lower to lowest surface in selection. Also drops selected things to floor.";
|
||||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
disregardcontrol = true;
|
||||
default = 34; //PgDn
|
||||
}
|
||||
|
||||
|
@ -511,10 +512,11 @@ raisesectortonearest
|
|||
{
|
||||
title = "Raise Floor/Ceiling to adjacent sector";
|
||||
category = "visual";
|
||||
description = "Raises the targeted or selected floors/ceilings to match the height of adjacent sector. Also aligns selected things to ceiling.";
|
||||
description = "Raises the targeted or selected floors/ceilings to match the height of adjacent sector. Hold Ctrl to raise to highest surface in selection. Also aligns selected things to ceiling.";
|
||||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
disregardcontrol = true;
|
||||
default = 33; //PgUp
|
||||
}
|
||||
|
||||
|
@ -672,6 +674,18 @@ texturepaste
|
|||
allowscroll = true;
|
||||
}
|
||||
|
||||
//mxd
|
||||
visualautoalign
|
||||
{
|
||||
title = "Auto-align Textures X and Y";
|
||||
category = "visual";
|
||||
description = "Automatically aligns the neighbouring textures X and Y offsets until another texture is encountered.";
|
||||
allowkeys = true;
|
||||
allowmouse = true;
|
||||
allowscroll = true;
|
||||
default = 131137; //Ctrl-A
|
||||
}
|
||||
|
||||
visualautoalignx
|
||||
{
|
||||
title = "Auto-align Textures X";
|
||||
|
|
|
@ -1632,7 +1632,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
Dictionary<Sector, VisualCeiling> ceilings = new Dictionary<Sector, VisualCeiling>();
|
||||
List<BaseVisualThing> things = new List<BaseVisualThing>();
|
||||
bool undoGroupCreated = false;
|
||||
string alignFailDescription = string.Empty;
|
||||
bool withinSelection = General.Interface.CtrlState;
|
||||
|
||||
//get selection
|
||||
if(selectedobjects.Count == 0) {
|
||||
|
@ -1660,12 +1660,36 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
}
|
||||
|
||||
//check what we have
|
||||
if(floors.Count + ceilings.Count + things.Count == 0) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "No suitable objects found!");
|
||||
PostAction();
|
||||
return;
|
||||
}
|
||||
|
||||
if(withinSelection) {
|
||||
string s = string.Empty;
|
||||
|
||||
if(floors.Count == 1) s = "floors";
|
||||
|
||||
if(ceilings.Count == 1) {
|
||||
if(!string.IsNullOrEmpty(s)) s += " and ";
|
||||
s += "ceilings";
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(s)){
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Can't do: at least 2 selected " + s + " are required!");
|
||||
PostAction();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//process floors...
|
||||
int maxSelectedHeight = int.MinValue;
|
||||
int minSelectedCeilingHeight = int.MaxValue;
|
||||
int targetHeight = int.MaxValue;
|
||||
int targetFloorHeight = int.MaxValue;
|
||||
|
||||
//get maximum floor height from selection
|
||||
//get maximum floor and minimum ceiling heights from selection
|
||||
foreach(KeyValuePair<Sector, VisualFloor> group in floors) {
|
||||
if(group.Key.FloorHeight > maxSelectedHeight)
|
||||
maxSelectedHeight = group.Key.FloorHeight;
|
||||
|
@ -1674,32 +1698,30 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
minSelectedCeilingHeight = group.Key.CeilHeight;
|
||||
}
|
||||
|
||||
//get next higher floor from surrounding unselected sectors
|
||||
foreach(KeyValuePair<Sector, VisualFloor> group in floors) {
|
||||
foreach(Sidedef side in group.Key.Sidedefs) {
|
||||
if(side.Other == null || ceilings.ContainsKey(side.Other.Sector) || floors.ContainsKey(side.Other.Sector))
|
||||
continue;
|
||||
if(side.Other.Sector.FloorHeight > maxSelectedHeight && side.Other.Sector.FloorHeight < targetHeight && side.Other.Sector.FloorHeight <= minSelectedCeilingHeight)
|
||||
targetHeight = side.Other.Sector.FloorHeight;
|
||||
if(withinSelection) {
|
||||
//check heights
|
||||
if(minSelectedCeilingHeight < maxSelectedHeight) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Can't do: lowest ceiling is lower than highest floor!");
|
||||
PostAction();
|
||||
return;
|
||||
} else {
|
||||
targetFloorHeight = maxSelectedHeight;
|
||||
}
|
||||
}
|
||||
|
||||
//change floor height
|
||||
if(targetHeight != int.MaxValue) {
|
||||
PreAction(UndoGroup.SectorHeightChange);
|
||||
undoGroupCreated = true;
|
||||
|
||||
} else {
|
||||
//get next higher floor from surrounding unselected sectors
|
||||
foreach(KeyValuePair<Sector, VisualFloor> group in floors) {
|
||||
if(targetHeight != group.Key.FloorHeight)
|
||||
group.Value.OnChangeTargetHeight(targetHeight - group.Key.FloorHeight);
|
||||
foreach(Sidedef side in group.Key.Sidedefs) {
|
||||
if(side.Other == null || ceilings.ContainsKey(side.Other.Sector) || floors.ContainsKey(side.Other.Sector))
|
||||
continue;
|
||||
if(side.Other.Sector.FloorHeight > maxSelectedHeight && side.Other.Sector.FloorHeight < targetFloorHeight && side.Other.Sector.FloorHeight <= minSelectedCeilingHeight)
|
||||
targetFloorHeight = side.Other.Sector.FloorHeight;
|
||||
}
|
||||
}
|
||||
} else if(floors.Count > 0) {
|
||||
alignFailDescription = floors.Count > 1 ? "floors" : "floor";
|
||||
}
|
||||
|
||||
//ceilings...
|
||||
maxSelectedHeight = int.MinValue;
|
||||
targetHeight = int.MaxValue;
|
||||
int targetCeilingHeight = int.MaxValue;
|
||||
|
||||
//get highest ceiling height from selection
|
||||
foreach(KeyValuePair<Sector, VisualCeiling> group in ceilings) {
|
||||
|
@ -1707,32 +1729,63 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
maxSelectedHeight = group.Key.CeilHeight;
|
||||
}
|
||||
|
||||
//get next higher ceiling from surrounding unselected sectors
|
||||
foreach(KeyValuePair<Sector, VisualCeiling> group in ceilings) {
|
||||
foreach(Sidedef side in group.Key.Sidedefs) {
|
||||
if(side.Other == null || ceilings.ContainsKey(side.Other.Sector) || floors.ContainsKey(side.Other.Sector))
|
||||
continue;
|
||||
if(side.Other.Sector.CeilHeight < targetHeight && side.Other.Sector.CeilHeight > maxSelectedHeight)
|
||||
targetHeight = side.Other.Sector.CeilHeight;
|
||||
if(withinSelection) {
|
||||
//we are raising, so we don't need to check anything
|
||||
targetCeilingHeight = maxSelectedHeight;
|
||||
} else {
|
||||
//get next higher ceiling from surrounding unselected sectors
|
||||
foreach(KeyValuePair<Sector, VisualCeiling> group in ceilings) {
|
||||
foreach(Sidedef side in group.Key.Sidedefs) {
|
||||
if(side.Other == null || ceilings.ContainsKey(side.Other.Sector) || floors.ContainsKey(side.Other.Sector))
|
||||
continue;
|
||||
if(side.Other.Sector.CeilHeight < targetCeilingHeight && side.Other.Sector.CeilHeight > maxSelectedHeight)
|
||||
targetCeilingHeight = side.Other.Sector.CeilHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//change ceiling height
|
||||
if(targetHeight != int.MaxValue) {
|
||||
//CHECK VALUES
|
||||
string alignFailDescription = string.Empty;
|
||||
|
||||
if(floors.Count > 0 && targetFloorHeight == int.MaxValue)
|
||||
alignFailDescription = floors.Count > 1 ? "floors" : "floor";
|
||||
|
||||
if(ceilings.Count > 0 && targetCeilingHeight == int.MaxValue) {
|
||||
if(!string.IsNullOrEmpty(alignFailDescription))
|
||||
alignFailDescription += " and ";
|
||||
|
||||
alignFailDescription += ceilings.Count > 1 ? "ceilings" : "ceiling";
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(alignFailDescription)) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Unable to align selected " + alignFailDescription + "!");
|
||||
PostAction();
|
||||
return;
|
||||
}
|
||||
|
||||
//APPLY VALUES
|
||||
//change floors heights
|
||||
if(floors.Count > 0) {
|
||||
PreAction(UndoGroup.SectorHeightChange);
|
||||
undoGroupCreated = true;
|
||||
|
||||
foreach(KeyValuePair<Sector, VisualFloor> group in floors) {
|
||||
if(targetFloorHeight != group.Key.FloorHeight)
|
||||
group.Value.OnChangeTargetHeight(targetFloorHeight - group.Key.FloorHeight);
|
||||
}
|
||||
}
|
||||
|
||||
//change ceilings heights
|
||||
if(ceilings.Count > 0) {
|
||||
if(!undoGroupCreated) {
|
||||
PreAction(UndoGroup.SectorHeightChange);
|
||||
undoGroupCreated = true;
|
||||
}
|
||||
|
||||
foreach(KeyValuePair<Sector, VisualCeiling> group in ceilings) {
|
||||
if(targetHeight != group.Key.CeilHeight)
|
||||
group.Value.OnChangeTargetHeight(targetHeight - group.Key.CeilHeight);
|
||||
if(targetCeilingHeight != group.Key.CeilHeight)
|
||||
group.Value.OnChangeTargetHeight(targetCeilingHeight - group.Key.CeilHeight);
|
||||
}
|
||||
} else if(ceilings.Count > 0) {
|
||||
if(!string.IsNullOrEmpty(alignFailDescription))
|
||||
alignFailDescription += " and ";
|
||||
|
||||
alignFailDescription += ceilings.Count > 1 ? "ceilings" : "ceiling";
|
||||
}
|
||||
|
||||
//and things. Just align them to ceiling
|
||||
|
@ -1753,9 +1806,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(alignFailDescription))
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Unable to align selected " + alignFailDescription + "!");
|
||||
|
||||
PostAction();
|
||||
}
|
||||
|
||||
|
@ -1766,7 +1816,7 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
Dictionary<Sector, VisualCeiling> ceilings = new Dictionary<Sector, VisualCeiling>();
|
||||
List<BaseVisualThing> things = new List<BaseVisualThing>();
|
||||
bool undoGroupCreated = false;
|
||||
string alignFailDescription = string.Empty;
|
||||
bool withinSelection = General.Interface.CtrlState;
|
||||
|
||||
//get selection
|
||||
if(selectedobjects.Count == 0) {
|
||||
|
@ -1794,43 +1844,59 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
}
|
||||
|
||||
//check what we have
|
||||
if(floors.Count + ceilings.Count + things.Count == 0) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "No suitable objects found!");
|
||||
PostAction();
|
||||
return;
|
||||
}
|
||||
|
||||
if(withinSelection) {
|
||||
string s = string.Empty;
|
||||
|
||||
if(floors.Count == 1) s = "floors";
|
||||
|
||||
if(ceilings.Count == 1) {
|
||||
if(!string.IsNullOrEmpty(s)) s += " and ";
|
||||
s += "ceilings";
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(s)) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Can't do: at least 2 selected " + s + " are required!");
|
||||
PostAction();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//process floors...
|
||||
int minSelectedHeight = int.MaxValue;
|
||||
int targetHeight = int.MinValue;
|
||||
int targetFloorHeight = int.MinValue;
|
||||
|
||||
//get minimum floor height from selection
|
||||
foreach(KeyValuePair<Sector, VisualFloor> group in floors) {
|
||||
if(group.Key.FloorHeight < minSelectedHeight)
|
||||
minSelectedHeight = group.Key.FloorHeight;
|
||||
}
|
||||
|
||||
//get next floor lower height from surrounding unselected sectors
|
||||
foreach(KeyValuePair<Sector, VisualFloor> group in floors){
|
||||
foreach(Sidedef side in group.Key.Sidedefs) {
|
||||
if(side.Other == null || ceilings.ContainsKey(side.Other.Sector) || floors.ContainsKey(side.Other.Sector))
|
||||
continue;
|
||||
if(side.Other.Sector.FloorHeight > targetHeight && side.Other.Sector.FloorHeight < minSelectedHeight)
|
||||
targetHeight = side.Other.Sector.FloorHeight;
|
||||
}
|
||||
}
|
||||
|
||||
//change floor height
|
||||
if(targetHeight != int.MinValue) {
|
||||
PreAction(UndoGroup.SectorHeightChange);
|
||||
undoGroupCreated = true;
|
||||
|
||||
|
||||
if(withinSelection) {
|
||||
//we are lowering, so we don't need to check anything
|
||||
targetFloorHeight = minSelectedHeight;
|
||||
} else {
|
||||
//get next floor lower height from surrounding unselected sectors
|
||||
foreach(KeyValuePair<Sector, VisualFloor> group in floors) {
|
||||
if(targetHeight != group.Key.FloorHeight)
|
||||
group.Value.OnChangeTargetHeight(targetHeight - group.Key.FloorHeight);
|
||||
foreach(Sidedef side in group.Key.Sidedefs) {
|
||||
if(side.Other == null || ceilings.ContainsKey(side.Other.Sector) || floors.ContainsKey(side.Other.Sector))
|
||||
continue;
|
||||
if(side.Other.Sector.FloorHeight > targetFloorHeight && side.Other.Sector.FloorHeight < minSelectedHeight)
|
||||
targetFloorHeight = side.Other.Sector.FloorHeight;
|
||||
}
|
||||
}
|
||||
} else if(floors.Count > 0) {
|
||||
alignFailDescription = floors.Count > 1 ? "floors" : "floor";
|
||||
}
|
||||
|
||||
//ceilings...
|
||||
minSelectedHeight = int.MaxValue;
|
||||
int maxSelectedFloorHeight = int.MinValue;
|
||||
targetHeight = int.MinValue;
|
||||
int targetCeilingHeight = int.MinValue;
|
||||
|
||||
//get minimum ceiling and maximum floor heights from selection
|
||||
foreach(KeyValuePair<Sector, VisualCeiling> group in ceilings) {
|
||||
|
@ -1841,35 +1907,71 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
maxSelectedFloorHeight = group.Key.FloorHeight;
|
||||
}
|
||||
|
||||
//get next lower ceiling height from surrounding unselected sectors
|
||||
foreach(KeyValuePair<Sector, VisualCeiling> group in ceilings) {
|
||||
foreach(Sidedef side in group.Key.Sidedefs) {
|
||||
if(side.Other == null || ceilings.ContainsKey(side.Other.Sector) || floors.ContainsKey(side.Other.Sector))
|
||||
continue;
|
||||
if(side.Other.Sector.CeilHeight > targetHeight && side.Other.Sector.CeilHeight < minSelectedHeight && side.Other.Sector.CeilHeight >= maxSelectedFloorHeight)
|
||||
targetHeight = side.Other.Sector.CeilHeight;
|
||||
if(withinSelection) {
|
||||
if(minSelectedHeight < maxSelectedFloorHeight) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Can't do: lowest ceiling is lower than highest floor!");
|
||||
PostAction();
|
||||
return;
|
||||
} else {
|
||||
targetCeilingHeight = minSelectedHeight;
|
||||
}
|
||||
} else {
|
||||
//get next lower ceiling height from surrounding unselected sectors
|
||||
foreach(KeyValuePair<Sector, VisualCeiling> group in ceilings) {
|
||||
foreach(Sidedef side in group.Key.Sidedefs) {
|
||||
if(side.Other == null || ceilings.ContainsKey(side.Other.Sector) || floors.ContainsKey(side.Other.Sector))
|
||||
continue;
|
||||
if(side.Other.Sector.CeilHeight > targetCeilingHeight && side.Other.Sector.CeilHeight < minSelectedHeight && side.Other.Sector.CeilHeight >= maxSelectedFloorHeight)
|
||||
targetCeilingHeight = side.Other.Sector.CeilHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//change ceiling height
|
||||
if(targetHeight != int.MinValue) {
|
||||
if(!undoGroupCreated) {
|
||||
PreAction(UndoGroup.SectorHeightChange);
|
||||
undoGroupCreated = true;
|
||||
}
|
||||
//CHECK VALUES:
|
||||
string alignFailDescription = string.Empty;
|
||||
|
||||
foreach(KeyValuePair<Sector, VisualCeiling> group in ceilings) {
|
||||
if(targetHeight != group.Key.CeilHeight)
|
||||
group.Value.OnChangeTargetHeight(targetHeight - group.Key.CeilHeight);
|
||||
}
|
||||
} else if(ceilings.Count > 0) {
|
||||
if(floors.Count > 0 && targetFloorHeight == int.MinValue)
|
||||
alignFailDescription = floors.Count > 1 ? "floors" : "floor";
|
||||
|
||||
if(ceilings.Count > 0 && targetCeilingHeight == int.MinValue) {
|
||||
if(!string.IsNullOrEmpty(alignFailDescription))
|
||||
alignFailDescription += " and ";
|
||||
|
||||
alignFailDescription += ceilings.Count > 1 ? "ceilings" : "ceiling";
|
||||
}
|
||||
|
||||
//and things. Just drop them to ground
|
||||
if(!string.IsNullOrEmpty(alignFailDescription)) {
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Unable to align selected " + alignFailDescription + "!");
|
||||
PostAction();
|
||||
return;
|
||||
}
|
||||
|
||||
//APPLY VALUES:
|
||||
//change floor height
|
||||
if(floors.Count > 0) {
|
||||
PreAction(UndoGroup.SectorHeightChange);
|
||||
undoGroupCreated = true;
|
||||
|
||||
foreach(KeyValuePair<Sector, VisualFloor> group in floors) {
|
||||
if(targetFloorHeight != group.Key.FloorHeight)
|
||||
group.Value.OnChangeTargetHeight(targetFloorHeight - group.Key.FloorHeight);
|
||||
}
|
||||
}
|
||||
|
||||
//change ceiling height
|
||||
if(ceilings.Count > 0) {
|
||||
if(!undoGroupCreated) {
|
||||
PreAction(UndoGroup.SectorHeightChange);
|
||||
undoGroupCreated = true;
|
||||
}
|
||||
|
||||
foreach(KeyValuePair<Sector, VisualCeiling> group in ceilings) {
|
||||
if(targetCeilingHeight != group.Key.CeilHeight)
|
||||
group.Value.OnChangeTargetHeight(targetCeilingHeight - group.Key.CeilHeight);
|
||||
}
|
||||
}
|
||||
|
||||
//process things. Just drop them to ground
|
||||
if(General.Map.FormatInterface.HasThingHeight){
|
||||
foreach(BaseVisualThing vt in things) {
|
||||
if(vt.Thing.Sector == null) continue;
|
||||
|
@ -1886,9 +1988,6 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
}
|
||||
}
|
||||
|
||||
if(!string.IsNullOrEmpty(alignFailDescription))
|
||||
General.Interface.DisplayStatus(StatusType.Warning, "Unable to align selected " + alignFailDescription + "!");
|
||||
|
||||
PostAction();
|
||||
}
|
||||
|
||||
|
@ -2018,6 +2117,18 @@ namespace CodeImp.DoomBuilder.BuilderModes
|
|||
PostAction();
|
||||
}
|
||||
|
||||
//mxd
|
||||
[BeginAction("visualautoalign")]
|
||||
public void TextureAutoAlign() {
|
||||
PreAction(UndoGroup.None);
|
||||
renderer.SetCrosshairBusy(true);
|
||||
General.Interface.RedrawDisplay();
|
||||
GetTargetEventReceiver(false).OnTextureAlign(true, true);
|
||||
UpdateChangedObjects();
|
||||
renderer.SetCrosshairBusy(false);
|
||||
PostAction();
|
||||
}
|
||||
|
||||
[BeginAction("visualautoalignx")]
|
||||
public void TextureAutoAlignX()
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue