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:
MaxED 2013-04-04 10:14:44 +00:00
parent b104e88a1d
commit d582d9b9a1
5 changed files with 323 additions and 100 deletions

View file

@ -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;
}
}

View file

@ -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

View file

@ -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>

View file

@ -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";

View file

@ -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()
{