2009-07-12 09:32:53 +00:00
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 ;
2012-11-27 21:12:20 +00:00
using System.Collections.ObjectModel ;
2009-04-19 18:07:22 +00:00
using System.Drawing ;
2015-03-03 09:42:54 +00:00
using System.Globalization ;
2009-04-19 18:07:22 +00:00
using CodeImp.DoomBuilder.Map ;
using CodeImp.DoomBuilder.Geometry ;
using CodeImp.DoomBuilder.Rendering ;
2012-11-27 21:12:20 +00:00
using CodeImp.DoomBuilder.Types ;
2009-04-19 18:07:22 +00:00
using CodeImp.DoomBuilder.VisualModes ;
2014-01-13 08:06:56 +00:00
using CodeImp.DoomBuilder.Data ;
2009-04-19 18:07:22 +00:00
#endregion
namespace CodeImp.DoomBuilder.BuilderModes
{
internal sealed class VisualFloor : BaseVisualGeometrySector
{
#region = = = = = = = = = = = = = = = = = = Constants
#endregion
#region = = = = = = = = = = = = = = = = = = Variables
2013-03-18 13:52:27 +00:00
2016-01-16 12:46:44 +00:00
private bool innerside ; //mxd
2013-03-18 13:52:27 +00:00
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Properties
#endregion
#region = = = = = = = = = = = = = = = = = = Constructor / Setup
// Constructor
public VisualFloor ( BaseVisualMode mode , VisualSector vs ) : base ( mode , vs )
{
2013-09-11 09:47:53 +00:00
//mxd
2014-12-22 21:36:49 +00:00
geometrytype = VisualGeometryType . FLOOR ;
partname = "floor" ;
2016-01-16 12:46:44 +00:00
performautoselection = mode . UseSelectionFromClassicMode & & vs ! = null & & vs . Sector . Selected & & ( General . Map . ViewMode = = ViewMode . FloorTextures | | General . Map . ViewMode = = ViewMode . Normal ) ;
2013-09-11 09:47:53 +00:00
// We have no destructor
2009-04-19 18:07:22 +00:00
GC . SuppressFinalize ( this ) ;
}
// This builds the geometry. Returns false when no geometry created.
2014-12-03 23:15:26 +00:00
public override bool Setup ( SectorLevel level , Effect3DFloor extrafloor )
{
2016-01-16 12:46:44 +00:00
return Setup ( level , extrafloor , innerside ) ;
2013-03-18 13:52:27 +00:00
}
//mxd
2016-01-16 12:46:44 +00:00
public bool Setup ( SectorLevel level , Effect3DFloor extrafloor , bool innerside )
2009-04-19 18:07:22 +00:00
{
2012-11-27 21:12:20 +00:00
Sector s = level . sector ;
Vector2D texscale ;
2016-01-16 12:46:44 +00:00
this . innerside = innerside ;
2012-11-27 21:12:20 +00:00
base . Setup ( level , extrafloor ) ;
// Fetch ZDoom fields
float rotate = Angle2D . DegToRad ( s . Fields . GetValue ( "rotationfloor" , 0.0f ) ) ;
Vector2D offset = new Vector2D ( s . Fields . GetValue ( "xpanningfloor" , 0.0f ) ,
s . Fields . GetValue ( "ypanningfloor" , 0.0f ) ) ;
Vector2D scale = new Vector2D ( s . Fields . GetValue ( "xscalefloor" , 1.0f ) ,
s . Fields . GetValue ( "yscalefloor" , 1.0f ) ) ;
2009-04-19 18:07:22 +00:00
2013-03-18 13:52:27 +00:00
//Load floor texture
2015-10-02 14:47:34 +00:00
if ( s . LongFloorTexture ! = MapSet . EmptyLongName )
2013-07-31 12:38:47 +00:00
{
base . Texture = General . Map . Data . GetFlatImage ( s . LongFloorTexture ) ;
2014-01-13 08:06:56 +00:00
if ( base . Texture = = null | | base . Texture is UnknownImage )
2013-07-31 12:38:47 +00:00
{
base . Texture = General . Map . Data . UnknownTexture3D ;
2013-04-26 12:32:51 +00:00
setuponloadedtexture = s . LongFloorTexture ;
2013-07-31 12:38:47 +00:00
}
2016-04-19 20:40:42 +00:00
else if ( ! base . Texture . IsImageLoaded )
2013-07-31 12:38:47 +00:00
{
2016-04-19 20:40:42 +00:00
setuponloadedtexture = s . LongFloorTexture ;
2013-07-31 12:38:47 +00:00
}
2015-02-06 21:03:20 +00:00
}
else
{
2013-07-31 12:38:47 +00:00
// Use missing texture
base . Texture = General . Map . Data . MissingTexture3D ;
setuponloadedtexture = 0 ;
2013-04-26 12:32:51 +00:00
}
2012-11-27 21:12:20 +00:00
// Determine texture scale
if ( base . Texture . IsImageLoaded )
texscale = new Vector2D ( 1.0f / base . Texture . ScaledWidth , 1.0f / base . Texture . ScaledHeight ) ;
else
texscale = new Vector2D ( 1.0f / 64.0f , 1.0f / 64.0f ) ;
2017-02-01 18:16:42 +00:00
// Determine brightness
byte alpha = ( byte ) General . Clamp ( level . alpha , 0 , 255 ) ;
int color = PixelColor . FromInt ( level . color ) . WithAlpha ( alpha ) . ToInt ( ) ;
//mxd. Top extrafloor level should calculate fogdensity
//from the brightness of the level above it
SectorData sd = mode . GetSectorData ( this . Sector . Sector ) ;
int targetbrightness ;
2016-01-11 13:00:52 +00:00
if ( extrafloor ! = null & & extrafloor . VavoomType & & ! level . disablelighting )
{
targetbrightness = 0 ;
for ( int i = 0 ; i < sd . LightLevels . Count - 1 ; i + + )
2015-12-04 12:29:22 +00:00
{
2016-01-11 13:00:52 +00:00
if ( sd . LightLevels [ i ] = = level )
2015-12-04 12:29:22 +00:00
{
2016-01-11 13:00:52 +00:00
targetbrightness = sd . LightLevels [ i + 1 ] . brightnessbelow ;
break ;
2015-12-04 12:29:22 +00:00
}
}
2016-01-11 13:00:52 +00:00
}
else
{
targetbrightness = level . brightnessbelow ;
2015-10-02 14:47:34 +00:00
}
2015-02-26 14:42:58 +00:00
2017-02-01 18:16:42 +00:00
// [ZZ] Apply Doom 64 lighting here (for extrafloor)
2017-02-02 05:34:21 +00:00
if ( extrafloor ! = null ) color = PixelColor . Modulate ( PixelColor . FromInt ( color ) , extrafloor . ColorFloor ) . WithAlpha ( alpha ) . ToInt ( ) ;
2017-02-01 18:16:42 +00:00
//mxd. Determine fog density
fogfactor = CalculateFogFactor ( targetbrightness ) ;
2016-01-11 13:00:52 +00:00
2009-04-19 18:07:22 +00:00
// Make vertices
2016-01-11 13:00:52 +00:00
ReadOnlyCollection < Vector2D > triverts = Sector . Sector . Triangles . Vertices ;
2014-09-22 09:04:30 +00:00
WorldVertex [ ] verts = new WorldVertex [ triverts . Count ] ;
2012-11-27 21:12:20 +00:00
for ( int i = 0 ; i < triverts . Count ; i + + )
2009-04-19 18:07:22 +00:00
{
2012-11-27 21:12:20 +00:00
// Color shading
2015-02-26 14:42:58 +00:00
verts [ i ] . c = color ; //mxd
2012-11-27 21:12:20 +00:00
// Vertex coordinates
verts [ i ] . x = triverts [ i ] . x ;
verts [ i ] . y = triverts [ i ] . y ;
2015-05-28 10:04:42 +00:00
verts [ i ] . z = level . plane . GetZ ( triverts [ i ] ) ;
2009-04-19 18:07:22 +00:00
2012-11-27 21:12:20 +00:00
// Texture coordinates
Vector2D pos = triverts [ i ] ;
pos = pos . GetRotated ( rotate ) ;
pos . y = - pos . y ;
pos = ( pos + offset ) * scale * texscale ;
verts [ i ] . u = pos . x ;
verts [ i ] . v = pos . y ;
}
2009-04-19 18:07:22 +00:00
2012-11-27 21:12:20 +00:00
// The sector triangulation created clockwise triangles that
// are right up for the floor. For the ceiling we must flip
// the triangles upside down.
2016-01-16 12:46:44 +00:00
if ( ( extrafloor ! = null ) & & ! extrafloor . VavoomType & & ! innerside )
2012-11-27 21:12:20 +00:00
SwapTriangleVertices ( verts ) ;
// Determine render pass
if ( extrafloor ! = null )
{
2017-03-19 16:19:14 +00:00
if ( extrafloor . Sloped3dFloor ) //mxd
2015-05-31 21:11:21 +00:00
this . RenderPass = RenderPass . Mask ;
2017-03-19 16:19:14 +00:00
else if ( extrafloor . RenderAdditive ) //mxd
2013-03-18 13:52:27 +00:00
this . RenderPass = RenderPass . Additive ;
2017-03-19 16:19:14 +00:00
else if ( ( level . alpha < 255 ) | | Texture . IsTranslucent )
2012-11-27 21:12:20 +00:00
this . RenderPass = RenderPass . Alpha ;
else
this . RenderPass = RenderPass . Mask ;
}
else
{
this . RenderPass = RenderPass . Solid ;
2009-04-19 18:07:22 +00:00
}
2016-01-11 13:00:52 +00:00
//mxd. Update sky render flag
2016-11-30 20:12:32 +00:00
renderassky = ( level . sector . FloorTexture = = General . Map . Config . SkyFlatName ) ;
2009-04-19 18:07:22 +00:00
// Apply vertices
base . SetVertices ( verts ) ;
return ( verts . Length > 0 ) ;
}
2016-01-11 13:00:52 +00:00
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Methods
2012-11-27 21:12:20 +00:00
2016-09-06 12:05:47 +00:00
//mxd
public override void OnChangeScale ( int incrementX , int incrementY )
{
// Only do this when not done yet in this call
// Because we may be able to select the same 3D floor multiple times through multiple sectors
SectorData sd = mode . GetSectorData ( level . sector ) ;
if ( ! sd . FloorChanged )
{
sd . FloorChanged = true ;
base . OnChangeScale ( incrementX , incrementY ) ;
}
}
//mxd
public override void OnChangeTextureRotation ( float angle )
{
// Only do this when not done yet in this call
// Because we may be able to select the same 3D floor multiple times through multiple sectors
SectorData sd = mode . GetSectorData ( level . sector ) ;
if ( ! sd . FloorChanged )
{
sd . FloorChanged = true ;
base . OnChangeTextureRotation ( angle ) ;
}
}
2012-11-27 21:12:20 +00:00
// Return texture coordinates
protected override Point GetTextureOffset ( )
{
2015-11-20 14:31:54 +00:00
return new Point { X = ( int ) Sector . Sector . Fields . GetValue ( "xpanningfloor" , 0.0f ) ,
Y = ( int ) Sector . Sector . Fields . GetValue ( "ypanningfloor" , 0.0f ) } ;
2012-11-27 21:12:20 +00:00
}
2016-09-06 12:05:47 +00:00
//mxd
public override void OnChangeTextureOffset ( int horizontal , int vertical , bool doSurfaceAngleCorrection )
{
// Only do this when not done yet in this call
// Because we may be able to select the same 3D floor multiple times through multiple sectors
SectorData sd = mode . GetSectorData ( level . sector ) ;
if ( ! sd . FloorChanged )
{
sd . FloorChanged = true ;
base . OnChangeTextureOffset ( horizontal , vertical , doSurfaceAngleCorrection ) ;
}
}
2012-11-27 21:12:20 +00:00
// Move texture coordinates
2016-09-06 12:05:47 +00:00
protected override void MoveTextureOffset ( int offsetx , int offsety )
2012-11-27 21:12:20 +00:00
{
2013-09-11 09:47:53 +00:00
//mxd
Sector s = GetControlSector ( ) ;
s . Fields . BeforeFieldsChange ( ) ;
2016-09-06 12:05:47 +00:00
float nx = ( s . Fields . GetValue ( "xpanningfloor" , 0.0f ) + offsetx ) % ( Texture . ScaledWidth / s . Fields . GetValue ( "xscalefloor" , 1.0f ) ) ;
float ny = ( s . Fields . GetValue ( "ypanningfloor" , 0.0f ) + offsety ) % ( Texture . ScaledHeight / s . Fields . GetValue ( "yscalefloor" , 1.0f ) ) ;
2013-09-11 09:47:53 +00:00
s . Fields [ "xpanningfloor" ] = new UniValue ( UniversalType . Float , nx ) ;
s . Fields [ "ypanningfloor" ] = new UniValue ( UniversalType . Float , ny ) ;
s . UpdateNeeded = true ;
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
mode . SetActionResult ( "Changed floor texture offsets to " + nx + ", " + ny + "." ) ;
}
//mxd. Texture scale change
2015-03-03 09:42:54 +00:00
protected override void ChangeTextureScale ( int incrementX , int incrementY )
2014-12-03 23:15:26 +00:00
{
2016-09-02 19:18:37 +00:00
if ( Texture = = null | | ! 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
Sector s = GetControlSector ( ) ;
float scaleX = s . Fields . GetValue ( "xscalefloor" , 1.0f ) ;
float scaleY = s . Fields . GetValue ( "yscalefloor" , 1.0f ) ;
s . Fields . BeforeFieldsChange ( ) ;
2014-12-03 23:15:26 +00:00
if ( incrementX ! = 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 . 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 ) ;
Removed "Paste Properties Options" action.
Added "Paste Properties Special" actions in "Classic" and "Visual" categories. They work the same way as "Paste Special" action.
Added: "Copy Properties", "Paste Properties" and "Paste Properties Special" options are now shown in the Edit menu if current classic mode supports them.
Changed, Paste Properties Special window: only options relevant to current map format are now displayed.
Changed, Paste Properties Special window, UDMF: all UI-managed options are now available.
Fixed: MAPINFO parser was unable to process "include" directives.
Fixed, General interface: selection info was reset to "Nothing selected" after few seconds regardless of current selection.
Fixed, Visual mode: thing bounding boxes were not updated when changing things positions using Randomize mode.
Fixed, Visual mode: event lines were displayed at incorrect height when entering Visual mode for the first time.
Fixed, Texture Browser window: when MixTexturesFlats Game Configuration option is disabled, textures/flats are no longer shown in the Used group when flats/textures with the same names are used in the map.
Fixed(?): probably fixed an exception some users reported when trying to initialize a Classic mode after switching from Visual mode with "Sync cameras" option enabled.
Changed, Game configurations, Thing Categories: a block must have at least one thing category property to be recognized as a thing category.
Changed, Visplane Explorer: the plugin now outputs more info when it fails to initialize vpo.dll.
Cosmetic, Thing Edit window, Doom/Hexen map format: adjusted UI layout so thing flags control no longer displays scrollbars in Hexen map format.
Internal: merged methods from UDMFTools into UniFields, removed UDMFTools.
Updated Inno Setup script (added VC++ 2008 SP1 distributive).
Updated ZDoom_DECORATE.cfg (A_CheckBlock).
Updated documentation (added "System Requirements" page).
2015-10-09 12:38:12 +00:00
UniFields . SetFloat ( s . Fields , "xscalefloor" , 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 ) ;
Removed "Paste Properties Options" action.
Added "Paste Properties Special" actions in "Classic" and "Visual" categories. They work the same way as "Paste Special" action.
Added: "Copy Properties", "Paste Properties" and "Paste Properties Special" options are now shown in the Edit menu if current classic mode supports them.
Changed, Paste Properties Special window: only options relevant to current map format are now displayed.
Changed, Paste Properties Special window, UDMF: all UI-managed options are now available.
Fixed: MAPINFO parser was unable to process "include" directives.
Fixed, General interface: selection info was reset to "Nothing selected" after few seconds regardless of current selection.
Fixed, Visual mode: thing bounding boxes were not updated when changing things positions using Randomize mode.
Fixed, Visual mode: event lines were displayed at incorrect height when entering Visual mode for the first time.
Fixed, Texture Browser window: when MixTexturesFlats Game Configuration option is disabled, textures/flats are no longer shown in the Used group when flats/textures with the same names are used in the map.
Fixed(?): probably fixed an exception some users reported when trying to initialize a Classic mode after switching from Visual mode with "Sync cameras" option enabled.
Changed, Game configurations, Thing Categories: a block must have at least one thing category property to be recognized as a thing category.
Changed, Visplane Explorer: the plugin now outputs more info when it fails to initialize vpo.dll.
Cosmetic, Thing Edit window, Doom/Hexen map format: adjusted UI layout so thing flags control no longer displays scrollbars in Hexen map format.
Internal: merged methods from UDMFTools into UniFields, removed UDMFTools.
Updated Inno Setup script (added VC++ 2008 SP1 distributive).
Updated ZDoom_DECORATE.cfg (A_CheckBlock).
Updated documentation (added "System Requirements" page).
2015-10-09 12:38:12 +00:00
UniFields . SetFloat ( s . Fields , "yscalefloor" , 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
}
2015-03-03 09:42:54 +00:00
mode . SetActionResult ( "Floor 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 ) + ")." ) ;
2012-11-27 21:12:20 +00:00
}
2013-04-16 12:52:40 +00:00
//mxd
2014-12-03 23:15:26 +00:00
public override void OnResetTextureOffset ( )
{
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
ClearFields ( new [ ] { "xpanningfloor" , "ypanningfloor" } , "Reset texture offsets" , "Texture offsets reset." ) ;
2013-04-16 12:52:40 +00:00
}
2013-09-19 09:17:49 +00:00
//mxd
2014-12-03 23:15:26 +00:00
public override void OnResetLocalTextureOffset ( )
{
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
ClearFields ( new [ ] { "xpanningfloor" , "ypanningfloor" , "xscalefloor" , "yscalefloor" , "rotationfloor" , "lightfloor" , "lightfloorabsolute" } ,
"Reset texture offsets, scale, rotation and brightness" , "Texture offsets, scale, rotation and brightness reset." ) ;
2013-09-19 09:17:49 +00:00
}
2009-04-19 18:07:22 +00:00
// Paste texture
public override void OnPasteTexture ( )
{
if ( BuilderPlug . Me . CopiedFlat ! = null )
{
2016-03-08 20:37:44 +00:00
mode . CreateUndo ( "Paste floor \"" + BuilderPlug . Me . CopiedFlat + "\"" ) ;
mode . SetActionResult ( "Pasted flat \"" + BuilderPlug . Me . CopiedFlat + "\" on floor." ) ;
Added, Visual mode, GLDEFS, GLOOME: subtractive glow is now supported.
Changed, Visual mode: changed thing fog calculation logic. Should be closer to GZDoom now.
Fixed, GLDEFS parser: "height" texture parameter was not treated as optional.
Fixed, text lump parsers: in some cases incorrect line number was displayed in error and warning messages.
Fixed, Visual mode: glow effect was not applied to sectors with 3 sidedefs.
Fixed, Visual mode: in some cases glow effect was not updated when replacing textures.
Fixed, general interface: "Full Brightness" button state was not updated during map loading.
Fixed, Drag Linedefs/Vertices/Sectors/Things modes: positions of line length labels were not updated while panning the view.
Cosmetic: added a bunch of new icons.
Cosmetic: changed Visual mode crosshair.
2015-08-27 20:46:49 +00:00
2009-04-19 18:07:22 +00:00
SetTexture ( BuilderPlug . Me . CopiedFlat ) ;
2013-03-18 13:52:27 +00:00
2016-04-19 20:40:42 +00:00
// Update
if ( mode . VisualSectorExists ( level . sector ) )
{
BaseVisualSector vs = ( BaseVisualSector ) mode . GetVisualSector ( level . sector ) ;
vs . UpdateSectorGeometry ( false ) ;
}
2009-04-19 18:07:22 +00:00
}
}
2012-11-27 21:12:20 +00:00
// Call to change the height
public override void OnChangeTargetHeight ( int amount )
{
// Only do this when not done yet in this call
// Because we may be able to select the same 3D floor multiple times through multiple sectors
SectorData sd = mode . GetSectorData ( level . sector ) ;
if ( ! sd . FloorChanged )
{
sd . FloorChanged = true ;
base . OnChangeTargetHeight ( amount ) ;
}
}
2009-04-19 18:07:22 +00:00
// This changes the height
protected override void ChangeHeight ( int amount )
{
2012-11-27 21:12:20 +00:00
mode . CreateUndo ( "Change floor height" , UndoGroup . FloorHeightChange , level . sector . FixedIndex ) ;
2014-10-17 11:55:08 +00:00
level . sector . FloorHeight + = amount ;
if ( General . Map . UDMF )
{
//mxd. Modify vertex offsets?
if ( level . sector . Sidedefs . Count = = 3 )
{
ChangeVertexHeight ( amount ) ;
}
//mxd. Modify slope offset?
if ( level . sector . FloorSlope . GetLengthSq ( ) > 0 )
{
Vector3D center = new Vector3D ( level . sector . BBox . X + level . sector . BBox . Width / 2 ,
level . sector . BBox . Y + level . sector . BBox . Height / 2 ,
level . sector . FloorHeight ) ;
Plane p = new Plane ( center ,
level . sector . FloorSlope . GetAngleXY ( ) + Angle2D . PIHALF ,
- level . sector . FloorSlope . GetAngleZ ( ) ,
true ) ;
level . sector . FloorSlopeOffset = p . Offset ;
}
2014-02-03 11:19:12 +00:00
}
2012-11-27 21:12:20 +00:00
mode . SetActionResult ( "Changed floor height to " + level . sector . FloorHeight + "." ) ;
2009-04-19 18:07:22 +00:00
}
2014-02-03 11:19:12 +00:00
//mxd
2014-10-17 11:55:08 +00:00
private void ChangeVertexHeight ( int amount )
{
2016-05-20 15:04:00 +00:00
HashSet < Vertex > verts = new HashSet < Vertex > ( ) ;
2014-02-03 11:19:12 +00:00
2016-05-20 15:04:00 +00:00
// Do this only if all 3 verts have offsets
2014-10-17 11:55:08 +00:00
foreach ( Sidedef side in level . sector . Sidedefs )
{
if ( float . IsNaN ( side . Line . Start . ZFloor ) | | float . IsNaN ( side . Line . End . ZFloor ) ) return ;
2016-05-20 15:04:00 +00:00
verts . Add ( side . Line . Start ) ;
verts . Add ( side . Line . End ) ;
2014-02-03 11:19:12 +00:00
}
2015-12-28 15:01:53 +00:00
foreach ( Vertex v in verts )
2014-02-03 11:19:12 +00:00
mode . GetVisualVertex ( v , true ) . OnChangeTargetHeight ( amount ) ;
}
2013-09-11 09:47:53 +00:00
//mxd. Sector brightness change
2014-12-03 23:15:26 +00:00
public override void OnChangeTargetBrightness ( bool up )
{
2015-11-20 14:31:54 +00:00
if ( level ! = null )
2014-12-03 23:15:26 +00:00
{
2015-12-02 13:55:15 +00:00
// This floor is part of 3D-floor
if ( level . sector ! = Sector . Sector )
2016-02-22 13:04:06 +00:00
{
BaseVisualSector vs = ( BaseVisualSector ) mode . GetVisualSector ( level . sector ) ;
vs . Floor . OnChangeTargetBrightness ( up ) ;
vs . UpdateSectorGeometry ( true ) ;
}
2015-12-02 13:55:15 +00:00
// This is actual floor of a sector with extrafloors
else if ( Sector . ExtraFloors . Count > 0 & & ! Sector . ExtraFloors [ 0 ] . ExtraFloor . Floor . restrictlighting & & ! Sector . ExtraFloors [ 0 ] . ExtraFloor . Floor . disablelighting )
2016-02-22 13:04:06 +00:00
{
2013-09-11 09:47:53 +00:00
Sector . ExtraFloors [ 0 ] . OnChangeTargetBrightness ( up ) ;
2016-02-22 13:04:06 +00:00
}
2013-09-11 09:47:53 +00:00
else
2016-02-22 13:04:06 +00:00
{
2013-09-11 09:47:53 +00:00
base . OnChangeTargetBrightness ( up ) ;
2016-02-22 13:04:06 +00:00
}
2014-12-03 23:15:26 +00:00
}
else
{
2013-09-11 09:47:53 +00:00
base . OnChangeTargetBrightness ( up ) ;
}
}
2012-11-27 21:12:20 +00:00
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 )
{
2012-11-27 21:12:20 +00:00
// Check if our ray starts at the correct side of the plane
2016-01-16 12:46:44 +00:00
if ( ( ! innerside & & level . plane . Distance ( from ) > 0.0f ) | | ( innerside & & level . plane . Distance ( from ) < 0.0f ) )
2009-04-19 18:07:22 +00:00
{
2012-11-27 21:12:20 +00:00
// Calculate the intersection
if ( level . plane . GetIntersection ( from , to , ref pickrayu ) )
{
if ( pickrayu > 0.0f )
{
pickintersect = from + ( to - from ) * pickrayu ;
// Intersection point within bbox?
RectangleF bbox = Sector . Sector . BBox ;
return ( ( pickintersect . x > = bbox . Left ) & & ( pickintersect . x < = bbox . Right ) & &
( pickintersect . y > = bbox . Top ) & & ( pickintersect . y < = bbox . Bottom ) ) ;
}
}
2009-04-19 18:07:22 +00:00
}
2012-11-27 21:12:20 +00:00
return false ;
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 )
{
u_ray = pickrayu ;
// Check on which side of the nearest sidedef we are
Sidedef sd = MapSet . NearestSidedef ( Sector . Sector . Sidedefs , pickintersect ) ;
float side = sd . Line . SideOfLine ( pickintersect ) ;
2016-01-26 22:29:12 +00:00
//mxd. Alpha based picking. Used only on extrafloors with transparent or masked textures
if ( ( side < = 0.0f & & sd . IsFront ) | | ( side > 0.0f & & ! sd . IsFront ) )
{
2016-06-13 23:37:55 +00:00
if ( ! BuilderPlug . Me . AlphaBasedTextureHighlighting | | ! Texture . IsImageLoaded | | extrafloor = = null | | RenderPass = = RenderPass . Solid | | ( ! Texture . IsTranslucent & & ! Texture . IsMasked ) )
2016-01-26 22:29:12 +00:00
return true ;
2016-03-23 21:26:26 +00:00
// Some textures (e.g. HiResImage) may lie about their size, so use bitmap size instead
Bitmap image = Texture . GetBitmap ( ) ;
2017-05-09 03:06:07 +00:00
lock ( image )
{
// Fetch ZDoom fields
float rotate = Angle2D . DegToRad ( level . sector . Fields . GetValue ( "rotationfloor" , 0.0f ) ) ;
Vector2D offset = new Vector2D ( level . sector . Fields . GetValue ( "xpanningfloor" , 0.0f ) , level . sector . Fields . GetValue ( "ypanningfloor" , 0.0f ) ) ;
Vector2D scale = new Vector2D ( level . sector . Fields . GetValue ( "xscalefloor" , 1.0f ) , level . sector . Fields . GetValue ( "yscalefloor" , 1.0f ) ) ;
Vector2D texscale = new Vector2D ( 1.0f / Texture . ScaledWidth , 1.0f / Texture . ScaledHeight ) ;
// Texture coordinates
Vector2D o = pickintersect ;
o = o . GetRotated ( rotate ) ;
o . y = - o . y ;
o = ( o + offset ) * scale * texscale ;
o . x = ( o . x * image . Width ) % image . Width ;
o . y = ( o . y * image . Height ) % image . Height ;
// Make sure coordinates are inside of texture dimensions...
if ( o . x < 0 ) o . x + = image . Width ;
if ( o . y < 0 ) o . y + = image . Height ;
// Make final texture coordinates...
int ox = General . Clamp ( ( int ) Math . Floor ( o . x ) , 0 , image . Width - 1 ) ;
int oy = General . Clamp ( ( int ) Math . Floor ( o . y ) , 0 , image . Height - 1 ) ;
// Check pixel alpha
return ( image . GetPixel ( ox , oy ) . A > 0 ) ;
}
2016-01-26 22:29:12 +00:00
}
return false ;
2009-04-19 18:07:22 +00:00
}
2009-05-06 07:26:12 +00:00
2009-04-19 18:07:22 +00:00
// Return texture name
public override string GetTextureName ( )
{
2012-11-27 21:12:20 +00:00
return level . sector . FloorTexture ;
2009-04-19 18:07:22 +00:00
}
// This changes the texture
protected override void SetTexture ( string texturename )
{
2016-03-08 20:37:44 +00:00
// Set new texture
2012-11-27 21:12:20 +00:00
level . sector . SetFloorTexture ( texturename ) ;
2009-04-19 18:07:22 +00:00
General . Map . Data . UpdateUsedTextures ( ) ;
}
2013-04-01 11:06:01 +00:00
//mxd
2014-09-22 09:04:30 +00:00
public override void SelectNeighbours ( bool select , bool withSameTexture , bool withSameHeight )
{
2015-12-09 19:55:30 +00:00
if ( ! withSameTexture & & ! withSameHeight ) return ;
2013-04-01 11:06:01 +00:00
2015-12-09 19:55:30 +00:00
if ( select & & ! selected )
2014-09-22 11:51:49 +00:00
{
2013-04-01 11:06:01 +00:00
selected = true ;
mode . AddSelectedObject ( this ) ;
2014-09-22 09:04:30 +00:00
}
2015-12-09 19:55:30 +00:00
else if ( ! select & & selected )
2014-09-22 09:04:30 +00:00
{
2013-04-01 11:06:01 +00:00
selected = false ;
mode . RemoveSelectedObject ( this ) ;
}
List < Sector > neighbours = new List < Sector > ( ) ;
2016-05-04 14:02:13 +00:00
bool regularorvavoom = ( extrafloor = = null | | extrafloor . VavoomType ) ;
2013-04-01 11:06:01 +00:00
//collect neighbour sectors
2014-09-22 09:04:30 +00:00
foreach ( Sidedef side in Sector . Sector . Sidedefs )
{
2015-12-09 19:55:30 +00:00
if ( side . Other ! = null & & side . Other . Sector ! = Sector . Sector & & ! neighbours . Contains ( side . Other . Sector ) )
2014-09-22 09:04:30 +00:00
{
2016-04-19 20:40:42 +00:00
BaseVisualSector vs = ( BaseVisualSector ) mode . GetVisualSector ( side . Other . Sector ) ;
2015-12-09 19:55:30 +00:00
if ( vs = = null ) continue ;
2013-04-01 11:06:01 +00:00
2014-09-22 09:04:30 +00:00
// When current floor is part of a 3d floor, it looks like a ceiling, so we need to select adjacent ceilings
2015-12-09 19:55:30 +00:00
if ( level . sector ! = Sector . Sector & & ! regularorvavoom )
2014-09-22 09:04:30 +00:00
{
2016-05-12 11:32:10 +00:00
if ( ( ! withSameTexture | | side . Other . Sector . LongCeilTexture = = level . sector . LongFloorTexture ) & &
( ! withSameHeight | | side . Other . Sector . CeilHeight = = level . sector . FloorHeight ) )
2014-09-22 09:04:30 +00:00
{
neighbours . Add ( side . Other . Sector ) ;
//(de)select regular visual ceiling?
2015-12-09 19:55:30 +00:00
if ( select ! = vs . Ceiling . Selected )
2014-09-22 09:04:30 +00:00
vs . Ceiling . SelectNeighbours ( select , withSameTexture , withSameHeight ) ;
}
}
2014-09-22 11:51:49 +00:00
else // Regular floor or vavoom-type extrafloor
2014-09-22 09:04:30 +00:00
{
// (De)select adjacent floor
2016-05-12 11:32:10 +00:00
if ( ( ! withSameTexture | | side . Other . Sector . LongFloorTexture = = level . sector . LongFloorTexture ) & &
( ! withSameHeight | | side . Other . Sector . FloorHeight = = level . sector . FloorHeight ) )
2014-09-22 09:04:30 +00:00
{
neighbours . Add ( side . Other . Sector ) ;
//(de)select regular visual floor?
2015-12-09 19:55:30 +00:00
if ( select ! = vs . Floor . Selected )
2014-09-22 09:04:30 +00:00
vs . Floor . SelectNeighbours ( select , withSameTexture , withSameHeight ) ;
}
2014-09-22 11:51:49 +00:00
}
// (De)select adjacent extra floors
2014-12-03 23:15:26 +00:00
foreach ( VisualFloor ef in vs . ExtraFloors )
{
2015-12-09 19:55:30 +00:00
if ( select = = ef . Selected | | ef . extrafloor . VavoomType ! = regularorvavoom ) continue ;
2016-05-12 11:32:10 +00:00
if ( ( ! withSameTexture | | level . sector . LongFloorTexture = = ef . level . sector . LongFloorTexture ) & &
( ! withSameHeight | | level . sector . FloorHeight = = ef . level . sector . FloorHeight ) )
2014-09-22 09:04:30 +00:00
{
2014-09-22 11:51:49 +00:00
ef . SelectNeighbours ( select , withSameTexture , withSameHeight ) ;
}
}
2014-09-22 09:04:30 +00:00
2014-09-22 11:51:49 +00:00
// (De)select adjacent vavoom type extra ceilings
foreach ( VisualCeiling ec in vs . ExtraCeilings )
{
if ( select = = ec . Selected | | ec . ExtraFloor . VavoomType = = regularorvavoom ) continue ;
2016-05-12 11:32:10 +00:00
if ( ( ! withSameTexture | | level . sector . LongFloorTexture = = ec . Level . sector . LongCeilTexture ) & &
( ! withSameHeight | | level . sector . FloorHeight = = ec . Level . sector . CeilHeight ) )
2014-09-22 11:51:49 +00:00
{
ec . SelectNeighbours ( select , withSameTexture , withSameHeight ) ;
2014-09-22 09:04:30 +00:00
}
}
2013-04-01 11:06:01 +00:00
}
}
}
2013-04-26 12:32:51 +00:00
//mxd
2014-12-03 23:15:26 +00:00
public void AlignTexture ( bool alignx , bool aligny )
{
2013-04-26 12:32:51 +00:00
if ( ! General . Map . UDMF ) return ;
2013-05-29 14:18:49 +00:00
//is is a surface with line slope?
2013-04-26 12:32:51 +00:00
float slopeAngle = level . plane . Normal . GetAngleZ ( ) - Angle2D . PIHALF ;
2014-12-03 23:15:26 +00:00
if ( slopeAngle = = 0 ) //it's a horizontal plane
{
AlignTextureToClosestLine ( alignx , aligny ) ;
}
else //it can be a surface with line slope
{
2013-05-29 14:18:49 +00:00
Linedef slopeSource = null ;
bool isFront = false ;
2014-12-03 23:15:26 +00:00
foreach ( Sidedef side in Sector . Sector . Sidedefs )
{
if ( side . Line . Action = = 181 )
{
if ( side . Line . Args [ 0 ] = = 1 & & side . Line . Front ! = null & & side . Line . Front = = side )
{
2013-05-29 14:18:49 +00:00
slopeSource = side . Line ;
isFront = true ;
break ;
2016-05-12 11:32:10 +00:00
}
if ( side . Line . Args [ 0 ] = = 2 & & side . Line . Back ! = null & & side . Line . Back = = side )
2014-12-03 23:15:26 +00:00
{
2013-05-29 14:18:49 +00:00
slopeSource = side . Line ;
break ;
}
2013-04-26 12:32:51 +00:00
}
}
2013-05-29 14:18:49 +00:00
if ( slopeSource ! = null & & slopeSource . Front ! = null & & slopeSource . Front . Sector ! = null & & slopeSource . Back ! = null & & slopeSource . Back . Sector ! = null )
2014-12-03 23:15:26 +00:00
AlignTextureToSlopeLine ( slopeSource , slopeAngle , isFront , alignx , aligny ) ;
2013-04-26 12:32:51 +00:00
else
2014-12-03 23:15:26 +00:00
AlignTextureToClosestLine ( alignx , aligny ) ;
2013-04-26 12:32:51 +00:00
}
}
2009-04-19 18:07:22 +00:00
#endregion
}
}