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 ;
2014-12-22 21:36:49 +00:00
using System.Drawing ;
2009-04-19 18:07:22 +00:00
using System.Windows.Forms ;
using CodeImp.DoomBuilder.Data ;
2014-12-22 21:36:49 +00:00
using CodeImp.DoomBuilder.Geometry ;
using CodeImp.DoomBuilder.GZBuilder.Tools ;
2009-04-19 18:07:22 +00:00
using CodeImp.DoomBuilder.IO ;
using CodeImp.DoomBuilder.Map ;
using CodeImp.DoomBuilder.Rendering ;
2014-12-22 21:36:49 +00:00
using CodeImp.DoomBuilder.Types ;
2009-04-19 18:07:22 +00:00
using CodeImp.DoomBuilder.VisualModes ;
2015-03-03 09:42:54 +00:00
using System.Globalization ;
2009-04-19 18:07:22 +00:00
#endregion
namespace CodeImp.DoomBuilder.BuilderModes
{
internal abstract class BaseVisualGeometrySidedef : VisualGeometry , IVisualEventReceiver
{
#region = = = = = = = = = = = = = = = = = = Constants
private const float DRAG_ANGLE_TOLERANCE = 0.06f ;
#endregion
#region = = = = = = = = = = = = = = = = = = Variables
2014-12-22 21:36:49 +00:00
protected readonly BaseVisualMode mode ;
2009-04-19 18:07:22 +00:00
2012-11-27 21:12:20 +00:00
protected Plane top ;
protected Plane bottom ;
2009-04-19 18:07:22 +00:00
protected long setuponloadedtexture ;
// UV dragging
private float dragstartanglexy ;
private float dragstartanglez ;
private Vector3D dragorigin ;
private Vector3D deltaxy ;
private Vector3D deltaz ;
private int startoffsetx ;
private int startoffsety ;
protected bool uvdragging ;
2009-05-03 19:22:32 +00:00
private int prevoffsetx ; // We have to provide delta offsets, but I don't
private int prevoffsety ; // want to calculate with delta offsets to prevent
// inaccuracy in the dragging.
2013-07-19 15:30:58 +00:00
private static List < BaseVisualSector > updateList ; //mxd
2009-04-19 18:07:22 +00:00
// Undo/redo
private int undoticket ;
#endregion
#region = = = = = = = = = = = = = = = = = = Properties
public bool IsDraggingUV { get { return uvdragging ; } }
new public BaseVisualSector Sector { get { return ( BaseVisualSector ) base . Sector ; } }
#endregion
#region = = = = = = = = = = = = = = = = = = Constructor / Destructor
// Constructor for sidedefs
public BaseVisualGeometrySidedef ( BaseVisualMode mode , VisualSector vs , Sidedef sd ) : base ( vs , sd )
{
this . mode = mode ;
this . deltaz = new Vector3D ( 0.0f , 0.0f , 1.0f ) ;
this . deltaxy = ( sd . Line . End . Position - sd . Line . Start . Position ) * sd . Line . LengthInv ;
if ( ! sd . IsFront ) this . deltaxy = - this . deltaxy ;
2013-03-18 13:52:27 +00:00
//mxd
2014-12-03 23:15:26 +00:00
if ( mode . UseSelectionFromClassicMode & & sd . Line . Selected )
{
2013-03-18 13:52:27 +00:00
this . selected = true ;
mode . AddSelectedObject ( this ) ;
}
2009-04-19 18:07:22 +00:00
}
#endregion
#region = = = = = = = = = = = = = = = = = = Methods
2012-11-27 21:12:20 +00:00
// This sets the renderstyle from linedef information and returns the alpha value or the vertices
protected byte SetLinedefRenderstyle ( bool solidasmask )
{
2014-02-21 14:42:12 +00:00
byte alpha ;
2012-11-27 21:12:20 +00:00
// From TranslucentLine action
if ( Sidedef . Line . Action = = 208 )
{
alpha = ( byte ) General . Clamp ( Sidedef . Line . Args [ 1 ] , 0 , 255 ) ;
if ( Sidedef . Line . Args [ 2 ] = = 1 )
this . RenderPass = RenderPass . Additive ;
else if ( alpha < 255 )
this . RenderPass = RenderPass . Alpha ;
else if ( solidasmask )
this . RenderPass = RenderPass . Mask ;
else
this . RenderPass = RenderPass . Solid ;
}
else
{
// From UDMF field
string field = Sidedef . Line . Fields . GetValue ( "renderstyle" , "translucent" ) ;
alpha = ( byte ) ( Sidedef . Line . Fields . GetValue ( "alpha" , 1.0f ) * 255.0f ) ;
2015-02-06 09:01:33 +00:00
if ( alpha = = 255 & & Sidedef . Line . IsFlagSet ( "transparent" ) ) alpha = 64 ; //mxd
2014-05-05 14:24:57 +00:00
2012-11-27 21:12:20 +00:00
if ( field = = "add" )
this . RenderPass = RenderPass . Additive ;
else if ( alpha < 255 )
this . RenderPass = RenderPass . Alpha ;
else if ( solidasmask )
this . RenderPass = RenderPass . Mask ;
else
this . RenderPass = RenderPass . Solid ;
}
return alpha ;
}
2009-04-19 18:07:22 +00:00
// This performs a fast test in object picking
public override bool PickFastReject ( Vector3D from , Vector3D to , Vector3D dir )
{
// Check if intersection point is between top and bottom
2012-11-27 21:12:20 +00:00
return ( pickintersect . z > = bottom . GetZ ( pickintersect ) ) & & ( pickintersect . z < = top . GetZ ( pickintersect ) ) ;
2009-04-19 18:07:22 +00:00
}
2012-11-27 21:12:20 +00:00
2009-04-19 18:07:22 +00:00
// This performs an accurate test for object picking
public override bool PickAccurate ( Vector3D from , Vector3D to , Vector3D dir , ref float u_ray )
{
// The fast reject pass is already as accurate as it gets,
// so we just return the intersection distance here
u_ray = pickrayu ;
return true ;
}
2012-11-27 21:12:20 +00:00
// This creates vertices from a wall polygon and applies lighting
2015-02-06 09:01:33 +00:00
/ * protected List < WorldVertex > CreatePolygonVertices ( WallPolygon poly , TexturePlane tp , SectorData sd , int lightvalue , bool lightabsolute )
2012-11-27 21:12:20 +00:00
{
List < WallPolygon > polylist = new List < WallPolygon > ( 1 ) ;
polylist . Add ( poly ) ;
return CreatePolygonVertices ( polylist , tp , sd , lightvalue , lightabsolute ) ;
2015-02-06 09:01:33 +00:00
} * /
2012-11-27 21:12:20 +00:00
// This creates vertices from a wall polygon and applies lighting
protected List < WorldVertex > CreatePolygonVertices ( List < WallPolygon > poly , TexturePlane tp , SectorData sd , int lightvalue , bool lightabsolute )
{
List < WallPolygon > polygons = new List < WallPolygon > ( poly ) ;
List < WorldVertex > verts = new List < WorldVertex > ( ) ;
2015-04-01 12:51:26 +00:00
SectorLevel prevlight = null ; //mxd
2012-11-27 21:12:20 +00:00
// Go for all levels to build geometry
for ( int i = sd . LightLevels . Count - 1 ; i > = 0 ; i - - )
{
SectorLevel l = sd . LightLevels [ i ] ;
2015-04-01 12:51:26 +00:00
//mxd. Skip current light level when it's between TYPE1 and TYPE1_BOTTOM
if ( prevlight ! = null
& & prevlight . type = = SectorLevelType . Light & & l . type = = SectorLevelType . Light
& & ( prevlight . lighttype = = LightLevelType . TYPE1 & & l . lighttype ! = LightLevelType . TYPE1_BOTTOM ) )
continue ;
2015-02-25 19:59:17 +00:00
if ( ( l ! = sd . Floor ) & & ( l ! = sd . Ceiling ) & & ( l . type ! = SectorLevelType . Floor | | l . alpha < 255 ) )
2012-11-27 21:12:20 +00:00
{
2013-09-11 09:47:53 +00:00
// Go for all polygons
2012-11-27 21:12:20 +00:00
int num = polygons . Count ;
2015-02-26 14:42:58 +00:00
Plane plane = ( l . type = = SectorLevelType . Floor ? l . plane . GetInverted ( ) : l . plane ) ; //mxd
2015-02-25 19:59:17 +00:00
2012-11-27 21:12:20 +00:00
for ( int pi = 0 ; pi < num ; pi + + )
{
// Split by plane
WallPolygon p = polygons [ pi ] ;
2015-02-25 19:59:17 +00:00
WallPolygon np = SplitPoly ( ref p , plane , false ) ;
2012-11-27 21:12:20 +00:00
if ( np . Count > 0 )
{
2015-02-25 19:59:17 +00:00
//mxd. Determine color
int lightlevel ;
if ( l . disablelighting ) //sidedef part is not affected by 3d floor brightness
{
lightlevel = lightabsolute ? lightvalue : l . brightnessbelow + lightvalue ;
}
else if ( l . restrictlighting | | ( l . type = = SectorLevelType . Floor & & l . alpha < 255 ) ) //only happens to a sidedef part inside of a non-opaque 3d floor.
{
lightlevel = l . sector . Brightness ;
}
else // "Regular" 3d floor transfers brightness below it ignoring sidedef's brightness.
{
lightlevel = l . brightnessbelow ;
}
2013-08-07 09:25:37 +00:00
PixelColor wallbrightness = PixelColor . FromInt ( mode . CalculateBrightness ( lightlevel , Sidedef ) ) ; //mxd
2015-04-14 11:33:57 +00:00
np . color = PixelColor . Modulate ( l . colorbelow , wallbrightness ) . WithAlpha ( 255 ) . ToInt ( ) ;
2012-11-27 21:12:20 +00:00
if ( p . Count = = 0 )
{
polygons [ pi ] = np ;
}
else
{
polygons [ pi ] = p ;
polygons . Add ( np ) ;
}
}
else
{
polygons [ pi ] = p ;
}
}
}
2015-04-14 11:33:57 +00:00
//mxd
if ( l . type = = SectorLevelType . Light ) prevlight = l ;
2012-11-27 21:12:20 +00:00
}
// Go for all polygons to make geometry
foreach ( WallPolygon p in polygons )
{
// Find texture coordinates for each vertex in the polygon
List < Vector2D > texc = new List < Vector2D > ( p . Count ) ;
2015-04-14 11:33:57 +00:00
foreach ( Vector3D v in p ) texc . Add ( tp . GetTextureCoordsAt ( v ) ) ;
2012-11-27 21:12:20 +00:00
// Now we create triangles from the polygon.
// The polygon is convex and clockwise, so this is a piece of cake.
2015-04-14 11:33:57 +00:00
if ( p . Count > 2 )
2012-11-27 21:12:20 +00:00
{
for ( int k = 1 ; k < ( p . Count - 1 ) ; k + + )
{
verts . Add ( new WorldVertex ( p [ 0 ] , p . color , texc [ 0 ] ) ) ;
verts . Add ( new WorldVertex ( p [ k ] , p . color , texc [ k ] ) ) ;
verts . Add ( new WorldVertex ( p [ k + 1 ] , p . color , texc [ k + 1 ] ) ) ;
}
}
}
2015-04-14 11:33:57 +00:00
//mxd. Interpolate vertex colors?
if ( sd . CeilingGlow ! = null | | sd . FloorGlow ! = null )
{
for ( int i = 0 ; i < verts . Count ; i + + )
verts [ i ] = InterpolateVertexColor ( verts [ i ] , sd ) ;
}
2012-11-27 21:12:20 +00:00
return verts ;
}
2015-04-14 11:33:57 +00:00
//mxd
private static WorldVertex InterpolateVertexColor ( WorldVertex v , SectorData data )
{
// Apply ceiling glow?
if ( data . CeilingGlow ! = null )
{
float cgz = data . CeilingGlowPlane . GetZ ( v . x , v . y ) ;
// Vertex is above ceiling glow plane?
if ( v . z > cgz )
{
float cz = data . Ceiling . plane . GetZ ( v . x , v . y ) ;
float delta = ( ( v . z - cgz ) / ( cz - cgz ) ) * 0.9f ;
PixelColor vc = PixelColor . FromInt ( v . c ) ;
v . c = InterpolationTools . InterpolateColor ( PixelColor . Add ( vc , data . CeilingGlow . Color ) , vc , delta ) ;
}
}
// Apply floor glow?
if ( data . FloorGlow ! = null )
{
float fgz = data . FloorGlowPlane . GetZ ( v . x , v . y ) ;
// Vertex is below floor glow plane?
if ( v . z < fgz )
{
float fz = data . Floor . plane . GetZ ( v . x , v . y ) ;
float delta = ( ( v . z - fz ) / ( fgz - fz ) ) * 0.9f ;
PixelColor vc = PixelColor . FromInt ( v . c ) ;
v . c = InterpolationTools . InterpolateColor ( vc , PixelColor . Add ( vc , data . FloorGlow . Color ) , delta ) ;
}
}
return v ;
}
2012-11-27 21:12:20 +00:00
// This splits a polygon with a plane and returns the other part as a new polygon
// The polygon is expected to be convex and clockwise
2014-12-22 21:36:49 +00:00
protected static WallPolygon SplitPoly ( ref WallPolygon poly , Plane p , bool keepfront )
2012-11-27 21:12:20 +00:00
{
const float NEAR_ZERO = 0.01f ;
WallPolygon front = new WallPolygon ( poly . Count ) ;
WallPolygon back = new WallPolygon ( poly . Count ) ;
poly . CopyProperties ( front ) ;
poly . CopyProperties ( back ) ;
if ( poly . Count > 0 )
{
// Go for all vertices to see which side they have to be on
Vector3D v1 = poly [ poly . Count - 1 ] ;
float side1 = p . Distance ( v1 ) ;
for ( int i = 0 ; i < poly . Count ; i + + )
{
// Fetch vertex and determine side
Vector3D v2 = poly [ i ] ;
float side2 = p . Distance ( v2 ) ;
// Front?
if ( side2 > NEAR_ZERO )
{
if ( side1 < - NEAR_ZERO )
{
// Split line with plane and insert the vertex
float u = 0.0f ;
p . GetIntersection ( v1 , v2 , ref u ) ;
Vector3D v3 = v1 + ( v2 - v1 ) * u ;
front . Add ( v3 ) ;
back . Add ( v3 ) ;
}
front . Add ( v2 ) ;
}
// Back?
else if ( side2 < - NEAR_ZERO )
{
if ( side1 > NEAR_ZERO )
{
// Split line with plane and insert the vertex
float u = 0.0f ;
p . GetIntersection ( v1 , v2 , ref u ) ;
Vector3D v3 = v1 + ( v2 - v1 ) * u ;
front . Add ( v3 ) ;
back . Add ( v3 ) ;
}
back . Add ( v2 ) ;
}
else
{
// On the plane, add to both polygons
front . Add ( v2 ) ;
back . Add ( v2 ) ;
}
// Next
v1 = v2 ;
side1 = side2 ;
}
}
if ( keepfront )
{
poly = front ;
return back ;
}
else
{
poly = back ;
return front ;
}
}
// This crops a polygon with a plane and keeps only a certain part of the polygon
2014-12-22 21:36:49 +00:00
protected static void CropPoly ( ref WallPolygon poly , Plane p , bool keepfront )
2012-11-27 21:12:20 +00:00
{
const float NEAR_ZERO = 0.01f ;
float sideswitch = keepfront ? 1 : - 1 ;
WallPolygon newp = new WallPolygon ( poly . Count ) ;
poly . CopyProperties ( newp ) ;
if ( poly . Count > 0 )
{
// First split lines that cross the plane so that we have vertices on the plane where the lines cross
Vector3D v1 = poly [ poly . Count - 1 ] ;
float side1 = p . Distance ( v1 ) * sideswitch ;
for ( int i = 0 ; i < poly . Count ; i + + )
{
// Fetch vertex and determine side
Vector3D v2 = poly [ i ] ;
float side2 = p . Distance ( v2 ) * sideswitch ;
// Front?
if ( side2 > NEAR_ZERO )
{
if ( side1 < - NEAR_ZERO )
{
// Split line with plane and insert the vertex
float u = 0.0f ;
p . GetIntersection ( v1 , v2 , ref u ) ;
Vector3D v3 = v1 + ( v2 - v1 ) * u ;
newp . Add ( v3 ) ;
}
newp . Add ( v2 ) ;
}
// Back?
else if ( side2 < - NEAR_ZERO )
{
if ( side1 > NEAR_ZERO )
{
// Split line with plane and insert the vertex
float u = 0.0f ;
p . GetIntersection ( v1 , v2 , ref u ) ;
Vector3D v3 = v1 + ( v2 - v1 ) * u ;
newp . Add ( v3 ) ;
}
}
else
{
// On the plane
newp . Add ( v2 ) ;
}
// Next
v1 = v2 ;
side1 = side2 ;
}
}
poly = newp ;
}
2015-02-06 09:01:33 +00:00
//mxd
protected void GetLightValue ( out int lightvalue , out bool lightabsolute )
{
2015-02-06 21:03:20 +00:00
lightabsolute = Sidedef . Fields . GetValue ( "lightabsolute" , false ) ;
2015-02-06 09:01:33 +00:00
bool affectedbyfog = General . Map . Data . MapInfo . HasFadeColor | | ( Sector . Sector . CeilTexture = = General . Map . Config . SkyFlatName & & General . Map . Data . MapInfo . HasOutsideFogColor ) | | Sector . Sector . Fields . ContainsKey ( "fadecolor" ) ;
bool ignorelight = affectedbyfog & & ! Sidedef . IsFlagSet ( "lightfog" ) & & ! lightabsolute ;
lightvalue = ignorelight ? 0 : Sidedef . Fields . GetValue ( "light" , 0 ) ; //mxd
if ( ignorelight ) lightabsolute = false ;
}
2013-09-11 09:47:53 +00:00
//mxd
2014-12-22 21:36:49 +00:00
protected static float GetRoundedTextureOffset ( float oldValue , float offset , float scale , float textureSize )
2014-12-03 23:15:26 +00:00
{
2012-11-27 21:12:20 +00:00
if ( offset = = 0f ) return oldValue ;
Visual mode, UDMF: added "Scale Texture Up (X)", "Scale Texture Down (X)", "Scale Texture Up (Y)", "Scale Texture Down (Y)" actions. Default keys are Num6, Num4, Num8, Num5.
Visual mode, UDMF: renamed "Rotate Thing Clockwise" and "Rotate Thing Counterclockwise" actions to "Rotate Clockwise" and "Rotate Counterclockwise". These actions can now be used to change rotation of floor/ceiling textures.
Visual mode, UDMF: "Reset Texture Offsets" action now also resets sidedef's scale and floor/ceiling's scale and rotation.
Visual mode, UDMF: control line's OffsetX and OffsetY were not taken into account when calculating texture offsets of 3d floors' sides.
Visual mode, UDMF: fixed a ton of bugs in Auto align functions.
Visual mode, UDMF: when using "Move Texture Left/Right/Up/Down by 1" actions texture offsets were not updated properly when texture's scale was < 1.0.
Visual mode, UDMF: OffsetX and OffsetY were not taken into account in "Fit Texture Width/Height" actions.
Dockers Panel: added Pin/Unpin button, which acts the same as "Preferences -> Interface -> Side panels -> Auto hide" checkbox.
Texture size labels can now be disabled by unchecking "Preferences -> Interface -> Show texture and flat sizes in browsers" checkbox.
Texture size labels now are not shown for unknown textures.
Most of texture size labels had incorrect bg color.
ZDoom_linedefs.cfg: action specials 223 and 224 had incorrect Arg0.
2013-06-24 14:21:13 +00:00
float scaledOffset = offset * scale ;
2013-08-28 14:53:21 +00:00
float result = ( float ) Math . Round ( oldValue + scaledOffset ) ;
if ( textureSize > 0 ) result % = textureSize ;
Visual mode, UDMF: added "Scale Texture Up (X)", "Scale Texture Down (X)", "Scale Texture Up (Y)", "Scale Texture Down (Y)" actions. Default keys are Num6, Num4, Num8, Num5.
Visual mode, UDMF: renamed "Rotate Thing Clockwise" and "Rotate Thing Counterclockwise" actions to "Rotate Clockwise" and "Rotate Counterclockwise". These actions can now be used to change rotation of floor/ceiling textures.
Visual mode, UDMF: "Reset Texture Offsets" action now also resets sidedef's scale and floor/ceiling's scale and rotation.
Visual mode, UDMF: control line's OffsetX and OffsetY were not taken into account when calculating texture offsets of 3d floors' sides.
Visual mode, UDMF: fixed a ton of bugs in Auto align functions.
Visual mode, UDMF: when using "Move Texture Left/Right/Up/Down by 1" actions texture offsets were not updated properly when texture's scale was < 1.0.
Visual mode, UDMF: OffsetX and OffsetY were not taken into account in "Fit Texture Width/Height" actions.
Dockers Panel: added Pin/Unpin button, which acts the same as "Preferences -> Interface -> Side panels -> Auto hide" checkbox.
Texture size labels can now be disabled by unchecking "Preferences -> Interface -> Show texture and flat sizes in browsers" checkbox.
Texture size labels now are not shown for unknown textures.
Most of texture size labels had incorrect bg color.
ZDoom_linedefs.cfg: action specials 223 and 224 had incorrect Arg0.
2013-06-24 14:21:13 +00:00
if ( result = = oldValue ) result + = ( scaledOffset < 0 ? - 1 : 1 ) ;
2013-09-11 09:47:53 +00:00
return result ;
}
2013-03-18 13:52:27 +00:00
//mxd
2014-12-22 21:36:49 +00:00
private void OnTextureChanged ( )
2014-12-03 23:15:26 +00:00
{
2013-03-18 13:52:27 +00:00
//check for 3d floors
2014-12-03 23:15:26 +00:00
if ( Sidedef . Line . Action = = 160 )
{
2013-03-18 13:52:27 +00:00
int sectortag = Sidedef . Line . Args [ 0 ] + ( Sidedef . Line . Args [ 4 ] < < 8 ) ;
if ( sectortag = = 0 ) return ;
2014-12-03 23:15:26 +00:00
foreach ( Sector sector in General . Map . Map . Sectors )
{
if ( sector . Tag = = sectortag )
{
2013-03-18 13:52:27 +00:00
BaseVisualSector vs = ( BaseVisualSector ) mode . GetVisualSector ( sector ) ;
vs . UpdateSectorGeometry ( true ) ;
}
}
}
}
2013-04-01 11:06:01 +00:00
Visual mode, UDMF: added "Scale Texture Up (X)", "Scale Texture Down (X)", "Scale Texture Up (Y)", "Scale Texture Down (Y)" actions. Default keys are Num6, Num4, Num8, Num5.
Visual mode, UDMF: renamed "Rotate Thing Clockwise" and "Rotate Thing Counterclockwise" actions to "Rotate Clockwise" and "Rotate Counterclockwise". These actions can now be used to change rotation of floor/ceiling textures.
Visual mode, UDMF: "Reset Texture Offsets" action now also resets sidedef's scale and floor/ceiling's scale and rotation.
Visual mode, UDMF: control line's OffsetX and OffsetY were not taken into account when calculating texture offsets of 3d floors' sides.
Visual mode, UDMF: fixed a ton of bugs in Auto align functions.
Visual mode, UDMF: when using "Move Texture Left/Right/Up/Down by 1" actions texture offsets were not updated properly when texture's scale was < 1.0.
Visual mode, UDMF: OffsetX and OffsetY were not taken into account in "Fit Texture Width/Height" actions.
Dockers Panel: added Pin/Unpin button, which acts the same as "Preferences -> Interface -> Side panels -> Auto hide" checkbox.
Texture size labels can now be disabled by unchecking "Preferences -> Interface -> Show texture and flat sizes in browsers" checkbox.
Texture size labels now are not shown for unknown textures.
Most of texture size labels had incorrect bg color.
ZDoom_linedefs.cfg: action specials 223 and 224 had incorrect Arg0.
2013-06-24 14:21:13 +00:00
//mxd
2014-12-03 23:15:26 +00:00
protected void SelectNeighbours ( string texture , bool select , bool withSameTexture , bool withSameHeight )
2014-09-18 22:06:35 +00:00
{
2013-10-21 10:19:31 +00:00
if ( Sidedef . Sector = = null | | ( ! withSameTexture & & ! withSameHeight ) ) return ;
2013-04-01 11:06:01 +00:00
2014-12-22 21:36:49 +00:00
Rectangle rect = BuilderModesTools . GetSidedefPartSize ( this ) ;
2014-09-18 22:06:35 +00:00
if ( rect . Height = = 0 ) return ;
if ( select & & ! selected )
{
2013-04-01 11:06:01 +00:00
selected = true ;
mode . AddSelectedObject ( this ) ;
2014-09-18 22:06:35 +00:00
}
else if ( ! select & & selected )
{
2013-04-01 11:06:01 +00:00
selected = false ;
mode . RemoveSelectedObject ( this ) ;
}
//select
List < Linedef > connectedLines = new List < Linedef > ( ) ;
2014-09-18 22:06:35 +00:00
foreach ( Linedef line in Sidedef . Line . Start . Linedefs )
{
2013-10-21 10:19:31 +00:00
if ( line . Index = = Sidedef . Line . Index ) continue ;
2013-04-01 11:06:01 +00:00
connectedLines . Add ( line ) ;
}
2014-09-18 22:06:35 +00:00
foreach ( Linedef line in Sidedef . Line . End . Linedefs )
{
2013-10-21 10:19:31 +00:00
if ( line . Index = = Sidedef . Line . Index ) continue ;
if ( ! connectedLines . Contains ( line ) ) connectedLines . Add ( line ) ;
}
2014-09-18 22:06:35 +00:00
// Check connected lines
foreach ( Linedef line in connectedLines )
{
2013-04-01 11:06:01 +00:00
bool addFrontTop = false ;
bool addFrontMiddle = false ;
bool addFrontBottom = false ;
bool addBackTop = false ;
bool addBackMiddle = false ;
bool addBackBottom = false ;
2014-09-18 22:06:35 +00:00
bool lineHasFrontSector = ( line . Front ! = null & & line . Front . Sector ! = null ) ;
bool lineHasBackSector = ( line . Back ! = null & & line . Back . Sector ! = null ) ;
bool doublesided = ( lineHasFrontSector & & lineHasBackSector ) ;
List < VisualMiddle3D > extrasides = new List < VisualMiddle3D > ( ) ;
// Gather 3d floor sides
if ( doublesided )
{
BaseVisualSector s = mode . GetVisualSector ( line . Front . Sector ) as BaseVisualSector ;
2014-12-03 23:15:26 +00:00
if ( s ! = null )
{
2014-09-18 22:06:35 +00:00
extrasides . AddRange ( s . GetSidedefParts ( line . Front ) . middle3d . ToArray ( ) ) ;
2013-04-01 11:06:01 +00:00
}
2014-09-18 22:06:35 +00:00
s = mode . GetVisualSector ( line . Back . Sector ) as BaseVisualSector ;
2014-12-03 23:15:26 +00:00
if ( s ! = null )
{
2014-09-18 22:06:35 +00:00
extrasides . AddRange ( s . GetSidedefParts ( line . Back ) . middle3d . ToArray ( ) ) ;
2013-04-01 11:06:01 +00:00
}
}
2014-09-18 22:06:35 +00:00
// Add regular sides
if ( withSameTexture )
{
if ( line . Front ! = null )
{
addFrontTop = ( line . Front . HighTexture = = texture
& & line . Front . HighRequired ( )
& & BuilderModesTools . GetSidedefPartSize ( line . Front , VisualGeometryType . WALL_UPPER ) . IntersectsWith ( rect ) ) ;
2014-12-22 21:36:49 +00:00
addFrontMiddle = ( line . Front . MiddleTexture = = texture
2015-01-07 21:20:55 +00:00
& & ( line . Front . MiddleRequired ( ) | | ( line . Back ! = null & & texture ! = "-" ) )
2014-09-18 22:06:35 +00:00
& & line . Front . GetMiddleHeight ( ) > 0
& & BuilderModesTools . GetSidedefPartSize ( line . Front , VisualGeometryType . WALL_MIDDLE ) . IntersectsWith ( rect ) ) ;
addFrontBottom = ( line . Front . LowTexture = = texture
& & line . Front . LowRequired ( )
& & BuilderModesTools . GetSidedefPartSize ( line . Front , VisualGeometryType . WALL_LOWER ) . IntersectsWith ( rect ) ) ;
2013-10-21 10:19:31 +00:00
2013-04-01 11:06:01 +00:00
}
2014-09-18 22:06:35 +00:00
if ( line . Back ! = null )
{
addBackTop = ( line . Back . HighTexture = = texture
& & line . Back . HighRequired ( )
& & BuilderModesTools . GetSidedefPartSize ( line . Back , VisualGeometryType . WALL_UPPER ) . IntersectsWith ( rect ) ) ;
2015-01-07 21:20:55 +00:00
addBackMiddle = ( line . Back . MiddleTexture = = texture
& & ( line . Back . MiddleRequired ( ) | | ( line . Front ! = null & & texture ! = "-" ) )
2014-09-18 22:06:35 +00:00
& & line . Back . GetMiddleHeight ( ) > 0
& & BuilderModesTools . GetSidedefPartSize ( line . Back , VisualGeometryType . WALL_MIDDLE ) . IntersectsWith ( rect ) ) ;
addBackBottom = ( line . Back . LowTexture = = texture
& & line . Back . LowRequired ( )
& & BuilderModesTools . GetSidedefPartSize ( line . Back , VisualGeometryType . WALL_LOWER ) . IntersectsWith ( rect ) ) ;
2013-10-21 10:19:31 +00:00
}
2014-09-18 22:06:35 +00:00
// Add 3d floor sides
List < VisualMiddle3D > filtered = new List < VisualMiddle3D > ( ) ;
foreach ( VisualMiddle3D side3d in extrasides )
{
Sidedef controlside = side3d . GetControlLinedef ( ) . Front ;
if ( controlside . MiddleTexture = = texture & & BuilderModesTools . GetSidedefPartSize ( controlside , VisualGeometryType . WALL_MIDDLE ) . IntersectsWith ( rect ) )
{
filtered . Add ( side3d ) ;
}
2013-10-21 10:19:31 +00:00
}
2014-09-18 22:06:35 +00:00
extrasides = filtered ;
}
if ( withSameHeight & & rect . Height > 0 )
{
// Upper parts match?
if ( ( ! withSameTexture | | addFrontTop ) & & doublesided & & line . Front . HighRequired ( ) )
{
Rectangle r = BuilderModesTools . GetSidedefPartSize ( line . Front , VisualGeometryType . WALL_UPPER ) ;
addFrontTop = ( rect . Height = = r . Height & & rect . Y = = r . Y ) ;
}
if ( ( ! withSameTexture | | addBackTop ) & & doublesided & & line . Back . HighRequired ( ) )
{
Rectangle r = BuilderModesTools . GetSidedefPartSize ( line . Back , VisualGeometryType . WALL_UPPER ) ;
addBackTop = ( rect . Height = = r . Height & & rect . Y = = r . Y ) ;
}
// Middle parts match?
if ( ( ! withSameTexture | | addFrontMiddle )
& & lineHasFrontSector
& & ( line . Front . MiddleRequired ( ) | | line . Front . LongMiddleTexture ! = MapSet . EmptyLongName ) )
{
Rectangle r = BuilderModesTools . GetSidedefPartSize ( line . Front , VisualGeometryType . WALL_MIDDLE ) ;
addFrontMiddle = ( rect . Height = = r . Height & & rect . Y = = r . Y ) ;
}
if ( ( ! withSameTexture | | addBackMiddle )
& & lineHasBackSector
& & ( line . Back . MiddleRequired ( ) | | line . Back . LongMiddleTexture ! = MapSet . EmptyLongName ) )
{
Rectangle r = BuilderModesTools . GetSidedefPartSize ( line . Back , VisualGeometryType . WALL_MIDDLE ) ;
addBackMiddle = ( rect . Height = = r . Height & & rect . Y = = r . Y ) ;
}
// Lower parts match?
if ( ( ! withSameTexture | | addFrontBottom ) & & doublesided & & line . Front . LowRequired ( ) )
{
Rectangle r = BuilderModesTools . GetSidedefPartSize ( line . Front , VisualGeometryType . WALL_LOWER ) ;
addFrontBottom = ( rect . Height = = r . Height & & rect . Y = = r . Y ) ;
2013-10-21 10:19:31 +00:00
}
2014-09-18 22:06:35 +00:00
if ( ( ! withSameTexture | | addBackBottom ) & & doublesided & & line . Back . LowRequired ( ) )
{
Rectangle r = BuilderModesTools . GetSidedefPartSize ( line . Back , VisualGeometryType . WALL_LOWER ) ;
addBackBottom = ( rect . Height = = r . Height & & rect . Y = = r . Y ) ;
2013-10-21 10:19:31 +00:00
}
2014-09-18 22:06:35 +00:00
// 3d floor parts match?
List < VisualMiddle3D > filtered = new List < VisualMiddle3D > ( ) ;
foreach ( VisualMiddle3D side3d in extrasides )
{
Sidedef controlside = side3d . GetControlLinedef ( ) . Front ;
Rectangle r = BuilderModesTools . GetSidedefPartSize ( controlside , VisualGeometryType . WALL_MIDDLE ) ;
if ( rect . Height = = r . Height & & rect . Y = = r . Y )
{
filtered . Add ( side3d ) ;
}
2013-04-01 11:06:01 +00:00
}
2014-09-18 22:06:35 +00:00
extrasides = filtered ;
2013-04-01 11:06:01 +00:00
}
2014-09-18 22:06:35 +00:00
// Select front?
2013-04-01 11:06:01 +00:00
if ( addFrontTop | | addFrontMiddle | | addFrontBottom )
mode . SelectSideParts ( line . Front , addFrontTop , addFrontMiddle , addFrontBottom , select , withSameTexture , withSameHeight ) ;
2014-09-18 22:06:35 +00:00
// Select back?
2013-04-01 11:06:01 +00:00
if ( addBackTop | | addBackMiddle | | addBackBottom )
mode . SelectSideParts ( line . Back , addBackTop , addBackMiddle , addBackBottom , select , withSameTexture , withSameHeight ) ;
2014-09-18 22:06:35 +00:00
// Select 3d floor sides?
foreach ( VisualMiddle3D side3d in extrasides )
{
if ( ( select & & ! side3d . Selected ) | | ( ! select & & side3d . Selected ) )
side3d . SelectNeighbours ( select , withSameTexture , withSameHeight ) ;
}
2013-04-01 11:06:01 +00:00
}
}
//mxd
2014-12-03 23:15:26 +00:00
public virtual bool IsSelected ( )
{
2013-04-01 11:06:01 +00:00
return selected ;
}
2014-12-22 21:36:49 +00:00
//mxd
protected void FitTexture ( FitTextureOptions options )
{
// Create undo name
string s ;
if ( options . FitWidth & & options . FitHeight ) s = "width and height" ;
else if ( options . FitWidth ) s = "width" ;
else s = "height" ;
2015-03-10 18:49:29 +00:00
// Create undo
2014-12-22 21:36:49 +00:00
mode . CreateUndo ( "Fit texture (" + s + ")" , UndoGroup . TextureOffsetChange , Sector . Sector . FixedIndex ) ;
Sidedef . Fields . BeforeFieldsChange ( ) ;
2015-03-10 18:49:29 +00:00
// Get proper control side...
Linedef controlline = GetControlLinedef ( ) ;
Sidedef controlside ;
if ( controlline ! = Sidedef . Line )
{
controlside = controlline . Front ;
controlside . Fields . BeforeFieldsChange ( ) ;
}
else
{
controlside = Sidedef ;
}
2014-12-22 21:36:49 +00:00
// Fit width
if ( options . FitWidth )
{
float scalex , offsetx ;
if ( options . FitAcrossSurfaces )
{
scalex = Texture . ScaledWidth / ( Sidedef . Line . Length * ( options . GlobalBounds . Width / Sidedef . Line . Length ) ) * options . HorizontalRepeat ;
2015-03-10 18:49:29 +00:00
offsetx = ( float ) Math . Round ( ( options . Bounds . X * scalex - Sidedef . OffsetX - options . ControlSideOffsetX ) % Texture . Width , General . Map . FormatInterface . VertexDecimals ) ;
2014-12-22 21:36:49 +00:00
}
else
{
scalex = Texture . ScaledWidth / Sidedef . Line . Length * options . HorizontalRepeat ;
2015-03-10 18:49:29 +00:00
offsetx = - Sidedef . OffsetX - options . ControlSideOffsetX ;
2014-12-22 21:36:49 +00:00
}
2015-03-10 18:49:29 +00:00
UDMFTools . SetFloat ( controlside . Fields , "scalex_" + partname , ( float ) Math . Round ( scalex , General . Map . FormatInterface . VertexDecimals ) , 1.0f ) ;
2014-12-22 21:36:49 +00:00
UDMFTools . SetFloat ( Sidedef . Fields , "offsetx_" + partname , offsetx , 0.0f ) ;
}
else
{
// Restore initial offsets
2015-03-10 18:49:29 +00:00
UDMFTools . SetFloat ( controlside . Fields , "scalex_" + partname , options . InitialScaleX , 1.0f ) ;
2014-12-22 21:36:49 +00:00
UDMFTools . SetFloat ( Sidedef . Fields , "offsetx_" + partname , options . InitialOffsetX , 0.0f ) ;
}
// Fit height
if ( options . FitHeight )
{
if ( Sidedef . Sector ! = null )
{
float scaley , offsety ;
if ( options . FitAcrossSurfaces )
{
scaley = Texture . ScaledHeight / ( options . Bounds . Height * ( ( float ) options . GlobalBounds . Height / options . Bounds . Height ) ) * options . VerticalRepeat ;
if ( this is VisualLower ) // Special cases, special cases...
{
2015-01-29 21:41:16 +00:00
offsety = GetLowerOffsetY ( scaley ) ;
2014-12-22 21:36:49 +00:00
}
else if ( this is VisualMiddleDouble )
{
if ( Sidedef . Line . IsFlagSet ( General . Map . Config . LowerUnpeggedFlag ) )
{
2014-12-23 12:32:08 +00:00
offsety = ( options . Bounds . Y - Sidedef . GetHighHeight ( ) - Sidedef . GetLowHeight ( ) ) * scaley - Sidedef . OffsetY ;
2014-12-22 21:36:49 +00:00
}
else
{
offsety = options . Bounds . Y * scaley - Sidedef . OffsetY ;
}
}
else
{
2015-03-10 18:49:29 +00:00
offsety = Tools . GetSidedefOffsetY ( Sidedef , geometrytype , options . Bounds . Y * scaley - Sidedef . OffsetY - options . ControlSideOffsetY , scaley , true ) % Texture . Height ;
2014-12-22 21:36:49 +00:00
}
}
else
{
scaley = Texture . ScaledHeight / options . Bounds . Height * options . VerticalRepeat ;
2015-01-29 21:41:16 +00:00
if ( this is VisualLower ) // Special cases, special cases...
offsety = GetLowerOffsetY ( scaley ) ;
else
2015-03-10 18:49:29 +00:00
offsety = Tools . GetSidedefOffsetY ( Sidedef , geometrytype , - Sidedef . OffsetY - options . ControlSideOffsetY , scaley , true ) % Texture . Height ;
2014-12-22 21:36:49 +00:00
}
2015-03-10 18:49:29 +00:00
UDMFTools . SetFloat ( controlside . Fields , "scaley_" + partname , ( float ) Math . Round ( scaley , General . Map . FormatInterface . VertexDecimals ) , 1.0f ) ;
2014-12-22 21:36:49 +00:00
UDMFTools . SetFloat ( Sidedef . Fields , "offsety_" + partname , ( float ) Math . Round ( offsety , General . Map . FormatInterface . VertexDecimals ) , 0.0f ) ;
}
}
else
{
// Restore initial offsets
2015-03-10 18:49:29 +00:00
UDMFTools . SetFloat ( controlside . Fields , "scaley_" + partname , options . InitialScaleY , 1.0f ) ;
2014-12-22 21:36:49 +00:00
UDMFTools . SetFloat ( Sidedef . Fields , "offsety_" + partname , options . InitialOffsetY , 0.0f ) ;
}
}
2015-01-29 21:41:16 +00:00
//mxd. Oh so special cases...
private float GetLowerOffsetY ( float scaley )
{
if ( Sidedef . Line . IsFlagSet ( General . Map . Config . LowerUnpeggedFlag ) )
return ( ( - Sidedef . OffsetY - Sidedef . GetMiddleHeight ( ) - Sidedef . GetHighHeight ( ) ) * scaley ) % Texture . Height ;
return ( - Sidedef . OffsetY * scaley ) % Texture . Height ;
}
2012-11-27 21:12:20 +00:00
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Events
// Unused
public virtual void OnEditBegin ( ) { }
protected virtual void SetTexture ( string texturename ) { }
public abstract bool Setup ( ) ;
2012-11-27 21:12:20 +00:00
protected abstract void SetTextureOffsetX ( int x ) ;
protected abstract void SetTextureOffsetY ( int y ) ;
Visual mode, UDMF: added "Scale Texture Up (X)", "Scale Texture Down (X)", "Scale Texture Up (Y)", "Scale Texture Down (Y)" actions. Default keys are Num6, Num4, Num8, Num5.
Visual mode, UDMF: renamed "Rotate Thing Clockwise" and "Rotate Thing Counterclockwise" actions to "Rotate Clockwise" and "Rotate Counterclockwise". These actions can now be used to change rotation of floor/ceiling textures.
Visual mode, UDMF: "Reset Texture Offsets" action now also resets sidedef's scale and floor/ceiling's scale and rotation.
Visual mode, UDMF: control line's OffsetX and OffsetY were not taken into account when calculating texture offsets of 3d floors' sides.
Visual mode, UDMF: fixed a ton of bugs in Auto align functions.
Visual mode, UDMF: when using "Move Texture Left/Right/Up/Down by 1" actions texture offsets were not updated properly when texture's scale was < 1.0.
Visual mode, UDMF: OffsetX and OffsetY were not taken into account in "Fit Texture Width/Height" actions.
Dockers Panel: added Pin/Unpin button, which acts the same as "Preferences -> Interface -> Side panels -> Auto hide" checkbox.
Texture size labels can now be disabled by unchecking "Preferences -> Interface -> Show texture and flat sizes in browsers" checkbox.
Texture size labels now are not shown for unknown textures.
Most of texture size labels had incorrect bg color.
ZDoom_linedefs.cfg: action specials 223 and 224 had incorrect Arg0.
2013-06-24 14:21:13 +00:00
protected virtual void ResetTextureScale ( ) { } //mxd
2012-11-27 21:12:20 +00:00
protected abstract void MoveTextureOffset ( Point xy ) ;
protected abstract Point GetTextureOffset ( ) ;
2013-04-01 11:06:01 +00:00
public virtual void SelectNeighbours ( bool select , bool withSameTexture , bool withSameHeight ) { } //mxd
2014-12-22 21:36:49 +00:00
public virtual void OnTextureFit ( FitTextureOptions options ) { } //mxd
2009-04-19 18:07:22 +00:00
// Insert middle texture
public virtual void OnInsert ( )
{
// No middle texture yet?
2013-07-31 12:38:47 +00:00
if ( ! Sidedef . MiddleRequired ( ) & & ( string . IsNullOrEmpty ( Sidedef . MiddleTexture ) | | ( Sidedef . MiddleTexture = = "-" ) ) )
2009-04-19 18:07:22 +00:00
{
// Make it now
2009-05-03 19:22:32 +00:00
mode . CreateUndo ( "Create middle texture" ) ;
2009-05-02 14:59:05 +00:00
mode . SetActionResult ( "Created middle texture." ) ;
2009-04-19 18:07:22 +00:00
General . Settings . FindDefaultDrawSettings ( ) ;
2013-11-21 10:53:11 +00:00
Sidedef . SetTextureMid ( General . Map . Options . DefaultWallTexture ) ;
2009-04-19 18:07:22 +00:00
// Update
2009-05-01 20:31:17 +00:00
Sector . Changed = true ;
2009-04-19 18:07:22 +00:00
// Other side as well
2013-07-31 12:38:47 +00:00
if ( string . IsNullOrEmpty ( Sidedef . Other . MiddleTexture ) | | ( Sidedef . Other . MiddleTexture = = "-" ) )
2009-04-19 18:07:22 +00:00
{
2013-11-21 10:53:11 +00:00
Sidedef . Other . SetTextureMid ( General . Map . Options . DefaultWallTexture ) ;
2009-04-19 18:07:22 +00:00
// Update
VisualSector othersector = mode . GetVisualSector ( Sidedef . Other . Sector ) ;
2009-05-01 20:31:17 +00:00
if ( othersector is BaseVisualSector ) ( othersector as BaseVisualSector ) . Changed = true ;
2009-04-19 18:07:22 +00:00
}
}
}
// Delete texture
public virtual void OnDelete ( )
{
// Remove texture
2009-05-03 19:22:32 +00:00
mode . CreateUndo ( "Delete texture" ) ;
2009-05-02 14:59:05 +00:00
mode . SetActionResult ( "Deleted a texture." ) ;
2009-04-19 18:07:22 +00:00
SetTexture ( "-" ) ;
// Update
2015-02-07 17:52:39 +00:00
Sector . UpdateSectorGeometry ( true ) ;
2009-04-19 18:07:22 +00:00
}
// Processing
2012-07-12 22:34:12 +00:00
public virtual void OnProcess ( float deltatime )
2009-04-19 18:07:22 +00:00
{
// If the texture was not loaded, but is loaded now, then re-setup geometry
if ( setuponloadedtexture ! = 0 )
{
ImageData t = General . Map . Data . GetTextureImage ( setuponloadedtexture ) ;
if ( t ! = null )
{
if ( t . IsImageLoaded )
{
setuponloadedtexture = 0 ;
Setup ( ) ;
}
}
}
}
// Change target height
public virtual void OnChangeTargetHeight ( int amount )
{
switch ( BuilderPlug . Me . ChangeHeightBySidedef )
{
// Change ceiling
case 1 :
2009-05-03 19:22:32 +00:00
if ( ! this . Sector . Ceiling . Changed )
this . Sector . Ceiling . OnChangeTargetHeight ( amount ) ;
2009-04-19 18:07:22 +00:00
break ;
// Change floor
case 2 :
2009-05-03 19:22:32 +00:00
if ( ! this . Sector . Floor . Changed )
this . Sector . Floor . OnChangeTargetHeight ( amount ) ;
2009-04-19 18:07:22 +00:00
break ;
2009-05-05 11:26:50 +00:00
// Change both
case 3 :
if ( ! this . Sector . Floor . Changed )
this . Sector . Floor . OnChangeTargetHeight ( amount ) ;
if ( ! this . Sector . Ceiling . Changed )
this . Sector . Ceiling . OnChangeTargetHeight ( amount ) ;
break ;
2009-04-19 18:07:22 +00:00
}
}
// Reset texture offsets
public virtual void OnResetTextureOffset ( )
{
2009-05-03 19:22:32 +00:00
mode . CreateUndo ( "Reset texture offsets" ) ;
2009-05-02 14:59:05 +00:00
mode . SetActionResult ( "Texture offsets reset." ) ;
2009-04-19 18:07:22 +00:00
// Apply offsets
2013-09-19 09:17:49 +00:00
Sidedef . OffsetX = 0 ;
Sidedef . OffsetY = 0 ;
2012-11-27 21:12:20 +00:00
2009-04-19 18:07:22 +00:00
// Update sidedef geometry
VisualSidedefParts parts = Sector . GetSidedefParts ( Sidedef ) ;
2009-05-03 19:22:32 +00:00
parts . SetupAllParts ( ) ;
2009-04-19 18:07:22 +00:00
}
2013-09-19 09:17:49 +00:00
//mxd
2014-12-03 23:15:26 +00:00
public virtual void OnResetLocalTextureOffset ( )
{
if ( ! General . Map . UDMF )
{
2013-09-19 09:17:49 +00:00
OnResetTextureOffset ( ) ;
return ;
}
Added, Visual mode, UDMF: added "Change Pitch Clockwise", "Change Pitch Counterclockwise", "Change Roll Clockwise" and "Change Roll Counterclockwise" actions.
Added, Visual mode, UDMF: added "Increase Scale" and "Decrease Scale" actions.
Added, Visual mode, UDMF: "Reset Texture Offsets" action now resets scale when used on things.
Added, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets scale, pitch and roll when used on things.
Changed, Visual mode, UDMF: "Reset Texture Offsets" action now only resets texture offsets (previously it also reset texture scale).
Changed, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets texture offsets, scale and brightness of sidedefs and also rotation of floors/ceilings.
Changed, Visual mode, UDMF: thing box arrow now displays pitch and roll for things, which have attached model and appropriate MODELDEF flags.
Changed, Thing Edit Form, UDMF: negative pitch and roll can now be entered.
Updated documentation.
2015-03-30 21:44:04 +00:00
mode . CreateUndo ( "Reset local texture offsets, scale and brightness" ) ;
mode . SetActionResult ( "Local texture offsets, scale and brightness reset." ) ;
2013-09-19 09:17:49 +00:00
Added, Visual mode, UDMF: added "Change Pitch Clockwise", "Change Pitch Counterclockwise", "Change Roll Clockwise" and "Change Roll Counterclockwise" actions.
Added, Visual mode, UDMF: added "Increase Scale" and "Decrease Scale" actions.
Added, Visual mode, UDMF: "Reset Texture Offsets" action now resets scale when used on things.
Added, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets scale, pitch and roll when used on things.
Changed, Visual mode, UDMF: "Reset Texture Offsets" action now only resets texture offsets (previously it also reset texture scale).
Changed, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets texture offsets, scale and brightness of sidedefs and also rotation of floors/ceilings.
Changed, Visual mode, UDMF: thing box arrow now displays pitch and roll for things, which have attached model and appropriate MODELDEF flags.
Changed, Thing Edit Form, UDMF: negative pitch and roll can now be entered.
Updated documentation.
2015-03-30 21:44:04 +00:00
// Reset texture offsets
2013-09-19 09:17:49 +00:00
SetTextureOffsetX ( 0 ) ;
SetTextureOffsetY ( 0 ) ;
Added, Visual mode, UDMF: added "Change Pitch Clockwise", "Change Pitch Counterclockwise", "Change Roll Clockwise" and "Change Roll Counterclockwise" actions.
Added, Visual mode, UDMF: added "Increase Scale" and "Decrease Scale" actions.
Added, Visual mode, UDMF: "Reset Texture Offsets" action now resets scale when used on things.
Added, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets scale, pitch and roll when used on things.
Changed, Visual mode, UDMF: "Reset Texture Offsets" action now only resets texture offsets (previously it also reset texture scale).
Changed, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets texture offsets, scale and brightness of sidedefs and also rotation of floors/ceilings.
Changed, Visual mode, UDMF: thing box arrow now displays pitch and roll for things, which have attached model and appropriate MODELDEF flags.
Changed, Thing Edit Form, UDMF: negative pitch and roll can now be entered.
Updated documentation.
2015-03-30 21:44:04 +00:00
// Scale
2013-09-19 09:17:49 +00:00
ResetTextureScale ( ) ;
Added, Visual mode, UDMF: added "Change Pitch Clockwise", "Change Pitch Counterclockwise", "Change Roll Clockwise" and "Change Roll Counterclockwise" actions.
Added, Visual mode, UDMF: added "Increase Scale" and "Decrease Scale" actions.
Added, Visual mode, UDMF: "Reset Texture Offsets" action now resets scale when used on things.
Added, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets scale, pitch and roll when used on things.
Changed, Visual mode, UDMF: "Reset Texture Offsets" action now only resets texture offsets (previously it also reset texture scale).
Changed, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets texture offsets, scale and brightness of sidedefs and also rotation of floors/ceilings.
Changed, Visual mode, UDMF: thing box arrow now displays pitch and roll for things, which have attached model and appropriate MODELDEF flags.
Changed, Thing Edit Form, UDMF: negative pitch and roll can now be entered.
Updated documentation.
2015-03-30 21:44:04 +00:00
// And brightness
if ( Sidedef . Fields . ContainsKey ( "light" ) ) Sidedef . Fields . Remove ( "light" ) ;
if ( Sidedef . Fields . ContainsKey ( "lightabsolute" ) ) Sidedef . Fields . Remove ( "lightabsolute" ) ;
2013-09-19 09:17:49 +00:00
// Update sidedef geometry
VisualSidedefParts parts = Sector . GetSidedefParts ( Sidedef ) ;
parts . SetupAllParts ( ) ;
}
2009-04-19 18:07:22 +00:00
// Toggle upper-unpegged
public virtual void OnToggleUpperUnpegged ( )
{
2009-06-11 21:21:20 +00:00
if ( this . Sidedef . Line . IsFlagSet ( General . Map . Config . UpperUnpeggedFlag ) )
2009-04-19 18:07:22 +00:00
{
// Remove flag
2009-05-03 19:22:32 +00:00
mode . ApplyUpperUnpegged ( false ) ;
}
else
{
// Add flag
mode . ApplyUpperUnpegged ( true ) ;
}
}
// Toggle lower-unpegged
public virtual void OnToggleLowerUnpegged ( )
{
2009-06-11 21:21:20 +00:00
if ( this . Sidedef . Line . IsFlagSet ( General . Map . Config . LowerUnpeggedFlag ) )
2009-05-03 19:22:32 +00:00
{
// Remove flag
mode . ApplyLowerUnpegged ( false ) ;
}
else
{
// Add flag
mode . ApplyLowerUnpegged ( true ) ;
}
}
// This sets the Upper Unpegged flag
public virtual void ApplyUpperUnpegged ( bool set )
{
if ( ! set )
{
// Remove flag
mode . CreateUndo ( "Remove upper-unpegged setting" ) ;
2009-05-02 14:59:05 +00:00
mode . SetActionResult ( "Removed upper-unpegged setting." ) ;
2009-06-11 21:21:20 +00:00
this . Sidedef . Line . SetFlag ( General . Map . Config . UpperUnpeggedFlag , false ) ;
2009-04-19 18:07:22 +00:00
}
else
{
// Add flag
2009-05-03 19:22:32 +00:00
mode . CreateUndo ( "Set upper-unpegged setting" ) ;
2009-05-02 14:59:05 +00:00
mode . SetActionResult ( "Set upper-unpegged setting." ) ;
2009-06-11 21:21:20 +00:00
this . Sidedef . Line . SetFlag ( General . Map . Config . UpperUnpeggedFlag , true ) ;
2009-04-19 18:07:22 +00:00
}
2009-05-03 19:22:32 +00:00
2009-04-19 18:07:22 +00:00
// Update sidedef geometry
VisualSidedefParts parts = Sector . GetSidedefParts ( Sidedef ) ;
2009-05-03 19:22:32 +00:00
parts . SetupAllParts ( ) ;
2009-04-27 17:32:23 +00:00
// Update other sidedef geometry
if ( Sidedef . Other ! = null )
{
BaseVisualSector othersector = ( BaseVisualSector ) mode . GetVisualSector ( Sidedef . Other . Sector ) ;
parts = othersector . GetSidedefParts ( Sidedef . Other ) ;
2009-05-03 19:22:32 +00:00
parts . SetupAllParts ( ) ;
2009-04-27 17:32:23 +00:00
}
2009-04-19 18:07:22 +00:00
}
2009-05-03 19:22:32 +00:00
// This sets the Lower Unpegged flag
public virtual void ApplyLowerUnpegged ( bool set )
2009-04-19 18:07:22 +00:00
{
2009-05-03 19:22:32 +00:00
if ( ! set )
2009-04-19 18:07:22 +00:00
{
// Remove flag
2009-05-03 19:22:32 +00:00
mode . CreateUndo ( "Remove lower-unpegged setting" ) ;
2009-05-02 14:59:05 +00:00
mode . SetActionResult ( "Removed lower-unpegged setting." ) ;
2009-06-11 21:21:20 +00:00
this . Sidedef . Line . SetFlag ( General . Map . Config . LowerUnpeggedFlag , false ) ;
2009-04-19 18:07:22 +00:00
}
else
{
// Add flag
2009-05-03 19:22:32 +00:00
mode . CreateUndo ( "Set lower-unpegged setting" ) ;
2009-05-02 14:59:05 +00:00
mode . SetActionResult ( "Set lower-unpegged setting." ) ;
2009-06-11 21:21:20 +00:00
this . Sidedef . Line . SetFlag ( General . Map . Config . LowerUnpeggedFlag , true ) ;
2009-04-19 18:07:22 +00:00
}
2009-05-03 19:22:32 +00:00
2009-04-19 18:07:22 +00:00
// Update sidedef geometry
VisualSidedefParts parts = Sector . GetSidedefParts ( Sidedef ) ;
2009-05-03 19:22:32 +00:00
parts . SetupAllParts ( ) ;
2009-04-27 17:32:23 +00:00
// Update other sidedef geometry
if ( Sidedef . Other ! = null )
{
BaseVisualSector othersector = ( BaseVisualSector ) mode . GetVisualSector ( Sidedef . Other . Sector ) ;
parts = othersector . GetSidedefParts ( Sidedef . Other ) ;
2009-05-03 19:22:32 +00:00
parts . SetupAllParts ( ) ;
2009-04-27 17:32:23 +00:00
}
2009-04-19 18:07:22 +00:00
}
2009-05-03 19:22:32 +00:00
2009-04-19 18:07:22 +00:00
// Flood-fill textures
public virtual void OnTextureFloodfill ( )
{
if ( BuilderPlug . Me . CopiedTexture ! = null )
{
string oldtexture = GetTextureName ( ) ;
2015-02-19 13:00:19 +00:00
long oldtexturelong = Lump . MakeLongName ( General . Map . Data . GetFullTextureName ( oldtexture ) ) ; //mxd
2009-04-19 18:07:22 +00:00
string newtexture = BuilderPlug . Me . CopiedTexture ;
if ( newtexture ! = oldtexture )
{
2009-05-03 19:22:32 +00:00
mode . CreateUndo ( "Flood-fill textures with " + newtexture ) ;
2009-05-02 14:59:05 +00:00
mode . SetActionResult ( "Flood-filled textures with " + newtexture + "." ) ;
2009-04-19 18:07:22 +00:00
mode . Renderer . SetCrosshairBusy ( true ) ;
General . Interface . RedrawDisplay ( ) ;
// Get the texture
ImageData newtextureimage = General . Map . Data . GetTextureImage ( newtexture ) ;
if ( newtextureimage ! = null )
{
2009-06-12 09:44:38 +00:00
if ( mode . IsSingleSelection )
{
// Clear all marks, this will align everything it can
General . Map . Map . ClearMarkedSidedefs ( false ) ;
}
else
{
// Limit the alignment to selection only
General . Map . Map . ClearMarkedSidedefs ( true ) ;
List < Sidedef > sides = mode . GetSelectedSidedefs ( ) ;
foreach ( Sidedef sd in sides ) sd . Marked = false ;
}
2009-04-19 18:07:22 +00:00
// Do the alignment
2015-02-19 13:00:19 +00:00
Tools . FloodfillTextures ( this . Sidedef , oldtexturelong , newtexture , false ) ;
2009-04-19 18:07:22 +00:00
// Get the changed sidedefs
List < Sidedef > changes = General . Map . Map . GetMarkedSidedefs ( true ) ;
foreach ( Sidedef sd in changes )
{
// Update the parts for this sidedef!
if ( mode . VisualSectorExists ( sd . Sector ) )
{
BaseVisualSector vs = ( mode . GetVisualSector ( sd . Sector ) as BaseVisualSector ) ;
VisualSidedefParts parts = vs . GetSidedefParts ( sd ) ;
2009-05-03 19:22:32 +00:00
parts . SetupAllParts ( ) ;
2009-04-19 18:07:22 +00:00
}
}
General . Map . Data . UpdateUsedTextures ( ) ;
mode . Renderer . SetCrosshairBusy ( false ) ;
mode . ShowTargetInfo ( ) ;
}
}
}
}
2013-04-26 12:32:51 +00:00
// Auto-align texture offsets
2009-04-19 18:07:22 +00:00
public virtual void OnTextureAlign ( bool alignx , bool aligny )
{
2013-04-26 12:32:51 +00:00
//mxd
2014-02-21 14:42:12 +00:00
string rest ;
2013-04-26 12:32:51 +00:00
if ( alignx & & aligny ) rest = "(X and Y)" ;
else if ( alignx ) rest = "(X)" ;
else rest = "(Y)" ;
mode . CreateUndo ( "Auto-align textures " + rest ) ;
mode . SetActionResult ( "Auto-aligned textures " + rest + "." ) ;
2009-04-19 18:07:22 +00:00
// Make sure the texture is loaded (we need the texture size)
if ( ! base . Texture . IsImageLoaded ) base . Texture . LoadImage ( ) ;
2009-06-12 09:44:38 +00:00
if ( mode . IsSingleSelection )
{
// Clear all marks, this will align everything it can
General . Map . Map . ClearMarkedSidedefs ( false ) ;
}
else
{
// Limit the alignment to selection only
General . Map . Map . ClearMarkedSidedefs ( true ) ;
List < Sidedef > sides = mode . GetSelectedSidedefs ( ) ;
foreach ( Sidedef sd in sides ) sd . Marked = false ;
}
2009-04-19 18:07:22 +00:00
// Do the alignment
2013-09-03 09:34:28 +00:00
mode . AutoAlignTextures ( this , base . Texture , alignx , aligny , false , true ) ;
2009-04-19 18:07:22 +00:00
// Get the changed sidedefs
List < Sidedef > changes = General . Map . Map . GetMarkedSidedefs ( true ) ;
foreach ( Sidedef sd in changes )
{
// Update the parts for this sidedef!
if ( mode . VisualSectorExists ( sd . Sector ) )
{
BaseVisualSector vs = ( mode . GetVisualSector ( sd . Sector ) as BaseVisualSector ) ;
VisualSidedefParts parts = vs . GetSidedefParts ( sd ) ;
2009-05-03 19:22:32 +00:00
parts . SetupAllParts ( ) ;
2009-04-19 18:07:22 +00:00
}
}
}
// Select texture
public virtual void OnSelectTexture ( )
{
if ( General . Interface . IsActiveWindow )
{
string oldtexture = GetTextureName ( ) ;
string newtexture = General . Interface . BrowseTexture ( General . Interface , oldtexture ) ;
if ( newtexture ! = oldtexture )
{
2009-05-03 19:22:32 +00:00
mode . ApplySelectTexture ( newtexture , false ) ;
2009-04-19 18:07:22 +00:00
}
}
}
2009-05-03 19:22:32 +00:00
// Apply Texture
public virtual void ApplyTexture ( string texture )
{
mode . CreateUndo ( "Change texture " + texture ) ;
SetTexture ( texture ) ;
2014-12-03 23:15:26 +00:00
OnTextureChanged ( ) ; //mxd
2009-05-03 19:22:32 +00:00
}
2009-04-19 18:07:22 +00:00
// Paste texture
public virtual void OnPasteTexture ( )
{
if ( BuilderPlug . Me . CopiedTexture ! = null )
{
2014-01-13 08:44:31 +00:00
mode . CreateUndo ( "Paste texture '" + BuilderPlug . Me . CopiedTexture + "'" ) ;
mode . SetActionResult ( "Pasted texture '" + BuilderPlug . Me . CopiedTexture + "'." ) ;
2009-04-19 18:07:22 +00:00
SetTexture ( BuilderPlug . Me . CopiedTexture ) ;
2014-12-03 23:15:26 +00:00
OnTextureChanged ( ) ; //mxd
2009-04-19 18:07:22 +00:00
}
}
// Paste texture offsets
public virtual void OnPasteTextureOffsets ( )
{
2009-05-03 19:22:32 +00:00
mode . CreateUndo ( "Paste texture offsets" ) ;
2014-12-03 23:15:26 +00:00
if ( General . Map . UDMF )
{
2013-09-06 07:55:02 +00:00
SetTextureOffsetX ( BuilderPlug . Me . CopiedOffsets . X ) ;
SetTextureOffsetY ( BuilderPlug . Me . CopiedOffsets . Y ) ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-09-06 07:55:02 +00:00
Sidedef . OffsetX = BuilderPlug . Me . CopiedOffsets . X ;
Sidedef . OffsetY = BuilderPlug . Me . CopiedOffsets . Y ;
}
2012-11-27 21:12:20 +00:00
mode . SetActionResult ( "Pasted texture offsets " + BuilderPlug . Me . CopiedOffsets . X + ", " + BuilderPlug . Me . CopiedOffsets . Y + "." ) ;
2009-04-19 18:07:22 +00:00
// Update sidedef geometry
VisualSidedefParts parts = Sector . GetSidedefParts ( Sidedef ) ;
2009-05-03 19:22:32 +00:00
parts . SetupAllParts ( ) ;
2009-04-19 18:07:22 +00:00
}
// Copy texture
public virtual void OnCopyTexture ( )
{
2015-02-19 13:00:19 +00:00
if ( Texture = = null ) return ; //mxd
2015-03-03 18:32:59 +00:00
string texturename = ( ( ! General . Map . Options . UseLongTextureNames & & Texture . UsedInMap ) ? Texture . ShortName : GetTextureName ( ) ) ; //mxd
2015-02-19 13:00:19 +00:00
BuilderPlug . Me . CopiedTexture = texturename ;
if ( General . Map . Config . MixTexturesFlats ) BuilderPlug . Me . CopiedFlat = texturename ;
mode . SetActionResult ( "Copied texture '" + texturename + "'." ) ;
2009-04-19 18:07:22 +00:00
}
// Copy texture offsets
public virtual void OnCopyTextureOffsets ( )
{
2013-09-06 07:55:02 +00:00
//mxd
BuilderPlug . Me . CopiedOffsets = General . Map . UDMF ? GetTextureOffset ( ) : new Point ( Sidedef . OffsetX , Sidedef . OffsetY ) ;
2012-11-27 21:12:20 +00:00
mode . SetActionResult ( "Copied texture offsets " + BuilderPlug . Me . CopiedOffsets . X + ", " + BuilderPlug . Me . CopiedOffsets . Y + "." ) ;
2009-04-19 18:07:22 +00:00
}
// Copy properties
public virtual void OnCopyProperties ( )
{
BuilderPlug . Me . CopiedSidedefProps = new SidedefProperties ( Sidedef ) ;
2009-05-02 14:59:05 +00:00
mode . SetActionResult ( "Copied sidedef properties." ) ;
2009-04-19 18:07:22 +00:00
}
// Paste properties
public virtual void OnPasteProperties ( )
{
if ( BuilderPlug . Me . CopiedSidedefProps ! = null )
{
2009-05-03 19:22:32 +00:00
mode . CreateUndo ( "Paste sidedef properties" ) ;
2009-05-02 14:59:05 +00:00
mode . SetActionResult ( "Pasted sidedef properties." ) ;
2009-04-19 18:07:22 +00:00
BuilderPlug . Me . CopiedSidedefProps . Apply ( Sidedef ) ;
// Update sectors on both sides
BaseVisualSector front = ( BaseVisualSector ) mode . GetVisualSector ( Sidedef . Sector ) ;
2009-05-01 20:31:17 +00:00
if ( front ! = null ) front . Changed = true ;
2009-04-19 18:07:22 +00:00
if ( Sidedef . Other ! = null )
{
BaseVisualSector back = ( BaseVisualSector ) mode . GetVisualSector ( Sidedef . Other . Sector ) ;
2009-05-01 20:31:17 +00:00
if ( back ! = null ) back . Changed = true ;
2009-04-19 18:07:22 +00:00
}
mode . ShowTargetInfo ( ) ;
}
}
// Return texture name
public virtual string GetTextureName ( ) { return "" ; }
// Select button pressed
public virtual void OnSelectBegin ( )
{
2009-05-05 09:50:23 +00:00
mode . LockTarget ( ) ;
2009-04-19 18:07:22 +00:00
dragstartanglexy = General . Map . VisualCamera . AngleXY ;
dragstartanglez = General . Map . VisualCamera . AngleZ ;
dragorigin = pickintersect ;
2012-11-27 21:12:20 +00:00
startoffsetx = GetTextureOffset ( ) . X ;
startoffsety = GetTextureOffset ( ) . Y ;
prevoffsetx = GetTextureOffset ( ) . X ;
prevoffsety = GetTextureOffset ( ) . Y ;
2009-04-19 18:07:22 +00:00
}
// Select button released
public virtual void OnSelectEnd ( )
{
2009-05-05 09:50:23 +00:00
mode . UnlockTarget ( ) ;
2009-04-19 18:07:22 +00:00
// Was dragging?
if ( uvdragging )
{
// Dragging stops now
uvdragging = false ;
}
else
{
// Add/remove selection
2009-07-07 11:29:56 +00:00
if ( this . selected )
{
this . selected = false ;
mode . RemoveSelectedObject ( this ) ;
}
else
{
this . selected = true ;
mode . AddSelectedObject ( this ) ;
}
2009-04-19 18:07:22 +00:00
}
}
// Edit button released
public virtual void OnEditEnd ( )
{
2010-08-14 18:07:38 +00:00
if ( General . Interface . IsActiveWindow )
2009-04-19 18:07:22 +00:00
{
2010-08-14 18:07:38 +00:00
List < Linedef > linedefs = mode . GetSelectedLinedefs ( ) ;
2013-07-19 15:30:58 +00:00
updateList = new List < BaseVisualSector > ( ) ; //mxd
2014-12-03 23:15:26 +00:00
foreach ( Linedef l in linedefs )
{
2013-07-19 15:30:58 +00:00
if ( l . Front ! = null & & mode . VisualSectorExists ( l . Front . Sector ) )
updateList . Add ( ( BaseVisualSector ) mode . GetVisualSector ( l . Front . Sector ) ) ;
if ( l . Back ! = null & & mode . VisualSectorExists ( l . Back . Sector ) )
updateList . Add ( ( BaseVisualSector ) mode . GetVisualSector ( l . Back . Sector ) ) ;
}
2014-02-21 14:42:12 +00:00
General . Interface . OnEditFormValuesChanged + = Interface_OnEditFormValuesChanged ;
2013-07-19 15:30:58 +00:00
mode . StartRealtimeInterfaceUpdate ( SelectionType . Linedefs ) ;
2010-08-14 18:07:38 +00:00
DialogResult result = General . Interface . ShowEditLinedefs ( linedefs ) ;
2013-07-19 15:30:58 +00:00
mode . StopRealtimeInterfaceUpdate ( SelectionType . Linedefs ) ;
General . Interface . OnEditFormValuesChanged - = Interface_OnEditFormValuesChanged ;
updateList . Clear ( ) ;
updateList = null ;
2015-04-14 11:33:57 +00:00
//mxd. Effects may need updating...
if ( result = = DialogResult . OK ) mode . RebuildElementData ( ) ;
2009-04-19 18:07:22 +00:00
}
}
2013-07-19 15:30:58 +00:00
//mxd
2014-12-03 23:15:26 +00:00
private void Interface_OnEditFormValuesChanged ( object sender , EventArgs e )
{
foreach ( BaseVisualSector vs in updateList ) vs . UpdateSectorGeometry ( false ) ;
2013-07-19 15:30:58 +00:00
}
2009-04-19 18:07:22 +00:00
// Mouse moves
public virtual void OnMouseMove ( MouseEventArgs e )
{
// Dragging UV?
if ( uvdragging )
{
UpdateDragUV ( ) ;
}
else
{
// Select button pressed?
if ( General . Actions . CheckActionActive ( General . ThisAssembly , "visualselect" ) )
{
// Check if tolerance is exceeded to start UV dragging
float deltaxy = General . Map . VisualCamera . AngleXY - dragstartanglexy ;
float deltaz = General . Map . VisualCamera . AngleZ - dragstartanglez ;
if ( ( Math . Abs ( deltaxy ) + Math . Abs ( deltaz ) ) > DRAG_ANGLE_TOLERANCE )
{
2013-09-11 09:47:53 +00:00
mode . PreAction ( UndoGroup . TextureOffsetChange ) ;
mode . CreateUndo ( "Change texture offsets" ) ;
// Start drag now
uvdragging = true ;
mode . Renderer . ShowSelection = false ;
mode . Renderer . ShowHighlight = false ;
UpdateDragUV ( ) ;
2009-04-19 18:07:22 +00:00
}
}
}
}
// This is called to update UV dragging
protected virtual void UpdateDragUV ( )
{
float u_ray ;
// Calculate intersection position
Line2D ray = new Line2D ( General . Map . VisualCamera . Position , General . Map . VisualCamera . Target ) ;
Sidedef . Line . Line . GetIntersection ( ray , out u_ray ) ;
Vector3D intersect = General . Map . VisualCamera . Position + ( General . Map . VisualCamera . Target - General . Map . VisualCamera . Position ) * u_ray ;
// Calculate offsets
Vector3D dragdelta = intersect - dragorigin ;
Vector3D dragdeltaxy = dragdelta * deltaxy ;
Vector3D dragdeltaz = dragdelta * deltaz ;
float offsetx = dragdeltaxy . GetLength ( ) ;
float offsety = dragdeltaz . GetLength ( ) ;
if ( ( Math . Sign ( dragdeltaxy . x ) < 0 ) | | ( Math . Sign ( dragdeltaxy . y ) < 0 ) | | ( Math . Sign ( dragdeltaxy . z ) < 0 ) ) offsetx = - offsetx ;
if ( ( Math . Sign ( dragdeltaz . x ) < 0 ) | | ( Math . Sign ( dragdeltaz . y ) < 0 ) | | ( Math . Sign ( dragdeltaz . z ) < 0 ) ) offsety = - offsety ;
2014-12-22 21:36:49 +00:00
//mxd. Modify by surface scale?
if ( General . Map . UDMF )
{
float sx = UDMFTools . GetFloat ( Sidedef . Fields , "scalex_" + partname , 1.0f ) ;
float sy = UDMFTools . GetFloat ( Sidedef . Fields , "scaley_" + partname , 1.0f ) ;
if ( Math . Abs ( sx ) < 1 ) offsetx * = sx ;
if ( Math . Abs ( sy ) < 1 ) offsety * = sy ;
}
2009-04-19 18:07:22 +00:00
// Apply offsets
2014-12-03 23:15:26 +00:00
if ( General . Interface . CtrlState & & General . Interface . ShiftState )
{
//mxd. Clamp to grid size?
2013-12-05 09:24:55 +00:00
int newoffsetx = startoffsetx - ( int ) Math . Round ( offsetx ) ;
int newoffsety = startoffsety + ( int ) Math . Round ( offsety ) ;
int dx = prevoffsetx - newoffsetx ;
int dy = prevoffsety - newoffsety ;
2014-12-03 23:15:26 +00:00
if ( Math . Abs ( dx ) > = General . Map . Grid . GridSize )
{
2013-12-05 09:24:55 +00:00
dx = General . Map . Grid . GridSize * Math . Sign ( dx ) ;
prevoffsetx = newoffsetx ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-12-05 09:24:55 +00:00
dx = 0 ;
}
2014-12-03 23:15:26 +00:00
if ( Math . Abs ( dy ) > = General . Map . Grid . GridSize )
{
2013-12-05 09:24:55 +00:00
dy = General . Map . Grid . GridSize * Math . Sign ( dy ) ;
prevoffsety = newoffsety ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-12-05 09:24:55 +00:00
dy = 0 ;
}
if ( dx ! = 0 | | dy ! = 0 ) mode . ApplyTextureOffsetChange ( dx , dy ) ;
2014-12-03 23:15:26 +00:00
}
else
{
//mxd. Constraint to axis?
2013-12-05 09:24:55 +00:00
int newoffsetx = ( General . Interface . CtrlState ? startoffsetx : startoffsetx - ( int ) Math . Round ( offsetx ) ) ; //mxd
int newoffsety = ( General . Interface . ShiftState ? startoffsety : startoffsety + ( int ) Math . Round ( offsety ) ) ; //mxd
mode . ApplyTextureOffsetChange ( prevoffsetx - newoffsetx , prevoffsety - newoffsety ) ;
prevoffsetx = newoffsetx ;
prevoffsety = newoffsety ;
}
2009-04-19 18:07:22 +00:00
mode . ShowTargetInfo ( ) ;
}
// Sector brightness change
public virtual void OnChangeTargetBrightness ( bool up )
{
2014-12-22 21:36:49 +00:00
//mxd. Change UDMF wall light?
if ( General . Map . UDMF )
{
int light = Sidedef . Fields . GetValue ( "light" , 0 ) ;
bool absolute = Sidedef . Fields . GetValue ( "lightabsolute" , false ) ;
2015-02-12 22:04:49 +00:00
int newlight ;
2014-12-22 21:36:49 +00:00
if ( up )
2015-02-12 22:04:49 +00:00
newlight = General . Map . Config . BrightnessLevels . GetNextHigher ( light , absolute ) ;
2014-12-22 21:36:49 +00:00
else
2015-02-12 22:04:49 +00:00
newlight = General . Map . Config . BrightnessLevels . GetNextLower ( light , absolute ) ;
2014-12-22 21:36:49 +00:00
2015-02-12 22:04:49 +00:00
if ( newlight = = light ) return ;
2014-12-22 21:36:49 +00:00
//create undo
mode . CreateUndo ( "Change wall brightness" , UndoGroup . SurfaceBrightnessChange , Sector . Sector . FixedIndex ) ;
Sidedef . Fields . BeforeFieldsChange ( ) ;
//apply changes
2015-02-12 22:04:49 +00:00
UDMFTools . SetInteger ( Sidedef . Fields , "light" , newlight , ( absolute ? int . MinValue : 0 ) ) ;
Tools . UpdateLightFogFlag ( Sidedef ) ;
mode . SetActionResult ( "Changed wall brightness to " + newlight + "." ) ;
2014-12-22 21:36:49 +00:00
Sector . Sector . UpdateCache ( ) ;
//rebuild sector
Sector . UpdateSectorGeometry ( false ) ;
}
else if ( ! Sector . Changed )
2009-04-19 18:07:22 +00:00
{
2009-05-03 19:22:32 +00:00
// Change brightness
mode . CreateUndo ( "Change sector brightness" , UndoGroup . SectorBrightnessChange , Sector . Sector . FixedIndex ) ;
if ( up )
Sector . Sector . Brightness = General . Map . Config . BrightnessLevels . GetNextHigher ( Sector . Sector . Brightness ) ;
else
Sector . Sector . Brightness = General . Map . Config . BrightnessLevels . GetNextLower ( Sector . Sector . Brightness ) ;
mode . SetActionResult ( "Changed sector brightness to " + Sector . Sector . Brightness + "." ) ;
Sector . Sector . UpdateCache ( ) ;
// Rebuild sector
2012-11-27 21:12:20 +00:00
Sector . UpdateSectorGeometry ( false ) ;
2009-05-03 19:22:32 +00:00
// Go for all things in this sector
foreach ( Thing t in General . Map . Map . Things )
2009-04-19 18:07:22 +00:00
{
2009-05-03 19:22:32 +00:00
if ( t . Sector = = Sector . Sector )
2009-04-19 18:07:22 +00:00
{
2009-05-03 19:22:32 +00:00
if ( mode . VisualThingExists ( t ) )
{
// Update thing
BaseVisualThing vt = ( mode . GetVisualThing ( t ) as BaseVisualThing ) ;
vt . Changed = true ;
}
2009-04-19 18:07:22 +00:00
}
}
}
}
// Texture offset change
2013-04-26 12:32:51 +00:00
public virtual void OnChangeTextureOffset ( int horizontal , int vertical , bool doSurfaceAngleCorrection )
2009-04-19 18:07:22 +00:00
{
if ( ( General . Map . UndoRedo . NextUndo = = null ) | | ( General . Map . UndoRedo . NextUndo . TicketID ! = undoticket ) )
2009-05-03 19:22:32 +00:00
undoticket = mode . CreateUndo ( "Change texture offsets" ) ;
2009-04-19 18:07:22 +00:00
2013-09-11 09:47:53 +00:00
//mxd
2014-12-03 23:15:26 +00:00
if ( General . Map . UDMF )
{
2013-09-11 09:47:53 +00:00
// Apply UDMF offsets
MoveTextureOffset ( new Point ( - horizontal , - vertical ) ) ;
Point p = GetTextureOffset ( ) ;
mode . SetActionResult ( "Changed texture offsets to " + p . X + ", " + p . Y + "." ) ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-08-02 12:50:53 +00:00
//mxd. Apply classic offsets
2013-08-28 14:53:21 +00:00
Sidedef . OffsetX = ( Sidedef . OffsetX - horizontal ) ;
2013-09-11 09:47:53 +00:00
if ( Texture ! = null ) Sidedef . OffsetX % = Texture . Width ;
2013-08-28 14:53:21 +00:00
Sidedef . OffsetY = ( Sidedef . OffsetY - vertical ) ;
2014-12-22 21:36:49 +00:00
if ( geometrytype ! = VisualGeometryType . WALL_MIDDLE & & Texture ! = null ) Sidedef . OffsetY % = Texture . Height ;
2013-08-02 12:50:53 +00:00
2013-09-11 09:47:53 +00:00
mode . SetActionResult ( "Changed texture offsets to " + Sidedef . OffsetX + ", " + Sidedef . OffsetY + "." ) ;
}
2009-04-19 18:07:22 +00:00
// Update sidedef geometry
VisualSidedefParts parts = Sector . GetSidedefParts ( Sidedef ) ;
2009-05-03 19:22:32 +00:00
parts . SetupAllParts ( ) ;
2009-04-19 18:07:22 +00:00
}
2013-04-01 11:06:01 +00:00
Visual mode, UDMF: added "Scale Texture Up (X)", "Scale Texture Down (X)", "Scale Texture Up (Y)", "Scale Texture Down (Y)" actions. Default keys are Num6, Num4, Num8, Num5.
Visual mode, UDMF: renamed "Rotate Thing Clockwise" and "Rotate Thing Counterclockwise" actions to "Rotate Clockwise" and "Rotate Counterclockwise". These actions can now be used to change rotation of floor/ceiling textures.
Visual mode, UDMF: "Reset Texture Offsets" action now also resets sidedef's scale and floor/ceiling's scale and rotation.
Visual mode, UDMF: control line's OffsetX and OffsetY were not taken into account when calculating texture offsets of 3d floors' sides.
Visual mode, UDMF: fixed a ton of bugs in Auto align functions.
Visual mode, UDMF: when using "Move Texture Left/Right/Up/Down by 1" actions texture offsets were not updated properly when texture's scale was < 1.0.
Visual mode, UDMF: OffsetX and OffsetY were not taken into account in "Fit Texture Width/Height" actions.
Dockers Panel: added Pin/Unpin button, which acts the same as "Preferences -> Interface -> Side panels -> Auto hide" checkbox.
Texture size labels can now be disabled by unchecking "Preferences -> Interface -> Show texture and flat sizes in browsers" checkbox.
Texture size labels now are not shown for unknown textures.
Most of texture size labels had incorrect bg color.
ZDoom_linedefs.cfg: action specials 223 and 224 had incorrect Arg0.
2013-06-24 14:21:13 +00:00
//mxd
2015-03-03 09:42:54 +00:00
public virtual void OnChangeScale ( int incrementX , int incrementY )
2014-12-03 23:15:26 +00:00
{
2015-03-03 09:42:54 +00:00
if ( ! General . Map . UDMF | | ! Texture . IsImageLoaded ) return ;
Visual mode, UDMF: added "Scale Texture Up (X)", "Scale Texture Down (X)", "Scale Texture Up (Y)", "Scale Texture Down (Y)" actions. Default keys are Num6, Num4, Num8, Num5.
Visual mode, UDMF: renamed "Rotate Thing Clockwise" and "Rotate Thing Counterclockwise" actions to "Rotate Clockwise" and "Rotate Counterclockwise". These actions can now be used to change rotation of floor/ceiling textures.
Visual mode, UDMF: "Reset Texture Offsets" action now also resets sidedef's scale and floor/ceiling's scale and rotation.
Visual mode, UDMF: control line's OffsetX and OffsetY were not taken into account when calculating texture offsets of 3d floors' sides.
Visual mode, UDMF: fixed a ton of bugs in Auto align functions.
Visual mode, UDMF: when using "Move Texture Left/Right/Up/Down by 1" actions texture offsets were not updated properly when texture's scale was < 1.0.
Visual mode, UDMF: OffsetX and OffsetY were not taken into account in "Fit Texture Width/Height" actions.
Dockers Panel: added Pin/Unpin button, which acts the same as "Preferences -> Interface -> Side panels -> Auto hide" checkbox.
Texture size labels can now be disabled by unchecking "Preferences -> Interface -> Show texture and flat sizes in browsers" checkbox.
Texture size labels now are not shown for unknown textures.
Most of texture size labels had incorrect bg color.
ZDoom_linedefs.cfg: action specials 223 and 224 had incorrect Arg0.
2013-06-24 14:21:13 +00:00
if ( ( General . Map . UndoRedo . NextUndo = = null ) | | ( General . Map . UndoRedo . NextUndo . TicketID ! = undoticket ) )
undoticket = mode . CreateUndo ( "Change wall scale" ) ;
string keyX ;
string keyY ;
2014-12-03 23:15:26 +00:00
switch ( GeometryType )
{
Visual mode, UDMF: added "Scale Texture Up (X)", "Scale Texture Down (X)", "Scale Texture Up (Y)", "Scale Texture Down (Y)" actions. Default keys are Num6, Num4, Num8, Num5.
Visual mode, UDMF: renamed "Rotate Thing Clockwise" and "Rotate Thing Counterclockwise" actions to "Rotate Clockwise" and "Rotate Counterclockwise". These actions can now be used to change rotation of floor/ceiling textures.
Visual mode, UDMF: "Reset Texture Offsets" action now also resets sidedef's scale and floor/ceiling's scale and rotation.
Visual mode, UDMF: control line's OffsetX and OffsetY were not taken into account when calculating texture offsets of 3d floors' sides.
Visual mode, UDMF: fixed a ton of bugs in Auto align functions.
Visual mode, UDMF: when using "Move Texture Left/Right/Up/Down by 1" actions texture offsets were not updated properly when texture's scale was < 1.0.
Visual mode, UDMF: OffsetX and OffsetY were not taken into account in "Fit Texture Width/Height" actions.
Dockers Panel: added Pin/Unpin button, which acts the same as "Preferences -> Interface -> Side panels -> Auto hide" checkbox.
Texture size labels can now be disabled by unchecking "Preferences -> Interface -> Show texture and flat sizes in browsers" checkbox.
Texture size labels now are not shown for unknown textures.
Most of texture size labels had incorrect bg color.
ZDoom_linedefs.cfg: action specials 223 and 224 had incorrect Arg0.
2013-06-24 14:21:13 +00:00
case VisualGeometryType . WALL_UPPER :
keyX = "scalex_top" ;
keyY = "scaley_top" ;
break ;
case VisualGeometryType . WALL_MIDDLE :
case VisualGeometryType . WALL_MIDDLE_3D :
keyX = "scalex_mid" ;
keyY = "scaley_mid" ;
break ;
case VisualGeometryType . WALL_LOWER :
keyX = "scalex_bottom" ;
keyY = "scaley_bottom" ;
break ;
default :
throw new Exception ( "OnChangeTextureScale(): Got unknown GeometryType: " + GeometryType ) ;
}
float scaleX = Sidedef . Fields . GetValue ( keyX , 1.0f ) ;
float scaleY = Sidedef . Fields . GetValue ( keyY , 1.0f ) ;
Sidedef . Fields . BeforeFieldsChange ( ) ;
2015-03-03 09:42:54 +00:00
if ( incrementX ! = 0 )
2014-12-03 23:15:26 +00:00
{
Added, Visual mode, UDMF: added "Change Pitch Clockwise", "Change Pitch Counterclockwise", "Change Roll Clockwise" and "Change Roll Counterclockwise" actions.
Added, Visual mode, UDMF: added "Increase Scale" and "Decrease Scale" actions.
Added, Visual mode, UDMF: "Reset Texture Offsets" action now resets scale when used on things.
Added, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets scale, pitch and roll when used on things.
Changed, Visual mode, UDMF: "Reset Texture Offsets" action now only resets texture offsets (previously it also reset texture scale).
Changed, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets texture offsets, scale and brightness of sidedefs and also rotation of floors/ceilings.
Changed, Visual mode, UDMF: thing box arrow now displays pitch and roll for things, which have attached model and appropriate MODELDEF flags.
Changed, Thing Edit Form, UDMF: negative pitch and roll can now be entered.
Updated documentation.
2015-03-30 21:44:04 +00:00
float pix = ( int ) Math . Round ( Texture . Width * scaleX ) - incrementX ;
2015-03-03 09:42:54 +00:00
float newscaleX = ( float ) Math . Round ( pix / Texture . Width , 3 ) ;
scaleX = ( newscaleX = = 0 ? scaleX * - 1 : newscaleX ) ;
2013-08-10 11:28:51 +00:00
UDMFTools . SetFloat ( Sidedef . Fields , keyX , scaleX , 1.0f ) ;
Visual mode, UDMF: added "Scale Texture Up (X)", "Scale Texture Down (X)", "Scale Texture Up (Y)", "Scale Texture Down (Y)" actions. Default keys are Num6, Num4, Num8, Num5.
Visual mode, UDMF: renamed "Rotate Thing Clockwise" and "Rotate Thing Counterclockwise" actions to "Rotate Clockwise" and "Rotate Counterclockwise". These actions can now be used to change rotation of floor/ceiling textures.
Visual mode, UDMF: "Reset Texture Offsets" action now also resets sidedef's scale and floor/ceiling's scale and rotation.
Visual mode, UDMF: control line's OffsetX and OffsetY were not taken into account when calculating texture offsets of 3d floors' sides.
Visual mode, UDMF: fixed a ton of bugs in Auto align functions.
Visual mode, UDMF: when using "Move Texture Left/Right/Up/Down by 1" actions texture offsets were not updated properly when texture's scale was < 1.0.
Visual mode, UDMF: OffsetX and OffsetY were not taken into account in "Fit Texture Width/Height" actions.
Dockers Panel: added Pin/Unpin button, which acts the same as "Preferences -> Interface -> Side panels -> Auto hide" checkbox.
Texture size labels can now be disabled by unchecking "Preferences -> Interface -> Show texture and flat sizes in browsers" checkbox.
Texture size labels now are not shown for unknown textures.
Most of texture size labels had incorrect bg color.
ZDoom_linedefs.cfg: action specials 223 and 224 had incorrect Arg0.
2013-06-24 14:21:13 +00:00
}
2014-12-03 23:15:26 +00:00
if ( incrementY ! = 0 )
{
Added, Visual mode, UDMF: added "Change Pitch Clockwise", "Change Pitch Counterclockwise", "Change Roll Clockwise" and "Change Roll Counterclockwise" actions.
Added, Visual mode, UDMF: added "Increase Scale" and "Decrease Scale" actions.
Added, Visual mode, UDMF: "Reset Texture Offsets" action now resets scale when used on things.
Added, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets scale, pitch and roll when used on things.
Changed, Visual mode, UDMF: "Reset Texture Offsets" action now only resets texture offsets (previously it also reset texture scale).
Changed, Visual mode, UDMF: "Reset Local Texture Offsets" action now resets texture offsets, scale and brightness of sidedefs and also rotation of floors/ceilings.
Changed, Visual mode, UDMF: thing box arrow now displays pitch and roll for things, which have attached model and appropriate MODELDEF flags.
Changed, Thing Edit Form, UDMF: negative pitch and roll can now be entered.
Updated documentation.
2015-03-30 21:44:04 +00:00
float pix = ( int ) Math . Round ( Texture . Height * scaleY ) - incrementY ;
2015-03-03 09:42:54 +00:00
float newscaleY = ( float ) Math . Round ( pix / Texture . Height , 3 ) ;
scaleY = ( newscaleY = = 0 ? scaleY * - 1 : newscaleY ) ;
2013-08-10 11:28:51 +00:00
UDMFTools . SetFloat ( Sidedef . Fields , keyY , scaleY , 1.0f ) ;
Visual mode, UDMF: added "Scale Texture Up (X)", "Scale Texture Down (X)", "Scale Texture Up (Y)", "Scale Texture Down (Y)" actions. Default keys are Num6, Num4, Num8, Num5.
Visual mode, UDMF: renamed "Rotate Thing Clockwise" and "Rotate Thing Counterclockwise" actions to "Rotate Clockwise" and "Rotate Counterclockwise". These actions can now be used to change rotation of floor/ceiling textures.
Visual mode, UDMF: "Reset Texture Offsets" action now also resets sidedef's scale and floor/ceiling's scale and rotation.
Visual mode, UDMF: control line's OffsetX and OffsetY were not taken into account when calculating texture offsets of 3d floors' sides.
Visual mode, UDMF: fixed a ton of bugs in Auto align functions.
Visual mode, UDMF: when using "Move Texture Left/Right/Up/Down by 1" actions texture offsets were not updated properly when texture's scale was < 1.0.
Visual mode, UDMF: OffsetX and OffsetY were not taken into account in "Fit Texture Width/Height" actions.
Dockers Panel: added Pin/Unpin button, which acts the same as "Preferences -> Interface -> Side panels -> Auto hide" checkbox.
Texture size labels can now be disabled by unchecking "Preferences -> Interface -> Show texture and flat sizes in browsers" checkbox.
Texture size labels now are not shown for unknown textures.
Most of texture size labels had incorrect bg color.
ZDoom_linedefs.cfg: action specials 223 and 224 had incorrect Arg0.
2013-06-24 14:21:13 +00:00
}
//update geometry
Setup ( ) ;
2015-03-03 09:42:54 +00:00
mode . SetActionResult ( "Wall scale changed to " + scaleX . ToString ( "F03" , CultureInfo . InvariantCulture ) + ", " + scaleY . ToString ( "F03" , CultureInfo . InvariantCulture ) + " (" + ( int ) Math . Round ( Texture . Width / scaleX ) + " x " + ( int ) Math . Round ( Texture . Height / scaleY ) + ")." ) ;
Visual mode, UDMF: added "Scale Texture Up (X)", "Scale Texture Down (X)", "Scale Texture Up (Y)", "Scale Texture Down (Y)" actions. Default keys are Num6, Num4, Num8, Num5.
Visual mode, UDMF: renamed "Rotate Thing Clockwise" and "Rotate Thing Counterclockwise" actions to "Rotate Clockwise" and "Rotate Counterclockwise". These actions can now be used to change rotation of floor/ceiling textures.
Visual mode, UDMF: "Reset Texture Offsets" action now also resets sidedef's scale and floor/ceiling's scale and rotation.
Visual mode, UDMF: control line's OffsetX and OffsetY were not taken into account when calculating texture offsets of 3d floors' sides.
Visual mode, UDMF: fixed a ton of bugs in Auto align functions.
Visual mode, UDMF: when using "Move Texture Left/Right/Up/Down by 1" actions texture offsets were not updated properly when texture's scale was < 1.0.
Visual mode, UDMF: OffsetX and OffsetY were not taken into account in "Fit Texture Width/Height" actions.
Dockers Panel: added Pin/Unpin button, which acts the same as "Preferences -> Interface -> Side panels -> Auto hide" checkbox.
Texture size labels can now be disabled by unchecking "Preferences -> Interface -> Show texture and flat sizes in browsers" checkbox.
Texture size labels now are not shown for unknown textures.
Most of texture size labels had incorrect bg color.
ZDoom_linedefs.cfg: action specials 223 and 224 had incorrect Arg0.
2013-06-24 14:21:13 +00:00
}
2009-04-19 18:07:22 +00:00
#endregion
}
}