2010-09-11 20:14:36 +00:00
#region = = = Copyright ( c ) 2010 Pascal van der Heiden = = =
using System ;
2015-05-31 21:11:21 +00:00
using CodeImp.DoomBuilder.Geometry ;
2010-09-11 20:14:36 +00:00
using CodeImp.DoomBuilder.Map ;
using CodeImp.DoomBuilder.Rendering ;
#endregion
2012-11-27 21:12:20 +00:00
namespace CodeImp.DoomBuilder.BuilderModes
2010-09-11 20:14:36 +00:00
{
internal class Effect3DFloor : SectorEffect
{
// Linedef that is used to create this effect
// The sector can be found by linedef.Front.Sector
2015-11-20 14:31:54 +00:00
private readonly Linedef linedef ;
2010-09-11 20:14:36 +00:00
// Floor and ceiling planes
2017-02-01 18:16:42 +00:00
public PixelColor ColorFloor { get ; private set ; }
2010-09-11 20:14:36 +00:00
private SectorLevel floor ;
2017-02-01 18:16:42 +00:00
public PixelColor ColorCeiling { get ; private set ; }
2010-09-11 20:14:36 +00:00
private SectorLevel ceiling ;
// Alpha transparency
private int alpha ;
2010-09-15 18:17:38 +00:00
// Vavoom type?
private bool vavoomtype ;
2010-09-11 20:14:36 +00:00
2015-11-20 14:31:54 +00:00
//mxd. Render backsides?
2015-02-07 17:52:39 +00:00
private bool renderinside ;
2013-03-18 13:52:27 +00:00
2015-05-31 21:11:21 +00:00
//mxd. Dirty hack to emulate GZDoom behaviour?
private bool sloped3dfloor ;
2015-11-20 14:31:54 +00:00
//mxd. Render using Additive pass?
private bool renderadditive ;
//mxd. Sidedef should be clipped by floor/ceiling?
private bool clipsides ;
2013-03-18 13:52:27 +00:00
//mxd. Ignore Bottom Height?
2015-02-07 17:52:39 +00:00
private bool ignorebottomheight ;
2013-03-18 13:52:27 +00:00
2010-09-11 20:14:36 +00:00
// Properties
public int Alpha { get { return alpha ; } }
public SectorLevel Floor { get { return floor ; } }
public SectorLevel Ceiling { get { return ceiling ; } }
public Linedef Linedef { get { return linedef ; } }
2010-09-15 18:17:38 +00:00
public bool VavoomType { get { return vavoomtype ; } }
2015-02-07 17:52:39 +00:00
public bool RenderInside { get { return renderinside ; } } //mxd
2015-11-20 14:31:54 +00:00
public bool RenderAdditive { get { return renderadditive ; } } //mxd
2015-02-07 17:52:39 +00:00
public bool IgnoreBottomHeight { get { return ignorebottomheight ; } } //mxd
2015-05-31 21:11:21 +00:00
public bool Sloped3dFloor { get { return sloped3dfloor ; } } //mxd
2015-11-20 14:31:54 +00:00
public bool ClipSidedefs { get { return clipsides ; } } //mxd
2013-03-18 13:52:27 +00:00
//mxd. 3D-Floor Flags
[Flags]
2015-02-25 19:59:17 +00:00
public enum Flags
2013-03-18 13:52:27 +00:00
{
None = 0 ,
DisableLighting = 1 ,
RestrictLighting = 2 ,
Fog = 4 ,
IgnoreBottomHeight = 8 ,
UseUpperTexture = 16 ,
UseLowerTexture = 32 ,
2016-03-25 14:06:00 +00:00
RenderAdditive = 64 ,
Fade = 512 ,
ResetLighting = 1024 ,
2013-03-18 13:52:27 +00:00
}
//mxd. 3D-Floor Types
[Flags]
2015-02-25 19:59:17 +00:00
public enum FloorTypes
2013-03-18 13:52:27 +00:00
{
VavoomStyle = 0 ,
Solid = 1 ,
Swimmable = 2 ,
NonSolid = 3 ,
RenderInside = 4 ,
2013-05-20 10:43:34 +00:00
HiTagIsLineID = 8 ,
2013-03-18 13:52:27 +00:00
InvertVisibilityRules = 16 ,
InvertShootabilityRules = 32
}
2010-09-15 18:17:38 +00:00
2010-09-11 20:14:36 +00:00
// Constructor
public Effect3DFloor ( SectorData data , Linedef sourcelinedef ) : base ( data )
{
linedef = sourcelinedef ;
2010-09-13 06:07:11 +00:00
// New effect added: This sector needs an update!
if ( data . Mode . VisualSectorExists ( data . Sector ) )
{
BaseVisualSector vs = ( BaseVisualSector ) data . Mode . GetVisualSector ( data . Sector ) ;
vs . UpdateSectorGeometry ( true ) ;
}
2010-09-11 20:14:36 +00:00
}
// This makes sure we are updated with the source linedef information
public override void Update ( )
{
SectorData sd = data . Mode . GetSectorData ( linedef . Front . Sector ) ;
if ( ! sd . Updated ) sd . Update ( ) ;
sd . AddUpdateSector ( data . Sector , true ) ;
if ( floor = = null )
{
floor = new SectorLevel ( sd . Floor ) ;
data . AddSectorLevel ( floor ) ;
}
if ( ceiling = = null )
{
ceiling = new SectorLevel ( sd . Ceiling ) ;
data . AddSectorLevel ( ceiling ) ;
}
// For non-vavoom types, we must switch the level types
2015-02-07 17:52:39 +00:00
if ( linedef . Args [ 1 ] ! = ( int ) FloorTypes . VavoomStyle )
2010-09-11 20:14:36 +00:00
{
2015-11-20 14:31:54 +00:00
//mxd. check for Swimmable/RenderInside/RenderAdditive flags
renderadditive = ( linedef . Args [ 2 ] & ( int ) Flags . RenderAdditive ) = = ( int ) Flags . RenderAdditive ;
renderinside = ( ( ( ( linedef . Args [ 1 ] & ( int ) FloorTypes . Swimmable ) = = ( int ) FloorTypes . Swimmable ) & & ( linedef . Args [ 1 ] & ( int ) FloorTypes . NonSolid ) ! = ( int ) FloorTypes . NonSolid ) )
| | ( ( linedef . Args [ 1 ] & ( int ) FloorTypes . RenderInside ) = = ( int ) FloorTypes . RenderInside ) ;
ignorebottomheight = ( ( linedef . Args [ 2 ] & ( int ) Flags . IgnoreBottomHeight ) = = ( int ) Flags . IgnoreBottomHeight ) ;
2010-09-15 18:17:38 +00:00
vavoomtype = false ;
2015-11-20 14:31:54 +00:00
alpha = General . Clamp ( linedef . Args [ 3 ] , 0 , 255 ) ;
2010-09-11 20:14:36 +00:00
sd . Ceiling . CopyProperties ( floor ) ;
sd . Floor . CopyProperties ( ceiling ) ;
floor . type = SectorLevelType . Floor ;
2010-09-16 19:38:46 +00:00
floor . plane = sd . Ceiling . plane . GetInverted ( ) ;
2010-09-11 20:14:36 +00:00
ceiling . type = SectorLevelType . Ceiling ;
2015-11-20 14:31:54 +00:00
ceiling . plane = ( ignorebottomheight ? sd . Ceiling . plane : sd . Floor . plane . GetInverted ( ) ) ; //mxd. Use upper plane when "ignorebottomheight" flag is set
2010-09-16 19:38:46 +00:00
2015-11-20 14:31:54 +00:00
//mxd
clipsides = ( ! renderinside & & ! renderadditive & & alpha > 254 & & ! ignorebottomheight ) ;
2013-03-18 13:52:27 +00:00
2010-09-16 19:38:46 +00:00
// A 3D floor's color is always that of the sector it is placed in
2015-11-20 14:31:54 +00:00
// (unless it's affected by glow) - mxd
if ( sd . CeilingGlow = = null | | ! sd . CeilingGlow . Fullbright ) floor . color = 0 ;
2010-09-11 20:14:36 +00:00
}
else
{
2010-09-15 18:17:38 +00:00
vavoomtype = true ;
2015-11-20 14:31:54 +00:00
renderadditive = false ; //mxd
clipsides = true ; //mxd
2010-09-16 19:38:46 +00:00
floor . type = SectorLevelType . Ceiling ;
floor . plane = sd . Ceiling . plane ;
ceiling . type = SectorLevelType . Floor ;
ceiling . plane = sd . Floor . plane ;
2010-09-11 20:14:36 +00:00
alpha = 255 ;
2010-09-16 19:38:46 +00:00
// A 3D floor's color is always that of the sector it is placed in
2015-11-20 14:31:54 +00:00
// (unless it's affected by glow) - mxd
if ( sd . FloorGlow = = null | | ! sd . FloorGlow . Fullbright ) ceiling . color = 0 ;
2010-09-11 20:14:36 +00:00
}
// Apply alpha
floor . alpha = alpha ;
ceiling . alpha = alpha ;
2015-05-31 21:11:21 +00:00
2015-11-20 14:31:54 +00:00
//mxd
floor . extrafloor = true ;
ceiling . extrafloor = true ;
floor . splitsides = ! clipsides ;
ceiling . splitsides = ( ! clipsides & & ! ignorebottomheight ) ; // if "ignorebottomheight" flag is set, both ceiling and floor will be at the same level and sidedef clipping with floor level will fail resulting in incorrect light props transfer in some cases
2015-05-31 21:11:21 +00:00
//mxd. Check slopes, cause GZDoom can't handle sloped translucent 3d floors...
2015-11-20 14:31:54 +00:00
sloped3dfloor = ( ( alpha < 255 | | renderadditive ) & &
2015-05-31 21:11:21 +00:00
( Angle2D . RadToDeg ( ceiling . plane . Normal . GetAngleZ ( ) ) ! = 270 | |
Angle2D . RadToDeg ( floor . plane . Normal . GetAngleZ ( ) ) ! = 90 ) ) ;
2010-09-11 20:14:36 +00:00
// Do not adjust light? (works only for non-vavoom types)
2015-02-25 19:59:17 +00:00
if ( ! vavoomtype )
2010-09-11 20:14:36 +00:00
{
2015-12-04 12:29:22 +00:00
bool disablelighting = ( ( linedef . Args [ 2 ] & ( int ) Flags . DisableLighting ) = = ( int ) Flags . DisableLighting ) ; //mxd
bool restrictlighting = ( ( linedef . Args [ 2 ] & ( int ) Flags . RestrictLighting ) = = ( int ) Flags . RestrictLighting ) ; //mxd
2016-03-25 14:06:00 +00:00
floor . resetlighting = ( ( linedef . Args [ 2 ] & ( int ) Flags . ResetLighting ) = = ( int ) Flags . ResetLighting ) ; //mxd
2015-02-25 19:59:17 +00:00
if ( disablelighting | | restrictlighting )
{
floor . restrictlighting = restrictlighting ; //mxd
floor . disablelighting = disablelighting ; //mxd
2015-11-20 14:31:54 +00:00
if ( disablelighting ) //mxd
{
floor . color = 0 ;
floor . brightnessbelow = - 1 ;
floor . colorbelow = PixelColor . FromInt ( 0 ) ;
}
ceiling . disablelighting = disablelighting ; //mxd
ceiling . restrictlighting = restrictlighting ; //mxd
2015-02-25 19:59:17 +00:00
ceiling . color = 0 ;
ceiling . brightnessbelow = - 1 ;
ceiling . colorbelow = PixelColor . FromInt ( 0 ) ;
}
2010-09-11 20:14:36 +00:00
}
2017-02-01 18:16:42 +00:00
if ( VavoomType )
{
2017-02-02 05:34:21 +00:00
ColorFloor = sd . ColorCeiling ;
ColorCeiling = sd . ColorFloor ;
2017-02-01 18:16:42 +00:00
}
else
{
2017-02-02 05:34:21 +00:00
ColorFloor = sd . ColorFloor ;
ColorCeiling = sd . ColorCeiling ;
2017-02-01 18:16:42 +00:00
}
2010-09-11 20:14:36 +00:00
}
}
}