2015-12-31 12:21:44 +00:00
#region = = = Copyright ( c ) 2010 Pascal van der Heiden = = =
using System ;
using CodeImp.DoomBuilder.Geometry ;
using CodeImp.DoomBuilder.Map ;
using CodeImp.DoomBuilder.Rendering ;
#endregion
namespace CodeImp.DoomBuilder.BuilderModes
{
internal class Effect3DFloor : SectorEffect
{
// Linedef that is used to create this effect
// The sector can be found by linedef.Front.Sector
private readonly Linedef linedef ;
// Floor and ceiling planes
private SectorLevel floor ;
private SectorLevel ceiling ;
// Alpha transparency
private int alpha ;
// Vavoom type?
private bool vavoomtype ;
//mxd. Render backsides?
private bool renderinside ;
//mxd. Dirty hack to emulate GZDoom behaviour?
private bool sloped3dfloor ;
//mxd. Render using Additive pass?
private bool renderadditive ;
//mxd. Sidedef should be clipped by floor/ceiling?
private bool clipsides ;
//mxd. Ignore Bottom Height?
private bool ignorebottomheight ;
// 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 ; } }
public bool VavoomType { get { return vavoomtype ; } }
public bool RenderInside { get { return renderinside ; } } //mxd
public bool RenderAdditive { get { return renderadditive ; } } //mxd
public bool IgnoreBottomHeight { get { return ignorebottomheight ; } } //mxd
public bool Sloped3dFloor { get { return sloped3dfloor ; } } //mxd
public bool ClipSidedefs { get { return clipsides ; } } //mxd
//mxd. 3D-Floor Flags
[Flags]
public enum Flags
{
None = 0 ,
DisableLighting = 1 ,
RestrictLighting = 2 ,
Fog = 4 ,
IgnoreBottomHeight = 8 ,
UseUpperTexture = 16 ,
UseLowerTexture = 32 ,
RenderAdditive = 64
}
//mxd. 3D-Floor Types
[Flags]
public enum FloorTypes
{
VavoomStyle = 0 ,
Solid = 1 ,
Swimmable = 2 ,
NonSolid = 3 ,
RenderInside = 4 ,
HiTagIsLineID = 8 ,
InvertVisibilityRules = 16 ,
InvertShootabilityRules = 32
}
// Constructor
public Effect3DFloor ( SectorData data , Linedef sourcelinedef ) : base ( data )
{
linedef = sourcelinedef ;
// 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 ) ;
}
}
// 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
if ( linedef . Args [ 1 ] ! = ( int ) FloorTypes . VavoomStyle )
{
//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 ) ;
vavoomtype = false ;
alpha = General . Clamp ( linedef . Args [ 3 ] , 0 , 255 ) ;
sd . Ceiling . CopyProperties ( floor ) ;
sd . Floor . CopyProperties ( ceiling ) ;
floor . type = SectorLevelType . Floor ;
floor . plane = sd . Ceiling . plane . GetInverted ( ) ;
ceiling . type = SectorLevelType . Ceiling ;
ceiling . plane = ( ignorebottomheight ? sd . Ceiling . plane : sd . Floor . plane . GetInverted ( ) ) ; //mxd. Use upper plane when "ignorebottomheight" flag is set
//mxd
clipsides = ( ! renderinside & & ! renderadditive & & alpha > 254 & & ! ignorebottomheight ) ;
// A 3D floor's color is always that of the sector it is placed in
// (unless it's affected by glow) - mxd
if ( sd . CeilingGlow = = null | | ! sd . CeilingGlow . Fullbright ) floor . color = 0 ;
}
else
{
vavoomtype = true ;
renderadditive = false ; //mxd
clipsides = true ; //mxd
floor . type = SectorLevelType . Ceiling ;
floor . plane = sd . Ceiling . plane ;
ceiling . type = SectorLevelType . Floor ;
ceiling . plane = sd . Floor . plane ;
alpha = 255 ;
// A 3D floor's color is always that of the sector it is placed in
// (unless it's affected by glow) - mxd
if ( sd . FloorGlow = = null | | ! sd . FloorGlow . Fullbright ) ceiling . color = 0 ;
}
// Apply alpha
floor . alpha = alpha ;
ceiling . alpha = alpha ;
//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
//mxd. Check slopes, cause GZDoom can't handle sloped translucent 3d floors...
2015-12-31 15:46:40 +00:00
//MascaraSnake: SRB2 can, so only check in Doom
sloped3dfloor = ( ! General . Map . FormatInterface . HasTranslucent3DFloors & & ( alpha < 255 | | renderadditive ) & &
2015-12-31 12:21:44 +00:00
( Angle2D . RadToDeg ( ceiling . plane . Normal . GetAngleZ ( ) ) ! = 270 | |
Angle2D . RadToDeg ( floor . plane . Normal . GetAngleZ ( ) ) ! = 90 ) ) ;
// Do not adjust light? (works only for non-vavoom types)
if ( ! vavoomtype )
{
bool disablelighting = ( ( linedef . Args [ 2 ] & ( int ) Flags . DisableLighting ) = = ( int ) Flags . DisableLighting ) ; //mxd
bool restrictlighting = ( ( linedef . Args [ 2 ] & ( int ) Flags . RestrictLighting ) = = ( int ) Flags . RestrictLighting ) ; //mxd
if ( disablelighting | | restrictlighting )
{
floor . restrictlighting = restrictlighting ; //mxd
floor . disablelighting = disablelighting ; //mxd
if ( disablelighting ) //mxd
{
floor . color = 0 ;
floor . brightnessbelow = - 1 ;
floor . colorbelow = PixelColor . FromInt ( 0 ) ;
}
ceiling . disablelighting = disablelighting ; //mxd
ceiling . restrictlighting = restrictlighting ; //mxd
ceiling . color = 0 ;
ceiling . brightnessbelow = - 1 ;
ceiling . colorbelow = PixelColor . FromInt ( 0 ) ;
}
}
}
}
}