2009-04-19 18:07:22 +00:00
#region = = = = = = = = = = = = = = = = = = Copyright ( c ) 2007 Pascal vd Heiden
/ *
* Copyright ( c ) 2007 Pascal vd Heiden , www . codeimp . com
* This program is released under GNU General Public License
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* /
#endregion
#region = = = = = = = = = = = = = = = = = = Namespaces
using System ;
using System.Collections.Generic ;
using System.Drawing ;
2015-06-24 21:21:19 +00:00
using System.Windows.Forms ;
2009-04-19 18:07:22 +00:00
using CodeImp.DoomBuilder.Actions ;
using CodeImp.DoomBuilder.BuilderModes.Interface ;
2013-09-12 15:02:08 +00:00
using CodeImp.DoomBuilder.Config ;
2015-06-24 21:21:19 +00:00
using CodeImp.DoomBuilder.Editing ;
using CodeImp.DoomBuilder.Geometry ;
using CodeImp.DoomBuilder.GZBuilder.Geometry ;
using CodeImp.DoomBuilder.GZBuilder.Tools ;
using CodeImp.DoomBuilder.Map ;
using CodeImp.DoomBuilder.Rendering ;
using CodeImp.DoomBuilder.Types ;
using CodeImp.DoomBuilder.Windows ;
2009-04-19 18:07:22 +00:00
#endregion
namespace CodeImp.DoomBuilder.BuilderModes
{
[ EditMode ( DisplayName = "Sectors Mode" ,
SwitchAction = "sectorsmode" , // Action name used to switch to this mode
2013-09-11 09:47:53 +00:00
ButtonImage = "SectorsMode.png" , // Image resource name for the button
2009-04-19 18:07:22 +00:00
ButtonOrder = int . MinValue + 200 , // Position of the button (lower is more to the left)
ButtonGroup = "000_editing" ,
2009-07-09 15:15:49 +00:00
UseByDefault = true ,
SafeStartMode = true ) ]
2009-04-19 18:07:22 +00:00
public class SectorsMode : BaseClassicMode
{
#region = = = = = = = = = = = = = = = = = = Constants
#endregion
#region = = = = = = = = = = = = = = = = = = Variables
// Highlighted item
protected Sector highlighted ;
private Association highlightasso = new Association ( ) ;
// Interface
protected bool editpressed ;
// Labels
private Dictionary < Sector , TextLabel [ ] > labels ;
2013-09-12 15:02:08 +00:00
//mxd. Effects
2014-09-12 12:19:58 +00:00
private readonly Dictionary < int , string [ ] > effects ;
2009-04-19 18:07:22 +00:00
2013-12-10 12:19:27 +00:00
//mxd. Cached overlays stuff
private FlatVertex [ ] overlayGeometry ;
private Dictionary < Sector , string [ ] > selectedEffectLabels ;
private Dictionary < Sector , string [ ] > unselectedEffectLabels ;
2014-03-06 09:08:21 +00:00
//mxd. "Make Door" textures
private static string doortex = "-" ;
private static string tracktex = "-" ;
2014-09-12 12:19:58 +00:00
private static bool resetoffsets = true ;
2014-03-06 09:08:21 +00:00
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Properties
2009-05-17 14:00:36 +00:00
public override object HighlightedObject { get { return highlighted ; } }
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Constructor / Disposer
// Constructor
public SectorsMode ( )
{
2013-09-12 15:02:08 +00:00
//mxd
effects = new Dictionary < int , string [ ] > ( ) ;
2014-12-03 23:15:26 +00:00
foreach ( SectorEffectInfo info in General . Map . Config . SortedSectorEffects )
{
2013-09-12 15:40:15 +00:00
string name = info . Index + ": " + info . Title ;
effects . Add ( info . Index , new [ ] { name , "E" + info . Index } ) ;
2013-09-12 15:02:08 +00:00
}
2009-04-19 18:07:22 +00:00
}
// Disposer
public override void Dispose ( )
{
// Not already disposed?
if ( ! isdisposed )
{
// Dispose old labels
foreach ( KeyValuePair < Sector , TextLabel [ ] > lbl in labels )
foreach ( TextLabel l in lbl . Value ) l . Dispose ( ) ;
// Dispose base
base . Dispose ( ) ;
}
}
#endregion
#region = = = = = = = = = = = = = = = = = = Methods
// This makes a CRC for the selection
public int CreateSelectionCRC ( )
{
CRC crc = new CRC ( ) ;
ICollection < Sector > orderedselection = General . Map . Map . GetSelectedSectors ( true ) ;
crc . Add ( orderedselection . Count ) ;
foreach ( Sector s in orderedselection )
{
crc . Add ( s . FixedIndex ) ;
}
return ( int ) ( crc . Value & 0xFFFFFFFF ) ;
}
2014-04-02 10:57:52 +00:00
//mxd. This makes a CRC for given selection
2014-12-03 23:15:26 +00:00
private static int CreateSelectionCRC ( ICollection < Sector > selection )
{
2014-04-02 10:57:52 +00:00
CRC crc = new CRC ( ) ;
crc . Add ( selection . Count ) ;
2014-12-03 23:15:26 +00:00
foreach ( Sector s in selection ) crc . Add ( s . FixedIndex ) ;
2014-04-02 10:57:52 +00:00
return ( int ) ( crc . Value & 0xFFFFFFFF ) ;
}
2009-04-19 18:07:22 +00:00
// This sets up new labels
private void SetupLabels ( )
{
if ( labels ! = null )
{
// Dispose old labels
foreach ( KeyValuePair < Sector , TextLabel [ ] > lbl in labels )
foreach ( TextLabel l in lbl . Value ) l . Dispose ( ) ;
}
// Make text labels for sectors
labels = new Dictionary < Sector , TextLabel [ ] > ( General . Map . Map . Sectors . Count ) ;
foreach ( Sector s in General . Map . Map . Sectors )
{
// Setup labels
TextLabel [ ] labelarray = new TextLabel [ s . Labels . Count ] ;
for ( int i = 0 ; i < s . Labels . Count ; i + + )
{
Vector2D v = s . Labels [ i ] . position ;
2013-09-13 14:54:43 +00:00
labelarray [ i ] = new TextLabel ( 20 ) ;
2009-04-19 18:07:22 +00:00
labelarray [ i ] . TransformCoords = true ;
labelarray [ i ] . Rectangle = new RectangleF ( v . x , v . y , 0.0f , 0.0f ) ;
labelarray [ i ] . AlignX = TextAlignmentX . Center ;
labelarray [ i ] . AlignY = TextAlignmentY . Middle ;
labelarray [ i ] . Scale = 14f ;
labelarray [ i ] . Color = General . Colors . Highlight . WithAlpha ( 255 ) ;
labelarray [ i ] . Backcolor = General . Colors . Background . WithAlpha ( 255 ) ;
}
labels . Add ( s , labelarray ) ;
}
}
// This updates the overlay
private void UpdateOverlay ( )
{
if ( renderer . StartOverlay ( true ) )
{
2013-09-12 15:40:15 +00:00
// Go for all selected sectors
ICollection < Sector > orderedselection = General . Map . Map . GetSelectedSectors ( true ) ;
//mxd. Render selected sectors
2014-12-03 23:15:26 +00:00
if ( BuilderPlug . Me . UseHighlight )
{
2013-12-10 12:19:27 +00:00
renderer . RenderHighlight ( overlayGeometry , General . Colors . Selection . WithAlpha ( 64 ) . ToInt ( ) ) ;
}
//mxd. Render highlighted sector
2014-12-03 23:15:26 +00:00
if ( BuilderPlug . Me . UseHighlight & & highlighted ! = null )
{
2013-12-10 12:19:27 +00:00
renderer . RenderHighlight ( highlighted . FlatVertices , General . Colors . Highlight . WithAlpha ( 64 ) . ToInt ( ) ) ;
2013-09-12 15:40:15 +00:00
}
2014-12-03 23:15:26 +00:00
if ( BuilderPlug . Me . ViewSelectionNumbers )
{
foreach ( Sector s in orderedselection )
{
2009-04-19 18:07:22 +00:00
// Render labels
TextLabel [ ] labelarray = labels [ s ] ;
2014-12-03 23:15:26 +00:00
for ( int i = 0 ; i < s . Labels . Count ; i + + )
{
2009-04-19 18:07:22 +00:00
TextLabel l = labelarray [ i ] ;
// Render only when enough space for the label to see
float requiredsize = ( l . TextSize . Height / 2 ) / renderer . Scale ;
2013-09-16 11:44:47 +00:00
if ( requiredsize < s . Labels [ i ] . radius ) renderer . RenderText ( l ) ;
2009-04-19 18:07:22 +00:00
}
}
2013-09-16 11:44:47 +00:00
}
2013-09-12 15:02:08 +00:00
2013-12-10 12:19:27 +00:00
//mxd. Render effect labels
2014-12-03 23:15:26 +00:00
if ( BuilderPlug . Me . ViewSelectionEffects )
{
if ( ! BuilderPlug . Me . ViewSelectionNumbers ) RenderEffectLabels ( selectedEffectLabels ) ;
RenderEffectLabels ( unselectedEffectLabels ) ;
2013-09-16 11:44:47 +00:00
}
2015-07-14 23:34:31 +00:00
//mxd. Render comments
if ( General . Map . UDMF & & General . Settings . RenderComments ) foreach ( Sector s in General . Map . Map . Sectors ) RenderComment ( s ) ;
2013-09-16 11:44:47 +00:00
renderer . Finish ( ) ;
}
}
//mxd
2014-12-03 23:15:26 +00:00
private void RenderEffectLabels ( Dictionary < Sector , string [ ] > labelsGroup )
{
foreach ( KeyValuePair < Sector , string [ ] > group in labelsGroup )
{
2013-12-10 12:19:27 +00:00
// Render labels
TextLabel [ ] labelarray = labels [ group . Key ] ;
2014-12-03 23:15:26 +00:00
for ( int i = 0 ; i < group . Key . Labels . Count ; i + + )
{
2013-09-16 11:44:47 +00:00
TextLabel l = labelarray [ i ] ;
l . Color = General . Colors . InfoLine ;
2013-12-10 12:19:27 +00:00
// Render only when enough space for the label to see
float requiredsize = ( General . Map . GetTextSize ( group . Value [ 0 ] , l . Scale ) . Width ) / renderer . Scale ;
2014-12-03 23:15:26 +00:00
if ( requiredsize > group . Key . Labels [ i ] . radius )
{
2013-12-10 12:19:27 +00:00
requiredsize = ( General . Map . GetTextSize ( group . Value [ 1 ] , l . Scale ) . Width ) / renderer . Scale ;
l . Text = ( requiredsize > group . Key . Labels [ i ] . radius ? "+" : group . Value [ 1 ] ) ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-12-10 12:19:27 +00:00
l . Text = group . Value [ 0 ] ;
2013-09-12 15:02:08 +00:00
}
2013-09-16 11:44:47 +00:00
renderer . RenderText ( l ) ;
2009-04-19 18:07:22 +00:00
}
}
}
2013-12-10 12:19:27 +00:00
//mxd
2014-12-03 23:15:26 +00:00
private string [ ] GetEffectText ( Sector s )
{
2013-12-10 12:19:27 +00:00
string [ ] result = new [ ] { string . Empty , string . Empty } ;
2014-12-03 23:15:26 +00:00
if ( s . Effect ! = 0 )
{
if ( effects . ContainsKey ( s . Effect ) )
{
if ( s . Tag ! = 0 )
{
2013-12-10 12:19:27 +00:00
result [ 0 ] = "Tag " + s . Tag + ", " + effects [ s . Effect ] [ 0 ] ;
result [ 1 ] = "T" + s . Tag + " " + "E" + s . Effect ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-12-10 12:19:27 +00:00
result [ 0 ] = effects [ s . Effect ] [ 0 ] ;
result [ 1 ] = "E" + s . Effect ;
}
2014-12-03 23:15:26 +00:00
}
else
{
2014-09-04 12:34:26 +00:00
string effect = s . Effect + " - " + General . Map . Config . GetGeneralizedSectorEffectName ( s . Effect ) ;
2014-12-03 23:15:26 +00:00
if ( s . Tag ! = 0 )
{
2014-09-04 12:34:26 +00:00
result [ 0 ] = "Tag " + s . Tag + ", Effect " + effect ;
2013-12-10 12:19:27 +00:00
result [ 1 ] = "T" + s . Tag + " " + "E" + s . Effect ;
2014-12-03 23:15:26 +00:00
}
else
{
2014-09-04 12:34:26 +00:00
result [ 0 ] = "Effect " + effect ;
2013-12-10 12:19:27 +00:00
result [ 1 ] = "E" + s . Effect ;
}
}
2014-12-03 23:15:26 +00:00
}
else if ( s . Tag ! = 0 )
{
2013-12-10 12:19:27 +00:00
result [ 0 ] = "Tag " + s . Tag ;
result [ 1 ] = "T" + s . Tag ;
}
return result ;
}
//mxd
2014-12-03 23:15:26 +00:00
private void UpdateOverlaySurfaces ( )
{
2013-12-10 12:19:27 +00:00
ICollection < Sector > orderedselection = General . Map . Map . GetSelectedSectors ( true ) ;
List < FlatVertex > vertsList = new List < FlatVertex > ( ) ;
// Go for all selected sectors
foreach ( Sector s in orderedselection ) vertsList . AddRange ( s . FlatVertices ) ;
overlayGeometry = vertsList . ToArray ( ) ;
}
//mxd
2014-12-03 23:15:26 +00:00
private void UpdateEffectLabels ( )
{
2013-12-10 12:19:27 +00:00
selectedEffectLabels = new Dictionary < Sector , string [ ] > ( ) ;
unselectedEffectLabels = new Dictionary < Sector , string [ ] > ( ) ;
//update effect labels for selected sectors
ICollection < Sector > orderedselection = General . Map . Map . GetSelectedSectors ( true ) ;
2014-12-03 23:15:26 +00:00
foreach ( Sector s in orderedselection )
{
string [ ] labelText = GetEffectText ( s ) ;
2013-12-10 12:19:27 +00:00
if ( ! string . IsNullOrEmpty ( labelText [ 0 ] ) )
selectedEffectLabels . Add ( s , labelText ) ;
}
//update effect labels for unselected sectors
orderedselection = General . Map . Map . GetSelectedSectors ( false ) ;
2014-12-03 23:15:26 +00:00
foreach ( Sector s in orderedselection )
{
string [ ] labelText = GetEffectText ( s ) ;
2013-12-10 12:19:27 +00:00
if ( ! string . IsNullOrEmpty ( labelText [ 0 ] ) )
unselectedEffectLabels . Add ( s , labelText ) ;
}
}
2009-04-19 18:07:22 +00:00
// Support function for joining and merging sectors
private void JoinMergeSectors ( bool removelines )
{
// Remove lines in betwen joining sectors?
if ( removelines )
{
// Go for all selected linedefs
List < Linedef > selectedlines = new List < Linedef > ( General . Map . Map . GetSelectedLinedefs ( true ) ) ;
foreach ( Linedef ld in selectedlines )
{
// Front and back side?
if ( ( ld . Front ! = null ) & & ( ld . Back ! = null ) )
{
// Both a selected sector, but not the same?
if ( ld . Front . Sector . Selected & & ld . Back . Sector . Selected & &
( ld . Front . Sector ! = ld . Back . Sector ) )
{
// Remove this line
ld . Dispose ( ) ;
}
}
}
}
// Find the first sector that is not disposed
List < Sector > orderedselection = new List < Sector > ( General . Map . Map . GetSelectedSectors ( true ) ) ;
Sector first = null ;
foreach ( Sector s in orderedselection )
if ( ! s . IsDisposed ) { first = s ; break ; }
// Join all selected sectors with the first
for ( int i = 0 ; i < orderedselection . Count ; i + + )
if ( ( orderedselection [ i ] ! = first ) & & ! orderedselection [ i ] . IsDisposed )
orderedselection [ i ] . Join ( first ) ;
// Clear selection
General . Map . Map . ClearAllSelected ( ) ;
// Update
General . Map . Map . Update ( ) ;
// Make text labels for sectors
SetupLabels ( ) ;
UpdateSelectedLabels ( ) ;
}
// This highlights a new item
protected void Highlight ( Sector s )
{
// Often we can get away by simply undrawing the previous
// highlight and drawing the new highlight. But if associations
// are or were drawn we need to redraw the entire display.
// Previous association highlights something?
2013-09-11 13:14:45 +00:00
bool completeredraw = ( highlighted ! = null ) & & ( highlighted . Tag > 0 ) ;
2009-04-19 18:07:22 +00:00
// Set highlight association
2014-12-03 23:15:26 +00:00
if ( s ! = null )
{
2013-09-11 13:57:27 +00:00
Vector2D center = ( s . Labels . Count > 0 ? s . Labels [ 0 ] . position : new Vector2D ( s . BBox . X + s . BBox . Width / 2 , s . BBox . Y + s . BBox . Height / 2 ) ) ;
highlightasso . Set ( center , s . Tag , UniversalType . SectorTag ) ;
2014-12-03 23:15:26 +00:00
}
else
{
2012-09-17 21:57:08 +00:00
highlightasso . Set ( new Vector2D ( ) , 0 , 0 ) ;
2013-09-11 13:57:27 +00:00
}
2009-04-19 18:07:22 +00:00
// New association highlights something?
if ( ( s ! = null ) & & ( s . Tag > 0 ) ) completeredraw = true ;
// Change label color
if ( ( highlighted ! = null ) & & ! highlighted . IsDisposed )
{
TextLabel [ ] labelarray = labels [ highlighted ] ;
foreach ( TextLabel l in labelarray ) l . Color = General . Colors . Selection ;
}
// Change label color
if ( ( s ! = null ) & & ! s . IsDisposed )
{
TextLabel [ ] labelarray = labels [ s ] ;
foreach ( TextLabel l in labelarray ) l . Color = General . Colors . Highlight ;
}
// If we're changing associations, then we
// need to redraw the entire display
if ( completeredraw )
{
// Set new highlight and redraw completely
highlighted = s ;
General . Interface . RedrawDisplay ( ) ;
}
else
{
// Update display
2015-07-14 23:34:31 +00:00
Sector possiblecommentsector = s ? ? highlighted ; //mxd
2009-04-19 18:07:22 +00:00
if ( renderer . StartPlotter ( false ) )
{
// Undraw previous highlight
if ( ( highlighted ! = null ) & & ! highlighted . IsDisposed )
renderer . PlotSector ( highlighted ) ;
// Set new highlight
highlighted = s ;
// Render highlighted item
if ( ( highlighted ! = null ) & & ! highlighted . IsDisposed )
renderer . PlotSector ( highlighted , General . Colors . Highlight ) ;
2015-07-14 23:34:31 +00:00
2009-04-19 18:07:22 +00:00
// Done
renderer . Finish ( ) ;
}
UpdateOverlay ( ) ;
2015-07-14 23:34:31 +00:00
//mxd. Update comment highlight?
if ( General . Map . UDMF & & General . Settings . RenderComments
& & possiblecommentsector ! = null & & ! possiblecommentsector . IsDisposed
& & renderer . StartOverlay ( false ) )
{
RenderComment ( possiblecommentsector ) ;
renderer . Finish ( ) ;
}
2009-04-19 18:07:22 +00:00
renderer . Present ( ) ;
}
// Show highlight info
if ( ( highlighted ! = null ) & & ! highlighted . IsDisposed )
2015-07-14 09:02:48 +00:00
{
2009-04-19 18:07:22 +00:00
General . Interface . ShowSectorInfo ( highlighted ) ;
2015-07-14 09:02:48 +00:00
}
2009-04-19 18:07:22 +00:00
else
2015-07-14 09:02:48 +00:00
{
General . Interface . Display . HideToolTip ( ) ; //mxd
2009-04-19 18:07:22 +00:00
General . Interface . HideInfo ( ) ;
2015-07-14 09:02:48 +00:00
}
2009-04-19 18:07:22 +00:00
}
// This selectes or deselects a sector
protected void SelectSector ( Sector s , bool selectstate , bool update )
{
bool selectionchanged = false ;
if ( ! s . IsDisposed )
{
// Select the sector?
if ( selectstate & & ! s . Selected )
{
s . Selected = true ;
selectionchanged = true ;
// Setup labels
2014-12-03 23:15:26 +00:00
if ( update )
{
//mxd
2013-12-10 12:19:27 +00:00
string selectedCount = General . Map . Map . SelectedSectorsCount . ToString ( ) ;
TextLabel [ ] labelarray = labels [ s ] ;
2014-12-03 23:15:26 +00:00
foreach ( TextLabel l in labelarray )
{
2013-12-10 13:01:27 +00:00
l . Text = selectedCount ;
2013-12-10 12:19:27 +00:00
l . Color = General . Colors . Selection ;
}
2014-12-03 23:15:26 +00:00
UpdateEffectLabels ( ) ;
2009-04-19 18:07:22 +00:00
}
}
// Deselect the sector?
else if ( ! selectstate & & s . Selected )
{
s . Selected = false ;
selectionchanged = true ;
// Clear labels
2014-12-03 23:15:26 +00:00
if ( update )
{
2013-12-10 12:19:27 +00:00
TextLabel [ ] labelarray = labels [ s ] ;
foreach ( TextLabel l in labelarray ) l . Text = "" ;
2009-04-19 18:07:22 +00:00
2013-12-10 12:19:27 +00:00
// Update all other labels
UpdateSelectedLabels ( ) ;
}
2009-04-19 18:07:22 +00:00
}
// Selection changed?
if ( selectionchanged )
{
// Make update lines selection
foreach ( Sidedef sd in s . Sidedefs )
{
bool front , back ;
if ( sd . Line . Front ! = null ) front = sd . Line . Front . Sector . Selected ; else front = false ;
if ( sd . Line . Back ! = null ) back = sd . Line . Back . Sector . Selected ; else back = false ;
sd . Line . Selected = front | back ;
}
2015-01-10 23:12:19 +00:00
//mxd. Also (de)select things?
if ( General . Interface . AltState )
{
foreach ( Thing t in General . Map . ThingsFilter . VisibleThings )
{
t . DetermineSector ( ) ;
if ( t . Sector ! = s ) continue ;
t . Selected = s . Selected ;
}
}
2013-12-10 12:19:27 +00:00
if ( update )
{
UpdateOverlay ( ) ;
renderer . Present ( ) ;
}
2009-04-19 18:07:22 +00:00
}
}
}
// This updates labels from the selected sectors
private void UpdateSelectedLabels ( )
{
// Go for all labels in all selected sectors
ICollection < Sector > orderedselection = General . Map . Map . GetSelectedSectors ( true ) ;
int index = 0 ;
foreach ( Sector s in orderedselection )
{
TextLabel [ ] labelarray = labels [ s ] ;
foreach ( TextLabel l in labelarray )
{
// Make sure the text and color are right
int labelnum = index + 1 ;
l . Text = labelnum . ToString ( ) ;
l . Color = General . Colors . Selection ;
}
index + + ;
}
2013-12-10 12:19:27 +00:00
//mxd
2014-12-03 23:15:26 +00:00
UpdateEffectLabels ( ) ;
2009-04-19 18:07:22 +00:00
}
2013-11-29 14:45:29 +00:00
//mxd
2014-12-03 23:15:26 +00:00
private bool IsInSelectionRect ( Sector s , List < Line2D > selectionOutline )
{
2013-12-11 08:47:11 +00:00
if ( selectionrect . Contains ( s . BBox ) ) return true ;
2013-12-10 12:19:27 +00:00
2014-12-03 23:15:26 +00:00
if ( BuilderPlug . Me . MarqueSelectTouching & & s . BBox . IntersectsWith ( selectionrect ) )
{
2013-11-29 14:45:29 +00:00
//check endpoints
2014-12-03 23:15:26 +00:00
foreach ( Sidedef side in s . Sidedefs )
{
2013-12-10 12:19:27 +00:00
if ( ( selectionrect . Contains ( side . Line . Start . Position . x , side . Line . Start . Position . y )
| | selectionrect . Contains ( side . Line . End . Position . x , side . Line . End . Position . y ) ) )
return true ;
2013-11-29 14:45:29 +00:00
}
//check line intersections
2014-12-03 23:15:26 +00:00
foreach ( Sidedef side in s . Sidedefs )
{
foreach ( Line2D line in selectionOutline )
{
if ( Line2D . GetIntersection ( side . Line . Line , line ) ) return true ;
2013-11-29 14:45:29 +00:00
}
}
}
2013-12-10 12:19:27 +00:00
return false ;
2013-11-29 14:45:29 +00:00
}
2014-01-13 12:49:54 +00:00
//mxd
2014-12-03 23:15:26 +00:00
public override void SelectMapElement ( SelectableElement element )
{
if ( element is Sector )
{
2014-01-13 12:49:54 +00:00
SelectSector ( element as Sector , true , true ) ;
// Update overlay
2014-12-03 23:15:26 +00:00
UpdateOverlaySurfaces ( ) ;
2014-05-08 09:24:32 +00:00
UpdateSelectionInfo ( ) ;
2014-01-13 12:49:54 +00:00
}
}
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Events
public override void OnHelp ( )
{
General . ShowHelp ( "e_sectors.html" ) ;
}
// Cancel mode
public override void OnCancel ( )
{
base . OnCancel ( ) ;
// Return to this mode
General . Editing . ChangeMode ( new SectorsMode ( ) ) ;
}
// Mode engages
public override void OnEngage ( )
{
base . OnEngage ( ) ;
renderer . SetPresentation ( Presentation . Standard ) ;
// Add toolbar buttons
2010-08-15 13:45:43 +00:00
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . CopyProperties ) ;
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . PasteProperties ) ;
2014-04-09 10:16:33 +00:00
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . PastePropertiesOptions ) ; //mxd
2010-08-15 13:45:43 +00:00
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . SeparatorCopyPaste ) ;
2009-04-19 18:07:22 +00:00
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . ViewSelectionNumbers ) ;
2013-09-16 11:44:47 +00:00
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . ViewSelectionEffects ) ;
2009-04-19 18:07:22 +00:00
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . SeparatorSectors1 ) ;
2014-02-26 14:11:06 +00:00
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . MakeDoor ) ; //mxd
2015-01-16 21:38:42 +00:00
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . SeparatorSectors2 ) ; //mxd
2009-04-19 18:07:22 +00:00
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . MakeGradientBrightness ) ;
2015-01-16 21:38:42 +00:00
if ( General . Map . UDMF ) General . Interface . AddButton ( BuilderPlug . Me . MenusForm . GradientModeMenu ) ; //mxd
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . GradientInterpolationMenu ) ; //mxd
2009-04-19 18:07:22 +00:00
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . MakeGradientFloors ) ;
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . MakeGradientCeilings ) ;
2015-01-16 21:38:42 +00:00
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . SeparatorSectors3 ) ; //mxd
2013-03-18 13:52:27 +00:00
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . MarqueSelectTouching ) ; //mxd
2014-07-18 15:11:37 +00:00
General . Interface . AddButton ( BuilderPlug . Me . MenusForm . DragThingsInSelectedSectors ) ; //mxd
2013-04-11 09:27:16 +00:00
if ( General . Map . UDMF ) General . Interface . AddButton ( BuilderPlug . Me . MenusForm . TextureOffsetLock , ToolbarSection . Geometry ) ; //mxd
2009-04-19 18:07:22 +00:00
// Convert geometry selection to sectors only
General . Map . Map . ConvertSelection ( SelectionType . Sectors ) ;
// Make text labels for sectors
SetupLabels ( ) ;
// Update
UpdateSelectedLabels ( ) ;
2014-12-03 23:15:26 +00:00
UpdateOverlaySurfaces ( ) ; //mxd
2014-05-08 09:24:32 +00:00
UpdateSelectionInfo ( ) ; //mxd
2009-04-19 18:07:22 +00:00
UpdateOverlay ( ) ;
}
// Mode disengages
public override void OnDisengage ( )
{
base . OnDisengage ( ) ;
// Remove toolbar buttons
2010-08-15 13:45:43 +00:00
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . CopyProperties ) ;
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . PasteProperties ) ;
2014-04-09 10:16:33 +00:00
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . PastePropertiesOptions ) ; //mxd
2010-08-15 13:45:43 +00:00
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . SeparatorCopyPaste ) ;
2009-04-19 18:07:22 +00:00
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . ViewSelectionNumbers ) ;
2013-09-16 11:44:47 +00:00
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . ViewSelectionEffects ) ;
2009-04-19 18:07:22 +00:00
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . SeparatorSectors1 ) ;
2014-02-26 14:11:06 +00:00
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . MakeDoor ) ; //mxd
2015-01-16 21:38:42 +00:00
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . SeparatorSectors2 ) ; //mxd
2009-04-19 18:07:22 +00:00
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . MakeGradientBrightness ) ;
2015-01-16 21:38:42 +00:00
if ( General . Map . UDMF ) General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . GradientModeMenu ) ; //mxd
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . GradientInterpolationMenu ) ; //mxd
2009-04-19 18:07:22 +00:00
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . MakeGradientFloors ) ;
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . MakeGradientCeilings ) ;
2015-01-16 21:38:42 +00:00
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . SeparatorSectors3 ) ; //mxd
2013-03-18 13:52:27 +00:00
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . MarqueSelectTouching ) ; //mxd
2014-07-18 15:11:37 +00:00
General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . DragThingsInSelectedSectors ) ; //mxd
2013-04-11 09:27:16 +00:00
if ( General . Map . UDMF ) General . Interface . RemoveButton ( BuilderPlug . Me . MenusForm . TextureOffsetLock ) ; //mxd
2009-04-19 18:07:22 +00:00
// Keep only sectors selected
General . Map . Map . ClearSelectedLinedefs ( ) ;
// Going to EditSelectionMode?
if ( General . Editing . NewMode is EditSelectionMode )
{
2009-08-19 11:42:20 +00:00
// Not pasting anything?
EditSelectionMode editmode = ( General . Editing . NewMode as EditSelectionMode ) ;
if ( ! editmode . Pasting )
2009-04-19 18:07:22 +00:00
{
2009-08-19 11:42:20 +00:00
// No selection made? But we have a highlight!
if ( ( General . Map . Map . GetSelectedSectors ( true ) . Count = = 0 ) & & ( highlighted ! = null ) )
{
// Make the highlight the selection
SelectSector ( highlighted , true , false ) ;
2013-12-10 12:19:27 +00:00
UpdateSelectedLabels ( ) ; //mxd
2009-08-19 11:42:20 +00:00
}
2009-04-19 18:07:22 +00:00
}
}
2015-07-14 09:02:48 +00:00
// Hide highlight info and tooltip
2009-04-19 18:07:22 +00:00
General . Interface . HideInfo ( ) ;
2015-07-14 09:02:48 +00:00
General . Interface . Display . HideToolTip ( ) ; //mxd
2009-04-19 18:07:22 +00:00
}
// This redraws the display
public override void OnRedrawDisplay ( )
{
renderer . RedrawSurface ( ) ;
2015-06-24 21:21:19 +00:00
List < Line3D > eventlines = new List < Line3D > ( ) ; //mxd
2009-04-19 18:07:22 +00:00
// Render lines and vertices
if ( renderer . StartPlotter ( true ) )
{
renderer . PlotLinedefSet ( General . Map . Map . Linedefs ) ;
renderer . PlotVerticesSet ( General . Map . Map . Vertices ) ;
if ( ( highlighted ! = null ) & & ! highlighted . IsDisposed )
{
renderer . PlotSector ( highlighted , General . Colors . Highlight ) ;
2015-06-24 21:21:19 +00:00
BuilderPlug . PlotReverseAssociations ( renderer , highlightasso , eventlines ) ;
2009-04-19 18:07:22 +00:00
}
renderer . Finish ( ) ;
}
// Render things
if ( renderer . StartThings ( true ) )
{
renderer . RenderThingSet ( General . Map . ThingsFilter . HiddenThings , Presentation . THINGS_HIDDEN_ALPHA ) ;
renderer . RenderThingSet ( General . Map . ThingsFilter . VisibleThings , 1.0f ) ;
renderer . Finish ( ) ;
}
2013-12-03 14:40:40 +00:00
// Render overlay
UpdateOverlay ( ) ;
2009-04-19 18:07:22 +00:00
// Render selection
2013-12-03 14:40:40 +00:00
if ( renderer . StartOverlay ( false ) )
2009-04-19 18:07:22 +00:00
{
2015-06-24 21:21:19 +00:00
if ( highlighted ! = null & & ! highlighted . IsDisposed ) BuilderPlug . RenderReverseAssociations ( renderer , highlightasso , eventlines ) ; //mxd
2009-04-19 18:07:22 +00:00
if ( selecting ) RenderMultiSelection ( ) ;
2015-06-24 21:21:19 +00:00
renderer . RenderArrows ( eventlines ) ; //mxd
2009-04-19 18:07:22 +00:00
renderer . Finish ( ) ;
}
renderer . Present ( ) ;
}
// Selection
protected override void OnSelectBegin ( )
{
// Item highlighted?
if ( ( highlighted ! = null ) & & ! highlighted . IsDisposed )
{
// Update display
if ( renderer . StartPlotter ( false ) )
{
// Redraw highlight to show selection
renderer . PlotSector ( highlighted ) ;
renderer . Finish ( ) ;
renderer . Present ( ) ;
}
}
base . OnSelectBegin ( ) ;
}
// End selection
protected override void OnSelectEnd ( )
{
// Not stopping from multiselection?
if ( ! selecting )
{
// Item highlighted?
if ( ( highlighted ! = null ) & & ! highlighted . IsDisposed )
{
2013-03-18 13:52:27 +00:00
//mxd. Flip selection
SelectSector ( highlighted , ! highlighted . Selected , true ) ;
2009-04-19 18:07:22 +00:00
// Update display
if ( renderer . StartPlotter ( false ) )
{
// Render highlighted item
renderer . PlotSector ( highlighted , General . Colors . Highlight ) ;
renderer . Finish ( ) ;
renderer . Present ( ) ;
}
// Update overlay
TextLabel [ ] labelarray = labels [ highlighted ] ;
foreach ( TextLabel l in labelarray ) l . Color = General . Colors . Highlight ;
2014-12-03 23:15:26 +00:00
UpdateOverlaySurfaces ( ) ; //mxd
2009-04-19 18:07:22 +00:00
UpdateOverlay ( ) ;
renderer . Present ( ) ;
2015-01-10 23:12:19 +00:00
//mxd. Thing selection state may've changed
if ( General . Interface . AltState ) General . Interface . RedrawDisplay ( ) ;
2014-12-03 23:15:26 +00:00
}
else if ( BuilderPlug . Me . AutoClearSelection & & General . Map . Map . SelectedSectorsCount > 0 ) //mxd
{
2013-03-28 11:37:08 +00:00
General . Map . Map . ClearSelectedLinedefs ( ) ;
General . Map . Map . ClearSelectedSectors ( ) ;
2014-12-03 23:15:26 +00:00
UpdateOverlaySurfaces ( ) ; //mxd
2013-03-28 11:37:08 +00:00
General . Interface . RedrawDisplay ( ) ;
2009-04-19 18:07:22 +00:00
}
2013-07-09 11:29:10 +00:00
2014-05-08 09:24:32 +00:00
UpdateSelectionInfo ( ) ; //mxd
2009-04-19 18:07:22 +00:00
}
base . OnSelectEnd ( ) ;
}
// Start editing
protected override void OnEditBegin ( )
{
// Item highlighted?
if ( ( highlighted ! = null ) & & ! highlighted . IsDisposed )
{
// Edit pressed in this mode
editpressed = true ;
// Highlighted item not selected?
2009-07-09 14:03:47 +00:00
if ( ! highlighted . Selected & & ( BuilderPlug . Me . AutoClearSelection | | ( General . Map . Map . SelectedSectorsCount = = 0 ) ) )
2009-04-19 18:07:22 +00:00
{
// Make this the only selection
General . Map . Map . ClearSelectedSectors ( ) ;
General . Map . Map . ClearSelectedLinedefs ( ) ;
SelectSector ( highlighted , true , false ) ;
2013-12-10 12:19:27 +00:00
UpdateSelectedLabels ( ) ; //mxd
2014-12-03 23:15:26 +00:00
UpdateOverlaySurfaces ( ) ; //mxd
2009-04-19 18:07:22 +00:00
General . Interface . RedrawDisplay ( ) ;
}
// Update display
if ( renderer . StartPlotter ( false ) )
{
// Redraw highlight to show selection
renderer . PlotSector ( highlighted ) ;
renderer . Finish ( ) ;
renderer . Present ( ) ;
}
}
2013-12-05 09:24:55 +00:00
else if ( ! selecting & & BuilderPlug . Me . AutoDrawOnEdit ) //mxd. We don't want to draw while multiselecting
2009-04-19 18:07:22 +00:00
{
// Start drawing mode
DrawGeometryMode drawmode = new DrawGeometryMode ( ) ;
bool snaptogrid = General . Interface . ShiftState ^ General . Interface . SnapToGrid ;
bool snaptonearest = General . Interface . CtrlState ^ General . Interface . AutoMerge ;
2015-07-09 22:32:12 +00:00
DrawnVertex v = DrawGeometryMode . GetCurrentPosition ( mousemappos , snaptonearest , snaptogrid , false , renderer , new List < DrawnVertex > ( ) ) ;
2010-08-13 18:32:21 +00:00
if ( drawmode . DrawPointAt ( v ) )
General . Editing . ChangeMode ( drawmode ) ;
else
General . Interface . DisplayStatus ( StatusType . Warning , "Failed to draw point: outside of map boundaries." ) ;
2009-04-19 18:07:22 +00:00
}
base . OnEditBegin ( ) ;
}
// Done editing
protected override void OnEditEnd ( )
{
// Edit pressed in this mode?
if ( editpressed )
{
// Anything selected?
ICollection < Sector > selected = General . Map . Map . GetSelectedSectors ( true ) ;
if ( selected . Count > 0 )
{
if ( General . Interface . IsActiveWindow )
{
2013-07-09 11:29:10 +00:00
//mxd. Show realtime vertex edit dialog
2014-02-21 14:42:12 +00:00
General . Interface . OnEditFormValuesChanged + = sectorEditForm_OnValuesChanged ;
2013-11-29 12:24:47 +00:00
DialogResult result = General . Interface . ShowEditSectors ( selected ) ;
2013-07-10 09:57:30 +00:00
General . Interface . OnEditFormValuesChanged - = sectorEditForm_OnValuesChanged ;
2013-07-29 08:50:50 +00:00
General . Map . Renderer2D . UpdateExtraFloorFlag ( ) ; //mxd
2009-04-19 18:07:22 +00:00
// When a single sector was selected, deselect it now
2014-12-03 23:15:26 +00:00
if ( selected . Count = = 1 )
{
2009-04-19 18:07:22 +00:00
General . Map . Map . ClearSelectedSectors ( ) ;
General . Map . Map . ClearSelectedLinedefs ( ) ;
2014-12-03 23:15:26 +00:00
UpdateEffectLabels ( ) ; //mxd
}
else if ( result = = DialogResult . Cancel ) //mxd. Restore selection...
{
2013-12-10 12:19:27 +00:00
foreach ( Sector s in selected ) SelectSector ( s , true , false ) ;
UpdateSelectedLabels ( ) ; //mxd
2009-04-19 18:07:22 +00:00
}
2013-12-10 12:19:27 +00:00
2014-12-03 23:15:26 +00:00
UpdateOverlaySurfaces ( ) ; //mxd
2013-11-29 12:24:47 +00:00
General . Interface . RedrawDisplay ( ) ;
2009-04-19 18:07:22 +00:00
}
}
2013-07-09 11:29:10 +00:00
2014-05-08 09:24:32 +00:00
UpdateSelectionInfo ( ) ; //mxd
2009-04-19 18:07:22 +00:00
}
editpressed = false ;
base . OnEditEnd ( ) ;
}
2013-07-09 11:29:10 +00:00
//mxd
2014-12-03 23:15:26 +00:00
private void sectorEditForm_OnValuesChanged ( object sender , EventArgs e )
{
2013-07-09 11:29:10 +00:00
// Update entire display
General . Map . Map . Update ( ) ;
General . Interface . RedrawDisplay ( ) ;
}
2009-04-19 18:07:22 +00:00
// Mouse moves
public override void OnMouseMove ( MouseEventArgs e )
{
base . OnMouseMove ( e ) ;
2013-11-08 08:18:33 +00:00
if ( panning ) return ; //mxd. Skip all this jazz while panning
2009-04-19 18:07:22 +00:00
2013-03-18 13:52:27 +00:00
//mxd
2014-12-03 23:15:26 +00:00
if ( selectpressed & & ! editpressed & & ! selecting )
{
2013-03-18 13:52:27 +00:00
// Check if moved enough pixels for multiselect
Vector2D delta = mousedownpos - mousepos ;
if ( ( Math . Abs ( delta . x ) > MULTISELECT_START_MOVE_PIXELS ) | |
2014-12-03 23:15:26 +00:00
( Math . Abs ( delta . y ) > MULTISELECT_START_MOVE_PIXELS ) )
{
2013-03-18 13:52:27 +00:00
// Start multiselecting
StartMultiSelection ( ) ;
}
}
2013-03-28 12:31:37 +00:00
else if ( paintselectpressed & & ! editpressed & & ! selecting ) //mxd. Drag-select
2013-03-18 13:52:27 +00:00
{
// Find the nearest linedef within highlight range
Linedef l = General . Map . Map . NearestLinedefRange ( mousemappos , BuilderPlug . Me . HighlightRange / renderer . Scale ) ;
Sector s = null ;
2014-12-03 23:15:26 +00:00
if ( l ! = null )
{
2013-03-18 13:52:27 +00:00
// Check on which side of the linedef the mouse is
float side = l . SideOfLine ( mousemappos ) ;
2014-12-03 23:15:26 +00:00
if ( side > 0 )
{
2013-03-18 13:52:27 +00:00
// Is there a sidedef here?
2014-12-03 23:15:26 +00:00
if ( l . Back ! = null ) s = l . Back . Sector ;
}
else
{
2013-03-18 13:52:27 +00:00
// Is there a sidedef here?
2014-12-03 23:15:26 +00:00
if ( l . Front ! = null ) s = l . Front . Sector ;
2013-03-18 13:52:27 +00:00
}
2014-12-03 23:15:26 +00:00
if ( s ! = null )
{
if ( s ! = highlighted )
{
2013-03-18 13:52:27 +00:00
//toggle selected state
highlighted = s ;
if ( General . Interface . ShiftState ^ BuilderPlug . Me . AdditiveSelect )
SelectSector ( highlighted , true , true ) ;
else if ( General . Interface . CtrlState )
SelectSector ( highlighted , false , true ) ;
else
SelectSector ( highlighted , ! highlighted . Selected , true ) ;
// Update entire display
2014-12-03 23:15:26 +00:00
UpdateOverlaySurfaces ( ) ; //mxd
2013-03-18 13:52:27 +00:00
General . Interface . RedrawDisplay ( ) ;
}
2014-12-03 23:15:26 +00:00
}
else if ( highlighted ! = null )
{
2013-03-18 13:52:27 +00:00
highlighted = null ;
Highlight ( null ) ;
// Update entire display
General . Interface . RedrawDisplay ( ) ;
}
2013-07-09 11:29:10 +00:00
2014-05-08 09:24:32 +00:00
UpdateSelectionInfo ( ) ; //mxd
2013-03-18 13:52:27 +00:00
}
}
else if ( e . Button = = MouseButtons . None ) // Not holding any buttons?
2009-04-19 18:07:22 +00:00
{
// Find the nearest linedef within highlight range
Linedef l = General . Map . Map . NearestLinedef ( mousemappos ) ;
if ( l ! = null )
{
// Check on which side of the linedef the mouse is
float side = l . SideOfLine ( mousemappos ) ;
if ( side > 0 )
{
// Is there a sidedef here?
if ( l . Back ! = null )
{
// Highlight if not the same
if ( l . Back . Sector ! = highlighted ) Highlight ( l . Back . Sector ) ;
}
else
{
// Highlight nothing
if ( highlighted ! = null ) Highlight ( null ) ;
}
}
else
{
// Is there a sidedef here?
if ( l . Front ! = null )
{
// Highlight if not the same
if ( l . Front . Sector ! = highlighted ) Highlight ( l . Front . Sector ) ;
}
else
{
// Highlight nothing
if ( highlighted ! = null ) Highlight ( null ) ;
}
}
}
else
{
// Highlight nothing
if ( highlighted ! = null ) Highlight ( null ) ;
}
2015-07-14 09:02:48 +00:00
//mxd. Show tooltip?
2015-07-15 09:09:47 +00:00
if ( General . Map . UDMF & & General . Settings . RenderComments & & mouselastpos ! = mousepos & & highlighted ! = null & & ! highlighted . IsDisposed & & highlighted . Fields . ContainsKey ( "comment" ) )
2015-07-14 09:02:48 +00:00
{
string comment = highlighted . Fields . GetValue ( "comment" , string . Empty ) ;
2015-07-14 23:34:31 +00:00
if ( comment . Length > 2 )
{
string type = comment . Substring ( 0 , 3 ) ;
int index = Array . IndexOf ( CommentType . Types , type ) ;
if ( index > 0 ) comment = comment . TrimStart ( type . ToCharArray ( ) ) ;
}
2015-07-14 09:02:48 +00:00
General . Interface . Display . ShowToolTip ( "Comment:" , comment , ( int ) ( mousepos . x + 32 * MainForm . DPIScaler . Width ) , ( int ) ( mousepos . y + 8 * MainForm . DPIScaler . Height ) ) ;
}
2013-03-18 13:52:27 +00:00
}
2009-04-19 18:07:22 +00:00
}
// Mouse leaves
public override void OnMouseLeave ( EventArgs e )
{
base . OnMouseLeave ( e ) ;
// Highlight nothing
Highlight ( null ) ;
}
2013-03-18 13:52:27 +00:00
//mxd
2014-12-03 23:15:26 +00:00
protected override void OnPaintSelectBegin ( )
{
if ( highlighted ! = null )
{
2013-04-05 10:56:07 +00:00
if ( General . Interface . ShiftState ^ BuilderPlug . Me . AdditiveSelect )
SelectSector ( highlighted , true , true ) ;
else if ( General . Interface . CtrlState )
SelectSector ( highlighted , false , true ) ;
else
SelectSector ( highlighted , ! highlighted . Selected , true ) ;
// Update entire display
2014-12-03 23:15:26 +00:00
UpdateOverlaySurfaces ( ) ; //mxd
2013-04-05 10:56:07 +00:00
General . Interface . RedrawDisplay ( ) ;
}
2013-03-18 13:52:27 +00:00
base . OnPaintSelectBegin ( ) ;
}
2009-04-19 18:07:22 +00:00
// Mouse wants to drag
protected override void OnDragStart ( MouseEventArgs e )
{
base . OnDragStart ( e ) ;
// Edit button used?
if ( General . Actions . CheckActionActive ( null , "classicedit" ) )
{
// Anything highlighted?
if ( ( highlighted ! = null ) & & ! highlighted . IsDisposed )
{
// Highlighted item not selected?
if ( ! highlighted . Selected )
{
// Select only this sector for dragging
General . Map . Map . ClearSelectedSectors ( ) ;
SelectSector ( highlighted , true , true ) ;
2014-12-03 23:15:26 +00:00
UpdateOverlaySurfaces ( ) ; //mxd
2009-04-19 18:07:22 +00:00
}
// Start dragging the selection
2014-12-03 23:15:26 +00:00
if ( ! BuilderPlug . Me . DontMoveGeometryOutsideMapBoundary | | CanDrag ( ) ) //mxd
2013-03-18 13:52:27 +00:00
General . Editing . ChangeMode ( new DragSectorsMode ( mousedownmappos ) ) ;
2009-04-19 18:07:22 +00:00
}
}
}
2013-03-18 13:52:27 +00:00
//mxd. Check if any selected sector is outside of map boundary
2014-12-03 23:15:26 +00:00
private bool CanDrag ( )
{
2013-03-18 13:52:27 +00:00
ICollection < Sector > selectedsectors = General . Map . Map . GetSelectedSectors ( true ) ;
int unaffectedCount = 0 ;
2014-12-03 23:15:26 +00:00
foreach ( Sector s in selectedsectors )
{
2013-03-18 13:52:27 +00:00
// Make sure the sector is inside the map boundary
2014-12-03 23:15:26 +00:00
foreach ( Sidedef sd in s . Sidedefs )
{
2013-03-18 13:52:27 +00:00
if ( sd . Line . Start . Position . x < General . Map . Config . LeftBoundary | | sd . Line . Start . Position . x > General . Map . Config . RightBoundary
| | sd . Line . Start . Position . y > General . Map . Config . TopBoundary | | sd . Line . Start . Position . y < General . Map . Config . BottomBoundary
| | sd . Line . End . Position . x < General . Map . Config . LeftBoundary | | sd . Line . End . Position . x > General . Map . Config . RightBoundary
2014-12-03 23:15:26 +00:00
| | sd . Line . End . Position . y > General . Map . Config . TopBoundary | | sd . Line . End . Position . y < General . Map . Config . BottomBoundary )
{
2013-12-10 12:19:27 +00:00
SelectSector ( s , false , false ) ;
2013-03-18 13:52:27 +00:00
unaffectedCount + + ;
break ;
}
}
}
2014-12-03 23:15:26 +00:00
if ( unaffectedCount = = selectedsectors . Count )
{
2013-03-18 13:52:27 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "Unable to drag selection: " + ( selectedsectors . Count = = 1 ? "selected sector is" : "all of selected sectors are" ) + " outside of map boundary!" ) ;
General . Interface . RedrawDisplay ( ) ;
return false ;
}
if ( unaffectedCount > 0 )
General . Interface . DisplayStatus ( StatusType . Warning , unaffectedCount + " of selected sectors " + ( unaffectedCount = = 1 ? "is" : "are" ) + " outside of map boundary!" ) ;
2013-12-10 12:19:27 +00:00
UpdateSelectedLabels ( ) ; //mxd
2013-03-18 13:52:27 +00:00
return true ;
}
2009-04-19 18:07:22 +00:00
// This is called wheh selection ends
protected override void OnEndMultiSelection ( )
{
2009-08-19 11:09:10 +00:00
bool selectionvolume = ( ( Math . Abs ( base . selectionrect . Width ) > 0.1f ) & & ( Math . Abs ( base . selectionrect . Height ) > 0.1f ) ) ;
if ( selectionvolume )
2009-04-19 18:07:22 +00:00
{
2014-12-03 23:15:26 +00:00
List < Line2D > selectionOutline = new List < Line2D > {
2013-11-29 14:45:29 +00:00
new Line2D ( selectionrect . Left , selectionrect . Top , selectionrect . Right , selectionrect . Top ) ,
new Line2D ( selectionrect . Right , selectionrect . Top , selectionrect . Right , selectionrect . Bottom ) ,
new Line2D ( selectionrect . Left , selectionrect . Bottom , selectionrect . Right , selectionrect . Bottom ) ,
new Line2D ( selectionrect . Left , selectionrect . Bottom , selectionrect . Left , selectionrect . Top )
2014-12-03 23:15:26 +00:00
} ;
2013-11-29 14:45:29 +00:00
2013-03-18 13:52:27 +00:00
//mxd. collect changed sectors
2014-12-03 23:15:26 +00:00
switch ( marqueSelectionMode )
{
2013-12-20 09:24:43 +00:00
case MarqueSelectionMode . SELECT :
bool select ;
2014-12-03 23:15:26 +00:00
foreach ( Sector s in General . Map . Map . Sectors )
{
select = IsInSelectionRect ( s , selectionOutline ) ;
2013-12-20 09:24:43 +00:00
if ( select & & ! s . Selected ) SelectSector ( s , true , false ) ;
else if ( ! select & & s . Selected ) SelectSector ( s , false , false ) ;
}
2014-12-03 23:15:26 +00:00
if ( marqueSelectionIncludesThings )
{
2014-01-13 12:49:54 +00:00
ICollection < Sector > selected = General . Map . Map . GetSelectedSectors ( true ) ;
2014-12-03 23:15:26 +00:00
foreach ( Thing t in General . Map . ThingsFilter . VisibleThings )
{
2014-01-13 12:49:54 +00:00
t . DetermineSector ( ) ;
if ( t . Sector = = null ) continue ;
t . Selected = selectionrect . Contains ( t . Position . x , t . Position . y ) & & selected . Contains ( t . Sector ) ;
}
}
2013-12-20 09:24:43 +00:00
break ;
2013-11-29 14:45:29 +00:00
2013-12-20 09:24:43 +00:00
case MarqueSelectionMode . ADD :
2014-12-03 23:15:26 +00:00
foreach ( Sector s in General . Map . Map . Sectors )
{
if ( ! s . Selected & & IsInSelectionRect ( s , selectionOutline ) )
2013-12-20 09:24:43 +00:00
SelectSector ( s , true , false ) ;
}
2014-12-03 23:15:26 +00:00
if ( marqueSelectionIncludesThings )
{
2014-01-13 12:49:54 +00:00
ICollection < Sector > selected = General . Map . Map . GetSelectedSectors ( true ) ;
2014-12-03 23:15:26 +00:00
foreach ( Thing t in General . Map . ThingsFilter . VisibleThings )
{
2014-01-13 12:49:54 +00:00
t . DetermineSector ( ) ;
if ( t . Sector = = null ) continue ;
t . Selected | = selectionrect . Contains ( t . Position . x , t . Position . y ) & & selected . Contains ( t . Sector ) ;
}
}
2013-12-20 09:24:43 +00:00
break ;
case MarqueSelectionMode . SUBTRACT :
2014-12-03 23:15:26 +00:00
foreach ( Sector s in General . Map . Map . Sectors )
{
2013-12-20 09:24:43 +00:00
if ( ! s . Selected ) continue ;
2014-12-03 23:15:26 +00:00
if ( IsInSelectionRect ( s , selectionOutline ) )
2013-12-20 09:24:43 +00:00
SelectSector ( s , false , false ) ;
}
2014-12-03 23:15:26 +00:00
if ( marqueSelectionIncludesThings )
{
2014-01-13 12:49:54 +00:00
foreach ( Thing t in General . Map . ThingsFilter . VisibleThings )
if ( selectionrect . Contains ( t . Position . x , t . Position . y ) ) t . Selected = false ;
}
2013-12-20 09:24:43 +00:00
break ;
default : //should be Intersect
2014-12-03 23:15:26 +00:00
foreach ( Sector s in General . Map . Map . Sectors )
{
2013-12-20 09:24:43 +00:00
if ( ! s . Selected ) continue ;
2014-12-03 23:15:26 +00:00
if ( ! IsInSelectionRect ( s , selectionOutline ) )
2013-12-20 09:24:43 +00:00
SelectSector ( s , false , false ) ;
}
2014-12-03 23:15:26 +00:00
if ( marqueSelectionIncludesThings )
{
2014-01-13 12:49:54 +00:00
foreach ( Thing t in General . Map . ThingsFilter . VisibleThings )
if ( ! selectionrect . Contains ( t . Position . x , t . Position . y ) ) t . Selected = false ;
}
2013-12-20 09:24:43 +00:00
break ;
2009-04-19 18:07:22 +00:00
}
2013-03-18 13:52:27 +00:00
2009-07-07 11:29:56 +00:00
// Make sure all linedefs reflect selected sectors
foreach ( Sidedef sd in General . Map . Map . Sidedefs )
2013-03-18 13:52:27 +00:00
sd . Line . Selected = sd . Sector . Selected | | ( sd . Other ! = null & & sd . Other . Sector . Selected ) ;
2013-07-09 11:29:10 +00:00
2013-12-10 12:19:27 +00:00
//mxd. Clear labels for unselected sectors
2014-12-03 23:15:26 +00:00
if ( marqueSelectionMode ! = MarqueSelectionMode . ADD )
{
2013-12-10 12:19:27 +00:00
ICollection < Sector > orderedselection = General . Map . Map . GetSelectedSectors ( false ) ;
2014-12-03 23:15:26 +00:00
foreach ( Sector s in orderedselection )
{
2013-12-10 12:19:27 +00:00
TextLabel [ ] labelarray = labels [ s ] ;
foreach ( TextLabel l in labelarray ) l . Text = "" ;
}
}
UpdateSelectedLabels ( ) ; //mxd
2014-05-08 09:24:32 +00:00
UpdateSelectionInfo ( ) ; //mxd
2014-12-03 23:15:26 +00:00
UpdateOverlaySurfaces ( ) ; //mxd
2009-04-19 18:07:22 +00:00
}
base . OnEndMultiSelection ( ) ;
if ( renderer . StartOverlay ( true ) ) renderer . Finish ( ) ;
General . Interface . RedrawDisplay ( ) ;
}
// This is called when the selection is updated
protected override void OnUpdateMultiSelection ( )
{
base . OnUpdateMultiSelection ( ) ;
// Render selection
if ( renderer . StartOverlay ( true ) )
{
RenderMultiSelection ( ) ;
renderer . Finish ( ) ;
renderer . Present ( ) ;
}
}
// When copying
public override bool OnCopyBegin ( )
{
// No selection made? But we have a highlight!
if ( ( General . Map . Map . GetSelectedSectors ( true ) . Count = = 0 ) & & ( highlighted ! = null ) )
{
// Make the highlight the selection
2015-04-16 13:03:12 +00:00
SelectSector ( highlighted , true , false ) ;
//mxd. Actually, we want it marked, not selected
bool result = base . OnCopyBegin ( ) ;
SelectSector ( highlighted , false , false ) ;
return result ;
2009-04-19 18:07:22 +00:00
}
return base . OnCopyBegin ( ) ;
}
// When undo is used
public override bool OnUndoBegin ( )
{
// Clear ordered selection
General . Map . Map . ClearAllSelected ( ) ;
return base . OnUndoBegin ( ) ;
}
// When undo is performed
public override void OnUndoEnd ( )
{
// Clear labels
SetupLabels ( ) ;
2014-12-03 23:15:26 +00:00
UpdateEffectLabels ( ) ; //mxd
UpdateOverlaySurfaces ( ) ; //mxd
2013-12-12 09:40:20 +00:00
base . OnUndoEnd ( ) ; //mxd
2009-04-19 18:07:22 +00:00
}
// When redo is used
public override bool OnRedoBegin ( )
{
// Clear ordered selection
General . Map . Map . ClearAllSelected ( ) ;
return base . OnRedoBegin ( ) ;
}
// When redo is performed
public override void OnRedoEnd ( )
{
// Clear labels
SetupLabels ( ) ;
2014-12-03 23:15:26 +00:00
UpdateEffectLabels ( ) ; //mxd
UpdateOverlaySurfaces ( ) ; //mxd
2013-09-12 15:02:08 +00:00
base . OnRedoEnd ( ) ; //mxd
2009-04-19 18:07:22 +00:00
}
2013-07-09 11:29:10 +00:00
//mxd
2014-12-03 23:15:26 +00:00
public override void UpdateSelectionInfo ( )
{
2013-07-09 11:29:10 +00:00
if ( General . Map . Map . SelectedSectorsCount > 0 )
General . Interface . DisplayStatus ( StatusType . Selection , General . Map . Map . SelectedSectorsCount + ( General . Map . Map . SelectedSectorsCount = = 1 ? " sector" : " sectors" ) + " selected." ) ;
else
General . Interface . DisplayStatus ( StatusType . Selection , string . Empty ) ;
}
2015-07-14 23:34:31 +00:00
//mxd
private void RenderComment ( Sector s )
{
if ( s . Fields . ContainsKey ( "comment" ) )
{
int iconindex = 0 ;
string comment = s . Fields . GetValue ( "comment" , string . Empty ) ;
if ( comment . Length > 2 )
{
string type = comment . Substring ( 0 , 3 ) ;
int index = Array . IndexOf ( CommentType . Types , type ) ;
if ( index ! = - 1 ) iconindex = index ;
}
Vector2D center = new Vector2D ( s . BBox . Left + s . BBox . Width / 2 , s . BBox . Top + s . BBox . Height / 2 ) ;
RectangleF rect = new RectangleF ( center . x - 8 / renderer . Scale , center . y + 16 * renderer . Scale + 16 / renderer . Scale , 16 / renderer . Scale , - 16 / renderer . Scale ) ;
PixelColor c = ( s = = highlighted ? General . Colors . Highlight : ( s . Selected ? General . Colors . Selection : PixelColor . FromColor ( Color . White ) ) ) ;
renderer . RenderRectangleFilled ( rect , c , true , General . Map . Data . CommentTextures [ iconindex ] ) ;
}
}
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Actions
2010-08-15 13:45:43 +00:00
// This copies the properties
[BeginAction("classiccopyproperties")]
public void CopyProperties ( )
{
// Determine source sectors
ICollection < Sector > sel = null ;
if ( General . Map . Map . SelectedSectorsCount > 0 )
sel = General . Map . Map . GetSelectedSectors ( true ) ;
else if ( highlighted ! = null )
2013-12-20 09:24:43 +00:00
sel = new List < Sector > { highlighted } ;
2010-08-15 13:45:43 +00:00
if ( sel ! = null )
{
// Copy properties from first source sectors
BuilderPlug . Me . CopiedSectorProps = new SectorProperties ( General . GetByIndex ( sel , 0 ) ) ;
General . Interface . DisplayStatus ( StatusType . Action , "Copied sector properties." ) ;
}
}
// This pastes the properties
[BeginAction("classicpasteproperties")]
public void PasteProperties ( )
{
if ( BuilderPlug . Me . CopiedSectorProps ! = null )
{
// Determine target sectors
ICollection < Sector > sel = null ;
if ( General . Map . Map . SelectedSectorsCount > 0 )
sel = General . Map . Map . GetSelectedSectors ( true ) ;
else if ( highlighted ! = null )
{
sel = new List < Sector > ( ) ;
sel . Add ( highlighted ) ;
}
if ( sel ! = null )
{
// Apply properties to selection
General . Map . UndoRedo . CreateUndo ( "Paste sector properties" ) ;
foreach ( Sector s in sel )
{
BuilderPlug . Me . CopiedSectorProps . Apply ( s ) ;
s . UpdateCeilingSurface ( ) ;
s . UpdateFloorSurface ( ) ;
}
General . Interface . DisplayStatus ( StatusType . Action , "Pasted sector properties." ) ;
// Update and redraw
General . Map . IsChanged = true ;
General . Interface . RefreshInfo ( ) ;
2013-07-29 08:50:50 +00:00
General . Map . Renderer2D . UpdateExtraFloorFlag ( ) ; //mxd
2014-12-03 23:15:26 +00:00
UpdateEffectLabels ( ) ; //mxd
2010-08-15 13:45:43 +00:00
General . Interface . RedrawDisplay ( ) ;
}
}
}
2009-04-19 18:07:22 +00:00
// This creates a new vertex at the mouse position
[BeginAction("insertitem", BaseAction = true)]
public virtual void InsertVertexAction ( )
{
// Start drawing mode
DrawGeometryMode drawmode = new DrawGeometryMode ( ) ;
if ( mouseinside )
{
bool snaptogrid = General . Interface . ShiftState ^ General . Interface . SnapToGrid ;
bool snaptonearest = General . Interface . CtrlState ^ General . Interface . AutoMerge ;
2015-07-09 22:32:12 +00:00
DrawnVertex v = DrawGeometryMode . GetCurrentPosition ( mousemappos , snaptonearest , snaptogrid , false , renderer , new List < DrawnVertex > ( ) ) ;
2009-04-19 18:07:22 +00:00
drawmode . DrawPointAt ( v ) ;
}
General . Editing . ChangeMode ( drawmode ) ;
}
[BeginAction("makedoor")]
public void MakeDoor ( )
{
2015-03-23 18:34:10 +00:00
// Anything selected?
ICollection < Sector > orderedselection = General . Map . Map . GetSelectedSectors ( true ) ;
//mxd. Should we use highlighted item?
if ( orderedselection . Count = = 0 & & highlighted ! = null )
2009-04-19 18:07:22 +00:00
{
2015-03-23 18:34:10 +00:00
orderedselection . Add ( highlighted ) ;
2009-04-19 18:07:22 +00:00
}
if ( orderedselection . Count > 0 )
{
2014-03-06 09:08:21 +00:00
if ( doortex = = "-" ) doortex = General . Map . Config . MakeDoorDoor ; //mxd
if ( tracktex = = "-" ) tracktex = General . Map . Config . MakeDoorTrack ; //mxd
2009-04-19 18:07:22 +00:00
string floortex = null ;
string ceiltex = null ;
// Find ceiling and floor textures
foreach ( Sector s in orderedselection )
{
if ( floortex = = null ) floortex = s . FloorTexture ; else if ( floortex ! = s . FloorTexture ) floortex = "" ;
if ( ceiltex = = null ) ceiltex = s . CeilTexture ; else if ( ceiltex ! = s . CeilTexture ) ceiltex = "" ;
}
// Show the dialog
MakeDoorForm form = new MakeDoorForm ( ) ;
2012-04-14 12:22:19 +00:00
if ( form . Show ( General . Interface , doortex , tracktex , ceiltex , floortex , resetoffsets ) = = DialogResult . OK )
2009-04-19 18:07:22 +00:00
{
doortex = form . DoorTexture ;
2012-04-14 12:22:19 +00:00
tracktex = form . TrackTexture ;
2009-04-19 18:07:22 +00:00
ceiltex = form . CeilingTexture ;
floortex = form . FloorTexture ;
2012-04-14 12:22:19 +00:00
resetoffsets = form . ResetOffsets ;
2009-04-19 18:07:22 +00:00
// Create undo
General . Map . UndoRedo . CreateUndo ( "Make door (" + doortex + ")" ) ;
General . Interface . DisplayStatus ( StatusType . Action , "Created a " + doortex + " door." ) ;
// Go for all selected sectors
foreach ( Sector s in orderedselection )
{
// Lower the ceiling down to the floor
s . CeilHeight = s . FloorHeight ;
// Make a unique tag (not sure if we need it yet, depends on the args)
int tag = General . Map . Map . GetNewTag ( ) ;
// Go for all it's sidedefs
foreach ( Sidedef sd in s . Sidedefs )
{
// Singlesided?
if ( sd . Other = = null )
{
// Make this a doortrak
sd . SetTextureHigh ( "-" ) ;
2012-04-14 12:22:19 +00:00
sd . SetTextureMid ( tracktex ) ;
2009-04-19 18:07:22 +00:00
sd . SetTextureLow ( "-" ) ;
// Set upper/lower unpegged flags
2009-06-11 21:21:20 +00:00
sd . Line . SetFlag ( General . Map . Config . UpperUnpeggedFlag , false ) ;
sd . Line . SetFlag ( General . Map . Config . LowerUnpeggedFlag , true ) ;
2009-04-19 18:07:22 +00:00
}
else
{
// Set textures
if ( floortex . Length > 0 ) s . SetFloorTexture ( floortex ) ;
if ( ceiltex . Length > 0 ) s . SetCeilTexture ( ceiltex ) ;
if ( doortex . Length > 0 ) sd . Other . SetTextureHigh ( doortex ) ;
// Set upper/lower unpegged flags
2009-06-11 21:21:20 +00:00
sd . Line . SetFlag ( General . Map . Config . UpperUnpeggedFlag , false ) ;
sd . Line . SetFlag ( General . Map . Config . LowerUnpeggedFlag , false ) ;
2009-04-19 18:07:22 +00:00
// Get door linedef type from config
sd . Line . Action = General . Map . Config . MakeDoorAction ;
2012-04-14 12:22:19 +00:00
// Set activation type
sd . Line . Activate = General . Map . Config . MakeDoorActivate ;
// Set the flags
foreach ( var flagpair in General . Map . Config . MakeDoorFlags )
sd . Line . SetFlag ( flagpair . Key , flagpair . Value ) ;
2009-04-19 18:07:22 +00:00
// Set the linedef args
for ( int i = 0 ; i < Linedef . NUM_ARGS ; i + + )
{
// A -1 arg indicates that the arg must be set to the new sector tag
// and only in this case we set the tag on the sector, because only
// then we know for sure that we need a tag.
if ( General . Map . Config . MakeDoorArgs [ i ] = = - 1 )
{
sd . Line . Args [ i ] = tag ;
s . Tag = tag ;
}
else
{
sd . Line . Args [ i ] = General . Map . Config . MakeDoorArgs [ i ] ;
}
}
// Make sure the line is facing outwards
if ( sd . IsFront )
{
sd . Line . FlipVertices ( ) ;
sd . Line . FlipSidedefs ( ) ;
}
}
2012-04-14 12:22:19 +00:00
// Reset the texture offsets if required
if ( resetoffsets )
{
sd . OffsetX = 0 ;
sd . OffsetY = 0 ;
if ( sd . Other ! = null )
{
sd . Other . OffsetX = 0 ;
sd . Other . OffsetY = 0 ;
}
}
2009-04-19 18:07:22 +00:00
}
}
// When a single sector was selected, deselect it now
2015-03-23 18:34:10 +00:00
if ( orderedselection . Count = = 1 ) ClearSelection ( ) ; //mxd
General . Map . Data . UpdateUsedTextures ( ) ; //mxd
2009-04-19 18:07:22 +00:00
}
// Done
form . Dispose ( ) ;
General . Interface . RedrawDisplay ( ) ;
}
2014-03-03 09:52:55 +00:00
else //mxd
{
2015-03-23 18:34:10 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "This action requires a selection!" ) ;
2014-03-03 09:52:55 +00:00
}
2009-04-19 18:07:22 +00:00
}
[BeginAction("deleteitem", BaseAction = true)]
public void DeleteItem ( )
{
// Make list of selected sectors
List < Sector > selected = new List < Sector > ( General . Map . Map . GetSelectedSectors ( true ) ) ;
if ( ( selected . Count = = 0 ) & & ( highlighted ! = null ) & & ! highlighted . IsDisposed ) selected . Add ( highlighted ) ;
// Anything to do?
if ( selected . Count > 0 )
{
// Make undo
if ( selected . Count > 1 )
{
General . Map . UndoRedo . CreateUndo ( "Delete " + selected . Count + " sectors" ) ;
General . Interface . DisplayStatus ( StatusType . Action , "Deleted " + selected . Count + " sectors." ) ;
}
else
{
General . Map . UndoRedo . CreateUndo ( "Delete sector" ) ;
General . Interface . DisplayStatus ( StatusType . Action , "Deleted sector." ) ;
}
2013-12-13 09:31:18 +00:00
General . Map . Map . BeginAddRemove ( ) ; //mxd
2009-04-19 18:07:22 +00:00
// Dispose selected sectors
foreach ( Sector s in selected )
{
2013-12-13 09:31:18 +00:00
//mxd. Get all the linedefs
List < Linedef > lines = new List < Linedef > ( s . Sidedefs . Count ) ;
foreach ( Sidedef side in s . Sidedefs ) lines . Add ( side . Line ) ;
2009-04-19 18:07:22 +00:00
// Dispose the sector
s . Dispose ( ) ;
// Check all the lines
for ( int i = lines . Count - 1 ; i > = 0 ; i - - )
{
// If the line has become orphaned, remove it
if ( ( lines [ i ] . Front = = null ) & & ( lines [ i ] . Back = = null ) )
{
// Remove line
lines [ i ] . Dispose ( ) ;
}
else
{
// If the line only has a back side left, flip the line and sides
if ( ( lines [ i ] . Front = = null ) & & ( lines [ i ] . Back ! = null ) )
{
lines [ i ] . FlipVertices ( ) ;
lines [ i ] . FlipSidedefs ( ) ;
}
2013-03-18 13:52:27 +00:00
//mxd. Check textures.
2014-12-03 23:15:26 +00:00
if ( lines [ i ] . Front . MiddleRequired ( ) & & lines [ i ] . Front . LongMiddleTexture = = MapSet . EmptyLongName )
{
if ( lines [ i ] . Front . LongHighTexture ! = MapSet . EmptyLongName )
{
2013-03-18 13:52:27 +00:00
lines [ i ] . Front . SetTextureMid ( lines [ i ] . Front . HighTexture ) ;
2014-12-03 23:15:26 +00:00
}
else if ( lines [ i ] . Front . LongLowTexture ! = MapSet . EmptyLongName )
{
2013-03-18 13:52:27 +00:00
lines [ i ] . Front . SetTextureMid ( lines [ i ] . Front . LowTexture ) ;
}
}
//mxd. Do we still need high/low textures?
2014-01-08 09:46:57 +00:00
lines [ i ] . Front . RemoveUnneededTextures ( false ) ;
2009-04-19 18:07:22 +00:00
// Update sided flags
lines [ i ] . ApplySidedFlags ( ) ;
}
}
}
2013-12-13 09:31:18 +00:00
General . Map . Map . EndAddRemove ( ) ; //mxd
2009-04-19 18:07:22 +00:00
// Update cache values
General . Map . IsChanged = true ;
General . Map . Map . Update ( ) ;
2014-12-03 23:15:26 +00:00
UpdateOverlaySurfaces ( ) ; //mxd
2009-04-19 18:07:22 +00:00
// Make text labels for sectors
SetupLabels ( ) ;
UpdateSelectedLabels ( ) ;
// Redraw screen
2015-06-30 18:34:08 +00:00
UpdateSelectionInfo ( ) ; //mxd
2015-04-06 19:33:57 +00:00
General . Map . Renderer2D . UpdateExtraFloorFlag ( ) ; //mxd
2009-04-19 18:07:22 +00:00
General . Interface . RedrawDisplay ( ) ;
}
}
2014-01-08 09:46:57 +00:00
[BeginAction("dissolveitem", BaseAction = true)] //mxd
2014-12-03 23:15:26 +00:00
public void DissolveItem ( )
{
2014-02-18 14:04:14 +00:00
//TODO handle this differently?..
2014-01-08 09:46:57 +00:00
DeleteItem ( ) ;
}
2009-04-19 18:07:22 +00:00
// This joins sectors together and keeps all lines
[BeginAction("joinsectors")]
public void JoinSectors ( )
{
// Worth our money?
int count = General . Map . Map . GetSelectedSectors ( true ) . Count ;
if ( count > 1 )
{
// Make undo
General . Map . UndoRedo . CreateUndo ( "Join " + count + " sectors" ) ;
General . Interface . DisplayStatus ( StatusType . Action , "Joined " + count + " sectors." ) ;
// Merge
JoinMergeSectors ( false ) ;
// Deselect
General . Map . Map . ClearSelectedSectors ( ) ;
General . Map . Map . ClearSelectedLinedefs ( ) ;
General . Map . IsChanged = true ;
2015-02-13 19:59:14 +00:00
//mxd. Clear selection info
General . Interface . DisplayStatus ( StatusType . Selection , string . Empty ) ;
//mxd. Update
UpdateOverlaySurfaces ( ) ;
UpdateEffectLabels ( ) ;
2009-04-19 18:07:22 +00:00
// Redraw display
General . Interface . RedrawDisplay ( ) ;
}
}
// This joins sectors together and removes the lines in between
[BeginAction("mergesectors")]
public void MergeSectors ( )
{
// Worth our money?
int count = General . Map . Map . GetSelectedSectors ( true ) . Count ;
if ( count > 1 )
{
// Make undo
General . Map . UndoRedo . CreateUndo ( "Merge " + count + " sectors" ) ;
General . Interface . DisplayStatus ( StatusType . Action , "Merged " + count + " sectors." ) ;
// Merge
JoinMergeSectors ( true ) ;
// Deselect
General . Map . Map . ClearSelectedSectors ( ) ;
General . Map . Map . ClearSelectedLinedefs ( ) ;
General . Map . IsChanged = true ;
2015-02-13 19:59:14 +00:00
//mxd. Clear selection info
General . Interface . DisplayStatus ( StatusType . Selection , string . Empty ) ;
//mxd. Update
UpdateOverlaySurfaces ( ) ;
UpdateEffectLabels ( ) ;
2009-04-19 18:07:22 +00:00
// Redraw display
General . Interface . RedrawDisplay ( ) ;
}
}
// Make gradient brightness
[BeginAction("gradientbrightness")]
public void MakeGradientBrightness ( )
{
// Need at least 3 selected sectors
// The first and last are not modified
ICollection < Sector > orderedselection = General . Map . Map . GetSelectedSectors ( true ) ;
2014-12-03 23:15:26 +00:00
if ( orderedselection . Count > 2 )
{
2013-03-18 13:52:27 +00:00
General . Interface . DisplayStatus ( StatusType . Action , "Created gradient brightness over selected sectors." ) ;
General . Map . UndoRedo . CreateUndo ( "Gradient brightness" ) ;
//mxd
Sector start = General . GetByIndex ( orderedselection , 0 ) ;
Sector end = General . GetByIndex ( orderedselection , orderedselection . Count - 1 ) ;
//mxd. Use UDMF light?
2015-01-16 21:38:42 +00:00
string mode = ( string ) BuilderPlug . Me . MenusForm . GradientModeMenu . SelectedItem ;
InterpolationTools . Mode interpolationmode = ( InterpolationTools . Mode ) BuilderPlug . Me . MenusForm . GradientInterpolationMenu . SelectedIndex ;
2015-01-29 12:14:45 +00:00
if ( General . Map . UDMF & & mode ! = MenusForm . BrightnessGradientModes . Sectors )
2014-12-03 23:15:26 +00:00
{
2015-01-16 21:38:42 +00:00
if ( mode = = MenusForm . BrightnessGradientModes . Ceilings | | mode = = MenusForm . BrightnessGradientModes . Floors )
2014-12-03 23:15:26 +00:00
{
2015-01-16 21:38:42 +00:00
string lightKey ;
string lightAbsKey ;
int startbrightness , endbrightness ;
2013-03-18 13:52:27 +00:00
2015-01-16 21:38:42 +00:00
if ( mode = = MenusForm . BrightnessGradientModes . Ceilings )
2014-12-03 23:15:26 +00:00
{
2015-01-16 21:38:42 +00:00
lightKey = "lightceiling" ;
lightAbsKey = "lightceilingabsolute" ;
}
else //should be floors...
2014-12-03 23:15:26 +00:00
{
2015-01-16 21:38:42 +00:00
lightKey = "lightfloor" ;
lightAbsKey = "lightfloorabsolute" ;
2013-03-18 13:52:27 +00:00
}
2015-01-16 21:38:42 +00:00
//get total brightness of start sector
if ( start . Fields . GetValue ( lightAbsKey , false ) )
startbrightness = start . Fields . GetValue ( lightKey , 0 ) ;
else
startbrightness = Math . Min ( 255 , Math . Max ( 0 , start . Brightness + start . Fields . GetValue ( lightKey , 0 ) ) ) ;
2013-09-11 08:49:45 +00:00
2015-01-16 21:38:42 +00:00
//get total brightness of end sector
if ( end . Fields . GetValue ( lightAbsKey , false ) )
endbrightness = end . Fields . GetValue ( lightKey , 0 ) ;
else
endbrightness = Math . Min ( 255 , Math . Max ( 0 , end . Brightness + end . Fields . GetValue ( lightKey , 0 ) ) ) ;
2013-09-11 08:49:45 +00:00
// Go for all sectors in between first and last
int index = 0 ;
2014-12-03 23:15:26 +00:00
foreach ( Sector s in orderedselection )
{
2013-09-11 08:49:45 +00:00
s . Fields . BeforeFieldsChange ( ) ;
2015-01-16 21:38:42 +00:00
float u = index / ( float ) ( orderedselection . Count - 1 ) ;
float b = InterpolationTools . Interpolate ( startbrightness , endbrightness , u , interpolationmode ) ;
//absolute flag set?
if ( s . Fields . GetValue ( lightAbsKey , false ) )
{
if ( s . Fields . ContainsKey ( lightKey ) )
s . Fields [ lightKey ] . Value = ( int ) b ;
else
s . Fields . Add ( lightKey , new UniValue ( UniversalType . Integer , ( int ) b ) ) ;
}
else
{
UDMFTools . SetInteger ( s . Fields , lightKey , ( int ) b - s . Brightness , 0 ) ;
}
2015-01-16 23:37:20 +00:00
s . UpdateNeeded = true ;
2013-09-11 08:49:45 +00:00
index + + ;
}
2015-01-16 21:38:42 +00:00
}
else if ( mode = = MenusForm . BrightnessGradientModes . Fade )
{
ApplyColorGradient ( orderedselection , start , end , interpolationmode , "fadecolor" , 0 ) ;
}
else if ( mode = = MenusForm . BrightnessGradientModes . Light )
{
ApplyColorGradient ( orderedselection , start , end , interpolationmode , "lightcolor" , 0xFFFFFF ) ;
}
else if ( mode = = MenusForm . BrightnessGradientModes . LightAndFade )
{
ApplyColorGradient ( orderedselection , start , end , interpolationmode , "fadecolor" , 0 ) ;
ApplyColorGradient ( orderedselection , start , end , interpolationmode , "lightcolor" , 0xFFFFFF ) ;
2013-09-11 08:49:45 +00:00
}
2015-01-16 21:38:42 +00:00
}
2014-12-03 23:15:26 +00:00
else
{
2013-03-18 13:52:27 +00:00
// Go for all sectors in between first and last
int index = 0 ;
2014-12-03 23:15:26 +00:00
foreach ( Sector s in orderedselection )
{
2013-09-16 11:44:47 +00:00
float u = index / ( float ) ( orderedselection . Count - 1 ) ;
2015-01-16 21:38:42 +00:00
s . Brightness = InterpolationTools . Interpolate ( start . Brightness , end . Brightness , u , interpolationmode ) ; //mxd
2013-03-18 13:52:27 +00:00
index + + ;
}
2009-04-19 18:07:22 +00:00
}
2014-04-02 10:57:52 +00:00
// Update
General . Map . Map . Update ( ) ;
UpdateOverlay ( ) ;
renderer . Present ( ) ;
General . Interface . RedrawDisplay ( ) ;
General . Interface . RefreshInfo ( ) ;
General . Map . IsChanged = true ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-03-18 13:52:27 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "Select at least 3 sectors first!" ) ;
2009-04-19 18:07:22 +00:00
}
}
2015-01-16 21:38:42 +00:00
//mxd
2015-02-20 13:22:43 +00:00
private static void ApplyColorGradient ( ICollection < Sector > orderedselection , Sector start , Sector end , InterpolationTools . Mode interpolationmode , string key , int defaultvalue )
2015-01-16 21:38:42 +00:00
{
if ( ! start . Fields . ContainsKey ( key ) & & ! end . Fields . ContainsKey ( key ) )
{
General . Interface . DisplayStatus ( StatusType . Warning , "First or last selected sector must have the '" + key + "' property!" ) ;
}
else
{
2015-02-20 13:22:43 +00:00
Color startColor , endColor ;
if ( key = = "fadecolor" )
{
startColor = Tools . GetSectorFadeColor ( start ) ;
endColor = Tools . GetSectorFadeColor ( end ) ;
}
else
{
startColor = PixelColor . FromInt ( start . Fields . GetValue ( key , defaultvalue ) ) . ToColor ( ) ;
endColor = PixelColor . FromInt ( end . Fields . GetValue ( key , defaultvalue ) ) . ToColor ( ) ;
}
2015-01-16 21:38:42 +00:00
// Go for all sectors in between first and last
int index = 0 ;
foreach ( Sector s in orderedselection )
{
2015-02-20 13:22:43 +00:00
if ( index > 0 & & index < orderedselection . Count - 1 )
{
s . Fields . BeforeFieldsChange ( ) ;
float u = index / ( float ) ( orderedselection . Count - 1 ) ;
Color c = Color . FromArgb ( 0 , General . Clamp ( InterpolationTools . Interpolate ( startColor . R , endColor . R , u , interpolationmode ) , 0 , 255 ) ,
General . Clamp ( InterpolationTools . Interpolate ( startColor . G , endColor . G , u , interpolationmode ) , 0 , 255 ) ,
General . Clamp ( InterpolationTools . Interpolate ( startColor . B , endColor . B , u , interpolationmode ) , 0 , 255 ) ) ;
UDMFTools . SetInteger ( s . Fields , key , c . ToArgb ( ) , defaultvalue ) ;
s . UpdateNeeded = true ;
}
2015-01-16 21:38:42 +00:00
index + + ;
}
}
}
2009-04-19 18:07:22 +00:00
// Make gradient floors
[BeginAction("gradientfloors")]
public void MakeGradientFloors ( )
{
// Need at least 3 selected sectors
// The first and last are not modified
ICollection < Sector > orderedselection = General . Map . Map . GetSelectedSectors ( true ) ;
2014-12-03 23:15:26 +00:00
if ( orderedselection . Count > 2 )
{
2013-03-18 13:52:27 +00:00
General . Interface . DisplayStatus ( StatusType . Action , "Created gradient floor heights over selected sectors." ) ;
General . Map . UndoRedo . CreateUndo ( "Gradient floor heights" ) ;
2015-01-16 21:38:42 +00:00
int startlevel = General . GetByIndex ( orderedselection , 0 ) . FloorHeight ;
int endlevel = General . GetByIndex ( orderedselection , orderedselection . Count - 1 ) . FloorHeight ;
InterpolationTools . Mode interpolationmode = ( InterpolationTools . Mode ) BuilderPlug . Me . MenusForm . GradientInterpolationMenu . SelectedIndex ; //mxd
2009-04-19 18:07:22 +00:00
// Go for all sectors in between first and last
int index = 0 ;
2014-12-03 23:15:26 +00:00
foreach ( Sector s in orderedselection )
{
2013-09-16 11:44:47 +00:00
float u = index / ( float ) ( orderedselection . Count - 1 ) ;
2015-01-16 21:38:42 +00:00
s . FloorHeight = InterpolationTools . Interpolate ( startlevel , endlevel , u , interpolationmode ) ; //mxd
2009-04-19 18:07:22 +00:00
index + + ;
}
2014-04-02 10:57:52 +00:00
// Update
General . Interface . RefreshInfo ( ) ;
General . Map . IsChanged = true ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-03-18 13:52:27 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "Select at least 3 sectors first!" ) ;
2009-04-19 18:07:22 +00:00
}
}
// Make gradient ceilings
[BeginAction("gradientceilings")]
public void MakeGradientCeilings ( )
{
// Need at least 3 selected sectors
// The first and last are not modified
ICollection < Sector > orderedselection = General . Map . Map . GetSelectedSectors ( true ) ;
2014-12-03 23:15:26 +00:00
if ( orderedselection . Count > 2 )
{
2013-03-18 13:52:27 +00:00
General . Interface . DisplayStatus ( StatusType . Action , "Created gradient ceiling heights over selected sectors." ) ;
General . Map . UndoRedo . CreateUndo ( "Gradient ceiling heights" ) ;
2015-01-16 21:38:42 +00:00
int startlevel = General . GetByIndex ( orderedselection , 0 ) . CeilHeight ;
int endlevel = General . GetByIndex ( orderedselection , orderedselection . Count - 1 ) . CeilHeight ;
InterpolationTools . Mode interpolationmode = ( InterpolationTools . Mode ) BuilderPlug . Me . MenusForm . GradientInterpolationMenu . SelectedIndex ; //mxd
2009-04-19 18:07:22 +00:00
// Go for all sectors in between first and last
int index = 0 ;
2014-12-03 23:15:26 +00:00
foreach ( Sector s in orderedselection )
{
2014-02-21 14:42:12 +00:00
float u = ( float ) index / ( orderedselection . Count - 1 ) ;
2015-01-16 21:38:42 +00:00
s . CeilHeight = InterpolationTools . Interpolate ( startlevel , endlevel , u , interpolationmode ) ;
2009-04-19 18:07:22 +00:00
index + + ;
}
2014-04-02 10:57:52 +00:00
// Update
General . Interface . RefreshInfo ( ) ;
General . Map . IsChanged = true ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-03-18 13:52:27 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "Select at least 3 sectors first!" ) ;
2009-04-19 18:07:22 +00:00
}
}
2014-01-13 08:06:56 +00:00
// Change heights
[BeginAction("lowerfloor8")]
2014-12-03 23:15:26 +00:00
public void LowerFloors8 ( )
{
2014-04-02 10:57:52 +00:00
// Get selection
ICollection < Sector > selected = General . Map . Map . GetSelectedSectors ( true ) ;
if ( selected . Count = = 0 & & highlighted ! = null & & ! highlighted . IsDisposed )
selected . Add ( highlighted ) ;
2014-12-03 23:15:26 +00:00
if ( selected . Count = = 0 )
{
2014-04-02 10:57:52 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "This action requires a selection!" ) ;
return ;
}
// Make undo
2014-01-13 08:06:56 +00:00
General . Interface . DisplayStatus ( StatusType . Action , "Lowered floor heights by 8mp." ) ;
2014-04-02 10:57:52 +00:00
General . Map . UndoRedo . CreateUndo ( "Floor heights change" , this , UndoGroup . FloorHeightChange , CreateSelectionCRC ( selected ) ) ;
2014-01-13 08:06:56 +00:00
// Change heights
2014-12-03 23:15:26 +00:00
foreach ( Sector s in selected ) s . FloorHeight - = 8 ;
2014-01-13 08:06:56 +00:00
// Update
General . Interface . RefreshInfo ( ) ;
General . Map . IsChanged = true ;
}
// Change heights
[BeginAction("raisefloor8")]
2014-12-03 23:15:26 +00:00
public void RaiseFloors8 ( )
{
2014-04-02 10:57:52 +00:00
// Get selection
ICollection < Sector > selected = General . Map . Map . GetSelectedSectors ( true ) ;
if ( selected . Count = = 0 & & highlighted ! = null & & ! highlighted . IsDisposed )
selected . Add ( highlighted ) ;
2014-12-03 23:15:26 +00:00
if ( selected . Count = = 0 )
{
2014-04-02 10:57:52 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "This action requires a selection!" ) ;
return ;
}
// Make undo
2014-01-13 08:06:56 +00:00
General . Interface . DisplayStatus ( StatusType . Action , "Raised floor heights by 8mp." ) ;
2014-04-02 10:57:52 +00:00
General . Map . UndoRedo . CreateUndo ( "Floor heights change" , this , UndoGroup . FloorHeightChange , CreateSelectionCRC ( selected ) ) ;
2014-01-13 08:06:56 +00:00
// Change heights
2014-12-03 23:15:26 +00:00
foreach ( Sector s in selected ) s . FloorHeight + = 8 ;
2014-01-13 08:06:56 +00:00
// Update
General . Interface . RefreshInfo ( ) ;
General . Map . IsChanged = true ;
}
// Change heights
[BeginAction("lowerceiling8")]
2014-12-03 23:15:26 +00:00
public void LowerCeilings8 ( )
{
2014-04-02 10:57:52 +00:00
// Get selection
ICollection < Sector > selected = General . Map . Map . GetSelectedSectors ( true ) ;
if ( ( selected . Count = = 0 ) & & ( highlighted ! = null ) & & ! highlighted . IsDisposed )
selected . Add ( highlighted ) ;
2014-12-03 23:15:26 +00:00
if ( selected . Count = = 0 )
{
2014-04-02 10:57:52 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "This action requires a selection!" ) ;
return ;
}
// Make undo
2014-01-13 08:06:56 +00:00
General . Interface . DisplayStatus ( StatusType . Action , "Lowered ceiling heights by 8mp." ) ;
2014-04-02 10:57:52 +00:00
General . Map . UndoRedo . CreateUndo ( "Ceiling heights change" , this , UndoGroup . CeilingHeightChange , CreateSelectionCRC ( selected ) ) ;
2014-01-13 08:06:56 +00:00
// Change heights
2014-12-03 23:15:26 +00:00
foreach ( Sector s in selected ) s . CeilHeight - = 8 ;
2014-01-13 08:06:56 +00:00
// Update
General . Interface . RefreshInfo ( ) ;
General . Map . IsChanged = true ;
}
// Change heights
[BeginAction("raiseceiling8")]
2014-12-03 23:15:26 +00:00
public void RaiseCeilings8 ( )
{
2014-04-02 10:57:52 +00:00
// Get selection
ICollection < Sector > selected = General . Map . Map . GetSelectedSectors ( true ) ;
if ( selected . Count = = 0 & & highlighted ! = null & & ! highlighted . IsDisposed )
selected . Add ( highlighted ) ;
2014-12-03 23:15:26 +00:00
if ( selected . Count = = 0 )
{
2014-04-02 10:57:52 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "This action requires a selection!" ) ;
return ;
}
// Make undo
2014-01-13 08:06:56 +00:00
General . Interface . DisplayStatus ( StatusType . Action , "Raised ceiling heights by 8mp." ) ;
2014-04-02 10:57:52 +00:00
General . Map . UndoRedo . CreateUndo ( "Ceiling heights change" , this , UndoGroup . CeilingHeightChange , CreateSelectionCRC ( selected ) ) ;
2014-01-13 08:06:56 +00:00
// Change heights
2014-12-03 23:15:26 +00:00
foreach ( Sector s in selected ) s . CeilHeight + = 8 ;
2014-01-13 08:06:56 +00:00
// Update
General . Interface . RefreshInfo ( ) ;
General . Map . IsChanged = true ;
}
2013-09-16 11:44:47 +00:00
//mxd. Raise brightness
[BeginAction("raisebrightness8")]
2014-12-03 23:15:26 +00:00
public void RaiseBrightness8 ( )
{
2014-04-02 10:57:52 +00:00
// Get selection
ICollection < Sector > selected = General . Map . Map . GetSelectedSectors ( true ) ;
if ( ( selected . Count = = 0 ) & & ( highlighted ! = null ) & & ! highlighted . IsDisposed )
selected . Add ( highlighted ) ;
2014-12-03 23:15:26 +00:00
if ( selected . Count = = 0 )
{
2014-04-02 10:57:52 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "This action requires a selection!" ) ;
return ;
}
// Make undo
2015-05-11 20:17:50 +00:00
Sector first = General . GetByIndex ( selected , 0 ) ; //mxd
int diff = General . Map . Config . BrightnessLevels . GetNextHigher ( first . Brightness ) - first . Brightness ; //mxd
General . Interface . DisplayStatus ( StatusType . Action , "Raised sector brightness by " + diff + "." ) ;
2014-04-02 10:57:52 +00:00
General . Map . UndoRedo . CreateUndo ( "Sector brightness change" , this , UndoGroup . SectorBrightnessChange , CreateSelectionCRC ( selected ) ) ;
2009-04-19 18:07:22 +00:00
// Change heights
2014-12-03 23:15:26 +00:00
foreach ( Sector s in selected )
{
2013-09-16 11:44:47 +00:00
s . Brightness = General . Map . Config . BrightnessLevels . GetNextHigher ( s . Brightness ) ;
s . UpdateNeeded = true ;
s . UpdateCache ( ) ;
2009-04-19 18:07:22 +00:00
}
// Update
General . Interface . RefreshInfo ( ) ;
General . Map . IsChanged = true ;
2013-09-16 11:44:47 +00:00
// Redraw
General . Interface . RedrawDisplay ( ) ;
2009-04-19 18:07:22 +00:00
}
2013-09-16 11:44:47 +00:00
//mxd. Lower brightness
[BeginAction("lowerbrightness8")]
2014-12-03 23:15:26 +00:00
public void LowerBrightness8 ( )
{
2014-04-02 10:57:52 +00:00
// Get selection
ICollection < Sector > selected = General . Map . Map . GetSelectedSectors ( true ) ;
if ( selected . Count = = 0 & & highlighted ! = null & & ! highlighted . IsDisposed )
selected . Add ( highlighted ) ;
2014-12-03 23:15:26 +00:00
if ( selected . Count = = 0 )
{
2014-04-02 10:57:52 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "This action requires a selection!" ) ;
return ;
}
// Make undo
2015-05-11 20:17:50 +00:00
Sector first = General . GetByIndex ( selected , 0 ) ; //mxd
int diff = first . Brightness - General . Map . Config . BrightnessLevels . GetNextLower ( first . Brightness ) ; //mxd
General . Interface . DisplayStatus ( StatusType . Action , "Lowered sector brightness by " + diff + "." ) ;
2014-04-02 10:57:52 +00:00
General . Map . UndoRedo . CreateUndo ( "Sector brightness change" , this , UndoGroup . SectorBrightnessChange , CreateSelectionCRC ( selected ) ) ;
2009-04-19 18:07:22 +00:00
// Change heights
2014-12-03 23:15:26 +00:00
foreach ( Sector s in selected )
{
2013-09-16 11:44:47 +00:00
s . Brightness = General . Map . Config . BrightnessLevels . GetNextLower ( s . Brightness ) ;
s . UpdateNeeded = true ;
s . UpdateCache ( ) ;
2009-04-19 18:07:22 +00:00
}
// Update
General . Interface . RefreshInfo ( ) ;
General . Map . IsChanged = true ;
2013-09-16 11:44:47 +00:00
// Redraw
General . Interface . RedrawDisplay ( ) ;
2009-04-19 18:07:22 +00:00
}
// This clears the selection
[BeginAction("clearselection", BaseAction = true)]
public void ClearSelection ( )
{
// Clear selection
General . Map . Map . ClearAllSelected ( ) ;
2013-12-12 09:07:30 +00:00
//mxd. Clear selection info
General . Interface . DisplayStatus ( StatusType . Selection , string . Empty ) ;
2013-07-09 11:29:10 +00:00
2009-04-19 18:07:22 +00:00
// Clear labels
foreach ( TextLabel [ ] labelarray in labels . Values )
foreach ( TextLabel l in labelarray ) l . Text = "" ;
2014-12-03 23:15:26 +00:00
UpdateOverlaySurfaces ( ) ; //mxd
UpdateEffectLabels ( ) ; //mxd
2009-04-19 18:07:22 +00:00
// Redraw
General . Interface . RedrawDisplay ( ) ;
}
2013-09-11 13:14:45 +00:00
[BeginAction("placethings")] //mxd
2014-12-03 23:15:26 +00:00
public void PlaceThings ( )
{
2013-09-11 13:14:45 +00:00
// Make list of selected sectors
ICollection < Sector > sectors = General . Map . Map . GetSelectedSectors ( true ) ;
List < Vector2D > positions = new List < Vector2D > ( ) ;
2014-12-03 23:15:26 +00:00
if ( sectors . Count = = 0 )
{
if ( highlighted ! = null & & ! highlighted . IsDisposed )
{
2013-09-11 13:14:45 +00:00
sectors . Add ( highlighted ) ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-09-11 13:14:45 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "This action requires selection of some description!" ) ;
return ;
}
}
// Make list of suitable positions
2014-12-03 23:15:26 +00:00
foreach ( Sector s in sectors )
{
2013-09-11 13:57:27 +00:00
Vector2D pos = ( s . Labels . Count > 0 ? s . Labels [ 0 ] . position : new Vector2D ( s . BBox . X + s . BBox . Width / 2 , s . BBox . Y + s . BBox . Height / 2 ) ) ;
if ( ! positions . Contains ( pos ) ) positions . Add ( pos ) ;
2013-09-11 13:14:45 +00:00
}
2014-12-03 23:15:26 +00:00
if ( positions . Count < 1 )
{
2013-09-11 13:14:45 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "Unable to get vertex positions from selection!" ) ;
return ;
}
2014-12-03 23:15:26 +00:00
PlaceThingsAtPositions ( positions ) ;
2013-09-11 13:14:45 +00:00
}
2014-04-02 10:57:52 +00:00
//mxd. rotate clockwise
[BeginAction("rotateclockwise")]
2014-12-03 23:15:26 +00:00
public void RotateCW ( )
{
RotateTextures ( 5 ) ;
2014-04-02 10:57:52 +00:00
}
//mxd. rotate counterclockwise
[BeginAction("rotatecounterclockwise")]
2014-12-03 23:15:26 +00:00
public void RotateCCW ( )
{
RotateTextures ( - 5 ) ;
2014-04-02 10:57:52 +00:00
}
//mxd
2014-12-03 23:15:26 +00:00
private void RotateTextures ( float increment )
{
if ( ! General . Map . UDMF )
{
2014-04-02 10:57:52 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "This action works only in UDMF map format!" ) ;
return ;
}
// Make list of selected sectors
ICollection < Sector > sectors = General . Map . Map . GetSelectedSectors ( true ) ;
if ( sectors . Count = = 0 & & highlighted ! = null & & ! highlighted . IsDisposed )
sectors . Add ( highlighted ) ;
2014-12-03 23:15:26 +00:00
if ( sectors . Count = = 0 )
{
2014-04-02 10:57:52 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "This action requires a selection!" ) ;
return ;
}
string targets ;
string target ;
2014-12-03 23:15:26 +00:00
switch ( General . Map . Renderer2D . ViewMode )
{
2014-04-02 10:57:52 +00:00
case ViewMode . FloorTextures :
target = " a floor" ;
targets = " floors" ;
break ;
case ViewMode . CeilingTextures :
target = " a ceiling" ;
targets = " ceilings" ;
break ;
default :
target = " a floor and a ceiling" ;
targets = " floors and ceilings" ;
break ;
}
// Make undo
2014-12-03 23:15:26 +00:00
if ( sectors . Count > 1 )
{
2014-04-02 10:57:52 +00:00
General . Map . UndoRedo . CreateUndo ( "Rotate " + sectors . Count + targets , this , UndoGroup . TextureRotationChange , CreateSelectionCRC ( sectors ) ) ;
General . Interface . DisplayStatus ( StatusType . Action , "Rotated " + sectors . Count + targets + "." ) ;
2014-12-03 23:15:26 +00:00
}
else
{
2014-04-02 10:57:52 +00:00
General . Map . UndoRedo . CreateUndo ( "Rotate" + target , this , UndoGroup . TextureRotationChange , CreateSelectionCRC ( sectors ) ) ;
General . Interface . DisplayStatus ( StatusType . Action , "Rotated" + target + "." ) ;
}
//rotate stuff
2014-12-03 23:15:26 +00:00
foreach ( Sector s in sectors )
{
2014-04-02 10:57:52 +00:00
s . Fields . BeforeFieldsChange ( ) ;
//floor
2014-12-03 23:15:26 +00:00
if ( General . Map . Renderer2D . ViewMode = = ViewMode . FloorTextures | | General . Map . Renderer2D . ViewMode ! = ViewMode . CeilingTextures )
{
2014-04-02 10:57:52 +00:00
UDMFTools . SetFloat ( s . Fields , "rotationfloor" , General . ClampAngle ( UDMFTools . GetFloat ( s . Fields , "rotationfloor" ) + increment ) ) ;
s . UpdateNeeded = true ;
}
//ceiling
2014-12-03 23:15:26 +00:00
if ( General . Map . Renderer2D . ViewMode = = ViewMode . CeilingTextures | | General . Map . Renderer2D . ViewMode ! = ViewMode . FloorTextures )
{
2014-04-02 10:57:52 +00:00
UDMFTools . SetFloat ( s . Fields , "rotationceiling" , General . ClampAngle ( UDMFTools . GetFloat ( s . Fields , "rotationceiling" ) + increment ) ) ;
s . UpdateNeeded = true ;
}
}
// Redraw screen
General . Map . Map . Update ( ) ;
General . Interface . RedrawDisplay ( ) ;
General . Interface . RefreshInfo ( ) ;
}
2014-05-08 09:24:32 +00:00
//mxd
[BeginAction("selectsimilar")]
2014-12-03 23:15:26 +00:00
public void SelectSimilar ( )
{
2014-05-08 09:24:32 +00:00
ICollection < Sector > selection = General . Map . Map . GetSelectedSectors ( true ) ;
2014-12-03 23:15:26 +00:00
if ( selection . Count = = 0 )
{
2014-05-08 09:24:32 +00:00
General . Interface . DisplayStatus ( StatusType . Warning , "This action requires a selection!" ) ;
return ;
}
var form = new SelectSimilarElementOptionsPanel ( ) ;
if ( form . Setup ( this ) ) form . ShowDialog ( ) ;
}
2009-04-19 18:07:22 +00:00
2014-07-07 14:17:49 +00:00
//mxd
[BeginAction("fliplinedefs")]
public void FlipLinedefs ( )
{
// Get selection
ICollection < Sector > selection = General . Map . Map . GetSelectedSectors ( true ) ;
if ( selection . Count = = 0 & & highlighted ! = null & & ! highlighted . IsDisposed )
selection . Add ( highlighted ) ;
if ( selection . Count = = 0 )
{
General . Interface . DisplayStatus ( StatusType . Warning , "This action requires a selection!" ) ;
return ;
}
// Make undo
if ( selection . Count > 1 )
{
General . Map . UndoRedo . CreateUndo ( "Flip linedefs of " + selection . Count + " sectors" ) ;
General . Interface . DisplayStatus ( StatusType . Action , "Flipped linedefs of " + selection . Count + "sectors." ) ;
}
else
{
General . Map . UndoRedo . CreateUndo ( "Flip sector linedefs" ) ;
General . Interface . DisplayStatus ( StatusType . Action , "Flipped sector linedefs." ) ;
}
// Flip lines
Tools . FlipSectorLinedefs ( selection , false ) ;
// Redraw
General . Map . Map . Update ( ) ;
General . Map . IsChanged = true ;
General . Interface . RefreshInfo ( ) ;
General . Interface . RedrawDisplay ( ) ;
}
2009-04-19 18:07:22 +00:00
#endregion
}
}