2009-04-19 18:07:22 +00:00
#region = = = = = = = = = = = = = = = = = = Copyright ( c ) 2007 Pascal vd Heiden
/ *
* Copyright ( c ) 2007 Pascal vd Heiden , www . codeimp . com
* This program is released under GNU General Public License
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* /
#endregion
#region = = = = = = = = = = = = = = = = = = Namespaces
using System ;
using System.Collections.Generic ;
using CodeImp.DoomBuilder.IO ;
using CodeImp.DoomBuilder.Geometry ;
using System.Drawing ;
using CodeImp.DoomBuilder.Rendering ;
using System.Collections.ObjectModel ;
2013-09-11 08:49:45 +00:00
using SlimDX ;
2009-04-19 18:07:22 +00:00
#endregion
namespace CodeImp.DoomBuilder.Map
{
Fixed, Visual mode: in some cases ceiling glow effect was interfering with Transfer Brightness effect resulting in incorrectly lit sidedef geometry.
Fixed, Visual mode: UDMF sidedef brightness should be ignored when a wall section is affected by Transfer Brightness effect.
Fixed, Visual mode: any custom fog should be rendered regardless of sector brightness.
Fixed, Visual mode: "fogdensity" and "outsidefogdensity" MAPINFO values were processed incorrectly.
Fixed, Visual mode: in some cases Things were rendered twice during a render pass.
Fixed, Visual mode: floor glow effect should affect thing brightness only when applied to floor of the sector thing is in.
Fixed, TEXTURES parser: TEXTURES group was named incorrectly in the Textures Browser window when parsed from a WAD file.
Fixed, MAPINFO, GLDEFS, DECORATE parsers: "//$GZDB_SKIP" special comment was processed incorrectly.
Fixed, MAPINFO parser: "fogdensity" and "outsidefogdensity" properties are now initialized using GZDoom default value (255) instead of 0.
2016-01-25 13:42:53 +00:00
public enum SectorFogMode //mxd
{
NONE , // no fog
CLASSIC , // black fog when sector brightness < 243
FOGDENSITY , // sector uses "fogdensity" MAPINFO property
OUTSIDEFOGDENSITY , // sector uses "outsidefogdensity" MAPINFO property
FADE // sector uses UDMF "fade" sector property
}
2016-04-09 23:18:39 +00:00
public sealed class Sector : SelectableElement , IMultiTaggedMapElement
2009-04-19 18:07:22 +00:00
{
#region = = = = = = = = = = = = = = = = = = Constants
2015-01-11 19:42:57 +00:00
internal const int SLOPE_DECIMALS = 7 ;
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Variables
// Map
private MapSet map ;
// List items
private LinkedListNode < Sector > selecteditem ;
// Sidedefs
private LinkedList < Sidedef > sidedefs ;
// Properties
private int fixedindex ;
private int floorheight ;
private int ceilheight ;
private string floortexname ;
private string ceiltexname ;
private long longfloortexname ;
private long longceiltexname ;
private int effect ;
2015-07-27 21:35:42 +00:00
private List < int > tags ; //mxd
2009-04-19 18:07:22 +00:00
private int brightness ;
2013-07-10 08:59:17 +00:00
//mxd. UDMF properties
private Dictionary < string , bool > flags ;
2009-04-19 18:07:22 +00:00
// Cloning
private Sector clone ;
private int serializedindex ;
// Triangulation
private bool updateneeded ;
private bool triangulationneeded ;
private RectangleF bbox ;
private Triangulation triangles ;
private FlatVertex [ ] flatvertices ;
private ReadOnlyCollection < LabelPositionInfo > labels ;
2014-08-25 11:15:19 +00:00
private readonly SurfaceEntryCollection surfaceentries ;
2013-09-11 08:49:45 +00:00
//mxd. Rendering
Fixed, Visual mode: in some cases ceiling glow effect was interfering with Transfer Brightness effect resulting in incorrectly lit sidedef geometry.
Fixed, Visual mode: UDMF sidedef brightness should be ignored when a wall section is affected by Transfer Brightness effect.
Fixed, Visual mode: any custom fog should be rendered regardless of sector brightness.
Fixed, Visual mode: "fogdensity" and "outsidefogdensity" MAPINFO values were processed incorrectly.
Fixed, Visual mode: in some cases Things were rendered twice during a render pass.
Fixed, Visual mode: floor glow effect should affect thing brightness only when applied to floor of the sector thing is in.
Fixed, TEXTURES parser: TEXTURES group was named incorrectly in the Textures Browser window when parsed from a WAD file.
Fixed, MAPINFO, GLDEFS, DECORATE parsers: "//$GZDB_SKIP" special comment was processed incorrectly.
Fixed, MAPINFO parser: "fogdensity" and "outsidefogdensity" properties are now initialized using GZDoom default value (255) instead of 0.
2016-01-25 13:42:53 +00:00
private Color4 fogcolor ;
private SectorFogMode fogmode ;
2014-08-25 11:15:19 +00:00
//mxd. Slopes
private Vector3D floorslope ;
private float flooroffset ;
private Vector3D ceilslope ;
private float ceiloffset ;
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Properties
public MapSet Map { get { return map ; } }
public ICollection < Sidedef > Sidedefs { get { return sidedefs ; } }
/// <summary>
/// An unique index that does not change when other sectors are removed.
/// </summary>
public int FixedIndex { get { return fixedindex ; } }
2009-06-11 21:21:20 +00:00
public int FloorHeight { get { return floorheight ; } set { BeforePropsChange ( ) ; floorheight = value ; } }
public int CeilHeight { get { return ceilheight ; } set { BeforePropsChange ( ) ; ceilheight = value ; } }
2009-04-19 18:07:22 +00:00
public string FloorTexture { get { return floortexname ; } }
public string CeilTexture { get { return ceiltexname ; } }
public long LongFloorTexture { get { return longfloortexname ; } }
public long LongCeilTexture { get { return longceiltexname ; } }
2013-07-10 08:59:17 +00:00
internal Dictionary < string , bool > Flags { get { return flags ; } } //mxd
2009-06-11 21:21:20 +00:00
public int Effect { get { return effect ; } set { BeforePropsChange ( ) ; effect = value ; } }
2015-07-27 21:35:42 +00:00
public int Tag { get { return tags [ 0 ] ; } set { BeforePropsChange ( ) ; tags [ 0 ] = value ; if ( ( value < General . Map . FormatInterface . MinTag ) | | ( value > General . Map . FormatInterface . MaxTag ) ) throw new ArgumentOutOfRangeException ( "Tag" , "Invalid tag number" ) ; } } //mxd
2015-07-28 15:04:21 +00:00
public List < int > Tags { get { return tags ; } set { BeforePropsChange ( ) ; tags = value ; } } //mxd
2009-06-11 21:21:20 +00:00
public int Brightness { get { return brightness ; } set { BeforePropsChange ( ) ; brightness = value ; updateneeded = true ; } }
2009-04-19 18:07:22 +00:00
public bool UpdateNeeded { get { return updateneeded ; } set { updateneeded | = value ; triangulationneeded | = value ; } }
public RectangleF BBox { get { return bbox ; } }
internal Sector Clone { get { return clone ; } set { clone = value ; } }
internal int SerializedIndex { get { return serializedindex ; } set { serializedindex = value ; } }
public Triangulation Triangles { get { return triangles ; } }
public FlatVertex [ ] FlatVertices { get { return flatvertices ; } }
public ReadOnlyCollection < LabelPositionInfo > Labels { get { return labels ; } }
2013-09-11 08:49:45 +00:00
//mxd. Rednering
Fixed, Visual mode: in some cases ceiling glow effect was interfering with Transfer Brightness effect resulting in incorrectly lit sidedef geometry.
Fixed, Visual mode: UDMF sidedef brightness should be ignored when a wall section is affected by Transfer Brightness effect.
Fixed, Visual mode: any custom fog should be rendered regardless of sector brightness.
Fixed, Visual mode: "fogdensity" and "outsidefogdensity" MAPINFO values were processed incorrectly.
Fixed, Visual mode: in some cases Things were rendered twice during a render pass.
Fixed, Visual mode: floor glow effect should affect thing brightness only when applied to floor of the sector thing is in.
Fixed, TEXTURES parser: TEXTURES group was named incorrectly in the Textures Browser window when parsed from a WAD file.
Fixed, MAPINFO, GLDEFS, DECORATE parsers: "//$GZDB_SKIP" special comment was processed incorrectly.
Fixed, MAPINFO parser: "fogdensity" and "outsidefogdensity" properties are now initialized using GZDoom default value (255) instead of 0.
2016-01-25 13:42:53 +00:00
public Color4 FogColor { get { return fogcolor ; } }
public SectorFogMode FogMode { get { return fogmode ; } }
2013-09-11 08:49:45 +00:00
2014-08-25 11:15:19 +00:00
//mxd. Slopes
public Vector3D FloorSlope { get { return floorslope ; } set { BeforePropsChange ( ) ; floorslope = value ; updateneeded = true ; } }
public float FloorSlopeOffset { get { return flooroffset ; } set { BeforePropsChange ( ) ; flooroffset = value ; updateneeded = true ; } }
2014-10-17 11:55:08 +00:00
public Vector3D CeilSlope { get { return ceilslope ; } set { BeforePropsChange ( ) ; ceilslope = value ; updateneeded = true ; } }
public float CeilSlopeOffset { get { return ceiloffset ; } set { BeforePropsChange ( ) ; ceiloffset = value ; updateneeded = true ; } }
2014-08-25 11:15:19 +00:00
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Constructor / Disposer
// Constructor
2009-06-05 19:03:56 +00:00
internal Sector ( MapSet map , int listindex , int index )
2009-04-19 18:07:22 +00:00
{
// Initialize
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
this . elementtype = MapElementType . SECTOR ; //mxd
2009-04-19 18:07:22 +00:00
this . map = map ;
2009-06-05 19:03:56 +00:00
this . listindex = listindex ;
2009-04-19 18:07:22 +00:00
this . sidedefs = new LinkedList < Sidedef > ( ) ;
this . fixedindex = index ;
this . floortexname = "-" ;
this . ceiltexname = "-" ;
this . longfloortexname = MapSet . EmptyLongName ;
this . longceiltexname = MapSet . EmptyLongName ;
2014-02-26 14:11:06 +00:00
this . flags = new Dictionary < string , bool > ( StringComparer . Ordinal ) ; //mxd
2015-07-27 21:35:42 +00:00
this . tags = new List < int > { 0 } ; //mxd
2009-06-16 08:49:14 +00:00
this . updateneeded = true ;
2009-04-19 18:07:22 +00:00
this . triangulationneeded = true ;
2015-09-25 13:20:53 +00:00
this . triangles = new Triangulation ( ) ; //mxd
2010-08-26 21:47:25 +00:00
this . surfaceentries = new SurfaceEntryCollection ( ) ;
2009-04-19 18:07:22 +00:00
2009-06-11 21:21:20 +00:00
if ( map = = General . Map . Map )
General . Map . UndoRedo . RecAddSector ( this ) ;
2009-04-19 18:07:22 +00:00
// We have no destructor
GC . SuppressFinalize ( this ) ;
}
// Disposer
public override void Dispose ( )
{
// Not already disposed?
if ( ! isdisposed )
{
// Already set isdisposed so that changes can be prohibited
isdisposed = true ;
2009-06-11 21:21:20 +00:00
2009-06-15 17:38:02 +00:00
// Dispose the sidedefs that are attached to this sector
// because a sidedef cannot exist without reference to its sector.
if ( map . AutoRemove )
foreach ( Sidedef sd in sidedefs ) sd . Dispose ( ) ;
else
foreach ( Sidedef sd in sidedefs ) sd . SetSectorP ( null ) ;
2009-06-11 21:21:20 +00:00
if ( map = = General . Map . Map )
General . Map . UndoRedo . RecRemSector ( this ) ;
2009-04-19 18:07:22 +00:00
// Remove from main list
2009-06-05 19:03:56 +00:00
map . RemoveSector ( listindex ) ;
2009-06-11 21:21:20 +00:00
2009-04-19 18:07:22 +00:00
// Register the index as free
map . AddSectorIndexHole ( fixedindex ) ;
2009-06-04 20:21:31 +00:00
// Free surface entry
2010-08-26 21:47:25 +00:00
General . Map . CRenderer2D . Surfaces . FreeSurfaces ( surfaceentries ) ;
2009-06-11 21:21:20 +00:00
2009-04-19 18:07:22 +00:00
// Clean up
sidedefs = null ;
map = null ;
2015-09-16 20:22:20 +00:00
//mxd. Restore isdisposed so base classes can do their disposal job
isdisposed = false ;
2009-06-11 21:21:20 +00:00
2009-04-19 18:07:22 +00:00
// Dispose base
base . Dispose ( ) ;
}
}
#endregion
#region = = = = = = = = = = = = = = = = = = Management
2009-06-11 21:21:20 +00:00
// Call this before changing properties
protected override void BeforePropsChange ( )
{
if ( map = = General . Map . Map )
General . Map . UndoRedo . RecPrpSector ( this ) ;
}
// Serialize / deserialize (passive: this doesn't record)
2013-03-18 13:52:27 +00:00
new internal void ReadWrite ( IReadWriteStream s )
2009-04-19 18:07:22 +00:00
{
2009-06-15 17:38:02 +00:00
if ( ! s . IsWriting )
{
BeforePropsChange ( ) ;
updateneeded = true ;
}
2009-04-19 18:07:22 +00:00
2009-06-11 21:21:20 +00:00
base . ReadWrite ( s ) ;
2013-07-10 08:59:17 +00:00
//mxd
2014-12-03 09:06:05 +00:00
if ( s . IsWriting )
{
2013-07-10 08:59:17 +00:00
s . wInt ( flags . Count ) ;
2014-12-03 09:06:05 +00:00
foreach ( KeyValuePair < string , bool > f in flags )
{
2013-07-10 08:59:17 +00:00
s . wString ( f . Key ) ;
s . wBool ( f . Value ) ;
}
2014-12-03 09:06:05 +00:00
}
else
{
2013-07-10 08:59:17 +00:00
int c ; s . rInt ( out c ) ;
2014-02-26 14:11:06 +00:00
flags = new Dictionary < string , bool > ( c , StringComparer . Ordinal ) ;
2014-12-03 09:06:05 +00:00
for ( int i = 0 ; i < c ; i + + )
{
2013-07-10 08:59:17 +00:00
string t ; s . rString ( out t ) ;
bool b ; s . rBool ( out b ) ;
flags . Add ( t , b ) ;
}
}
2009-04-19 18:07:22 +00:00
s . rwInt ( ref fixedindex ) ;
s . rwInt ( ref floorheight ) ;
s . rwInt ( ref ceilheight ) ;
s . rwString ( ref floortexname ) ;
s . rwString ( ref ceiltexname ) ;
2009-06-11 21:21:20 +00:00
s . rwLong ( ref longfloortexname ) ;
s . rwLong ( ref longceiltexname ) ;
2009-04-19 18:07:22 +00:00
s . rwInt ( ref effect ) ;
s . rwInt ( ref brightness ) ;
2014-08-25 11:15:19 +00:00
2015-07-27 21:35:42 +00:00
//mxd. (Re)store tags
if ( s . IsWriting )
{
s . wInt ( tags . Count ) ;
foreach ( int tag in tags ) s . wInt ( tag ) ;
}
else
{
int c ;
s . rInt ( out c ) ;
tags = new List < int > ( c ) ;
for ( int i = 0 ; i < c ; i + + )
{
int t ;
s . rInt ( out t ) ;
tags . Add ( t ) ;
}
}
2014-08-25 11:15:19 +00:00
//mxd. Slopes
s . rwFloat ( ref flooroffset ) ;
s . rwVector3D ( ref floorslope ) ;
s . rwFloat ( ref ceiloffset ) ;
s . rwVector3D ( ref ceilslope ) ;
2009-04-19 18:07:22 +00:00
}
// After deserialization
internal void PostDeserialize ( MapSet map )
{
triangles . PostDeserialize ( map ) ;
updateneeded = true ;
2009-06-16 08:49:14 +00:00
triangulationneeded = true ;
2009-04-19 18:07:22 +00:00
}
// This copies all properties to another sector
public void CopyPropertiesTo ( Sector s )
{
2009-06-11 21:21:20 +00:00
s . BeforePropsChange ( ) ;
2009-04-19 18:07:22 +00:00
// Copy properties
s . ceilheight = ceilheight ;
s . ceiltexname = ceiltexname ;
s . longceiltexname = longceiltexname ;
s . floorheight = floorheight ;
s . floortexname = floortexname ;
s . longfloortexname = longfloortexname ;
s . effect = effect ;
2015-07-27 21:35:42 +00:00
s . tags = new List < int > ( tags ) ; //mxd
2013-07-10 08:59:17 +00:00
s . flags = new Dictionary < string , bool > ( flags ) ; //mxd
2009-04-19 18:07:22 +00:00
s . brightness = brightness ;
2014-08-25 11:15:19 +00:00
s . flooroffset = flooroffset ; //mxd
s . floorslope = floorslope ; //mxd
s . ceiloffset = ceiloffset ; //mxd
s . ceilslope = ceilslope ; //mxd
2009-04-19 18:07:22 +00:00
s . updateneeded = true ;
base . CopyPropertiesTo ( s ) ;
}
// This attaches a sidedef and returns the listitem
2009-06-11 21:21:20 +00:00
internal LinkedListNode < Sidedef > AttachSidedefP ( Sidedef sd )
2009-04-19 18:07:22 +00:00
{
updateneeded = true ;
triangulationneeded = true ;
return sidedefs . AddLast ( sd ) ;
}
// This detaches a sidedef
2009-06-11 21:21:20 +00:00
internal void DetachSidedefP ( LinkedListNode < Sidedef > l )
2009-04-19 18:07:22 +00:00
{
// Not disposing?
if ( ! isdisposed )
{
// Remove sidedef
updateneeded = true ;
triangulationneeded = true ;
sidedefs . Remove ( l ) ;
// No more sidedefs left?
2009-06-07 10:26:06 +00:00
if ( ( sidedefs . Count = = 0 ) & & map . AutoRemove )
2009-04-19 18:07:22 +00:00
{
// This sector is now useless, dispose it
this . Dispose ( ) ;
}
}
}
2009-06-04 20:21:31 +00:00
// This triangulates the sector geometry
internal void Triangulate ( )
2009-04-19 18:07:22 +00:00
{
if ( updateneeded )
{
// Triangulate again?
if ( triangulationneeded | | ( triangles = = null ) )
{
// Triangulate sector
triangles = Triangulation . Create ( this ) ;
triangulationneeded = false ;
2009-06-04 20:21:31 +00:00
updateneeded = true ;
2009-04-19 18:07:22 +00:00
// Make label positions
2015-12-27 21:54:50 +00:00
labels = Array . AsReadOnly ( Tools . FindLabelPositions ( this ) . ToArray ( ) ) ;
2009-06-04 20:21:31 +00:00
// Number of vertices changed?
2010-08-26 21:47:25 +00:00
if ( triangles . Vertices . Count ! = surfaceentries . totalvertices )
General . Map . CRenderer2D . Surfaces . FreeSurfaces ( surfaceentries ) ;
2009-04-19 18:07:22 +00:00
}
2009-06-04 20:21:31 +00:00
}
}
// This makes new vertices as well as floor and ceiling surfaces
internal void CreateSurfaces ( )
{
if ( updateneeded )
{
2009-07-12 09:58:05 +00:00
// Brightness color
int brightint = General . Map . Renderer2D . CalculateBrightness ( brightness ) ;
2009-04-19 18:07:22 +00:00
// Make vertices
flatvertices = new FlatVertex [ triangles . Vertices . Count ] ;
for ( int i = 0 ; i < triangles . Vertices . Count ; i + + )
{
flatvertices [ i ] . x = triangles . Vertices [ i ] . x ;
flatvertices [ i ] . y = triangles . Vertices [ i ] . y ;
flatvertices [ i ] . z = 1.0f ;
flatvertices [ i ] . c = brightint ;
flatvertices [ i ] . u = triangles . Vertices [ i ] . x ;
flatvertices [ i ] . v = triangles . Vertices [ i ] . y ;
}
// Create bounding box
bbox = CreateBBox ( ) ;
2010-08-26 21:47:25 +00:00
// Make update info (this lets the plugin fill in texture coordinates and such)
SurfaceUpdate updateinfo = new SurfaceUpdate ( flatvertices . Length , true , true ) ;
flatvertices . CopyTo ( updateinfo . floorvertices , 0 ) ;
General . Plugins . OnSectorFloorSurfaceUpdate ( this , ref updateinfo . floorvertices ) ;
flatvertices . CopyTo ( updateinfo . ceilvertices , 0 ) ;
General . Plugins . OnSectorCeilingSurfaceUpdate ( this , ref updateinfo . ceilvertices ) ;
updateinfo . floortexture = longfloortexname ;
updateinfo . ceiltexture = longceiltexname ;
// Update surfaces
General . Map . CRenderer2D . Surfaces . UpdateSurfaces ( surfaceentries , updateinfo ) ;
2009-06-04 20:21:31 +00:00
2009-04-19 18:07:22 +00:00
// Updated
updateneeded = false ;
}
}
2009-06-04 20:21:31 +00:00
// This updates the floor surface
2009-04-19 18:07:22 +00:00
public void UpdateFloorSurface ( )
{
2009-06-11 21:21:20 +00:00
if ( flatvertices = = null ) return ;
2009-06-04 20:21:31 +00:00
// Create floor vertices
2010-08-26 21:47:25 +00:00
SurfaceUpdate updateinfo = new SurfaceUpdate ( flatvertices . Length , true , false ) ;
flatvertices . CopyTo ( updateinfo . floorvertices , 0 ) ;
General . Plugins . OnSectorFloorSurfaceUpdate ( this , ref updateinfo . floorvertices ) ;
updateinfo . floortexture = longfloortexname ;
2009-06-04 20:21:31 +00:00
// Update entry
2010-08-26 21:47:25 +00:00
General . Map . CRenderer2D . Surfaces . UpdateSurfaces ( surfaceentries , updateinfo ) ;
2009-06-04 20:21:31 +00:00
General . Map . CRenderer2D . Surfaces . UnlockBuffers ( ) ;
2009-04-19 18:07:22 +00:00
}
2009-06-04 20:21:31 +00:00
// This updates the ceiling surface
2009-04-19 18:07:22 +00:00
public void UpdateCeilingSurface ( )
{
2009-06-11 21:21:20 +00:00
if ( flatvertices = = null ) return ;
2009-06-04 20:21:31 +00:00
// Create ceiling vertices
2010-08-26 21:47:25 +00:00
SurfaceUpdate updateinfo = new SurfaceUpdate ( flatvertices . Length , false , true ) ;
flatvertices . CopyTo ( updateinfo . ceilvertices , 0 ) ;
General . Plugins . OnSectorCeilingSurfaceUpdate ( this , ref updateinfo . ceilvertices ) ;
updateinfo . ceiltexture = longceiltexname ;
2009-06-16 17:29:00 +00:00
2009-06-04 20:21:31 +00:00
// Update entry
2010-08-26 21:47:25 +00:00
General . Map . CRenderer2D . Surfaces . UpdateSurfaces ( surfaceentries , updateinfo ) ;
2009-06-04 20:21:31 +00:00
General . Map . CRenderer2D . Surfaces . UnlockBuffers ( ) ;
2009-04-19 18:07:22 +00:00
}
2009-06-04 20:21:31 +00:00
// This updates the sector when changes have been made
public void UpdateCache ( )
2009-04-19 18:07:22 +00:00
{
2009-06-04 20:21:31 +00:00
// Update if needed
if ( updateneeded )
2009-04-19 18:07:22 +00:00
{
2009-06-04 20:21:31 +00:00
Triangulate ( ) ;
CreateSurfaces ( ) ;
2010-08-01 16:02:00 +00:00
General . Map . CRenderer2D . Surfaces . UnlockBuffers ( ) ;
2009-04-19 18:07:22 +00:00
}
}
// Selected
protected override void DoSelect ( )
{
base . DoSelect ( ) ;
selecteditem = map . SelectedSectors . AddLast ( this ) ;
}
// Deselect
protected override void DoUnselect ( )
{
base . DoUnselect ( ) ;
if ( selecteditem . List ! = null ) selecteditem . List . Remove ( selecteditem ) ;
selecteditem = null ;
}
2014-09-16 20:26:42 +00:00
2014-10-03 21:55:38 +00:00
// This removes UDMF stuff (mxd)
2014-09-16 20:26:42 +00:00
internal void TranslateFromUDMF ( )
{
2014-10-03 21:55:38 +00:00
// Clear UDMF-related properties (but keep VirtualSectorField!)
bool isvirtual = this . Fields . ContainsKey ( MapSet . VirtualSectorField ) ;
2014-09-16 20:26:42 +00:00
this . Fields . Clear ( ) ;
2014-10-03 21:55:38 +00:00
if ( isvirtual ) this . Fields . Add ( MapSet . VirtualSectorField , MapSet . VirtualSectorValue ) ;
2014-09-16 20:26:42 +00:00
this . Flags . Clear ( ) ;
Fixed, Visual mode: in some cases ceiling glow effect was interfering with Transfer Brightness effect resulting in incorrectly lit sidedef geometry.
Fixed, Visual mode: UDMF sidedef brightness should be ignored when a wall section is affected by Transfer Brightness effect.
Fixed, Visual mode: any custom fog should be rendered regardless of sector brightness.
Fixed, Visual mode: "fogdensity" and "outsidefogdensity" MAPINFO values were processed incorrectly.
Fixed, Visual mode: in some cases Things were rendered twice during a render pass.
Fixed, Visual mode: floor glow effect should affect thing brightness only when applied to floor of the sector thing is in.
Fixed, TEXTURES parser: TEXTURES group was named incorrectly in the Textures Browser window when parsed from a WAD file.
Fixed, MAPINFO, GLDEFS, DECORATE parsers: "//$GZDB_SKIP" special comment was processed incorrectly.
Fixed, MAPINFO parser: "fogdensity" and "outsidefogdensity" properties are now initialized using GZDoom default value (255) instead of 0.
2016-01-25 13:42:53 +00:00
this . fogmode = SectorFogMode . NONE ;
2014-09-16 20:26:42 +00:00
// Reset Slopes
floorslope = new Vector3D ( ) ;
flooroffset = 0 ;
ceilslope = new Vector3D ( ) ;
ceiloffset = 0 ;
}
2009-04-19 18:07:22 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Methods
2013-07-10 08:59:17 +00:00
// This checks and returns a flag without creating it
2014-12-03 09:06:05 +00:00
public bool IsFlagSet ( string flagname )
{
return flags . ContainsKey ( flagname ) & & flags [ flagname ] ;
2013-07-10 08:59:17 +00:00
}
// This sets a flag
2014-12-03 09:06:05 +00:00
public void SetFlag ( string flagname , bool value )
{
if ( ! flags . ContainsKey ( flagname ) | | ( IsFlagSet ( flagname ) ! = value ) )
{
2013-07-10 08:59:17 +00:00
BeforePropsChange ( ) ;
flags [ flagname ] = value ;
}
}
// This returns a copy of the flags dictionary
2014-12-03 09:06:05 +00:00
public Dictionary < string , bool > GetFlags ( )
{
2013-07-10 08:59:17 +00:00
return new Dictionary < string , bool > ( flags ) ;
}
2016-06-15 22:57:39 +00:00
//mxd. This returns enabled flags
public HashSet < string > GetEnabledFlags ( )
{
HashSet < string > result = new HashSet < string > ( ) ;
foreach ( KeyValuePair < string , bool > group in flags )
if ( group . Value ) result . Add ( group . Key ) ;
return result ;
}
2013-07-10 08:59:17 +00:00
// This clears all flags
2014-12-03 09:06:05 +00:00
public void ClearFlags ( )
{
2013-07-10 08:59:17 +00:00
BeforePropsChange ( ) ;
flags . Clear ( ) ;
}
2009-04-19 18:07:22 +00:00
// This checks if the given point is inside the sector polygon
2016-05-29 00:38:55 +00:00
// See: http://paulbourke.net/geometry/polygonmesh/index.html#insidepoly
2016-09-18 23:46:24 +00:00
public bool Intersect ( Vector2D p ) { return Intersect ( p , true ) ; }
public bool Intersect ( Vector2D p , bool countontopastrue )
2009-04-19 18:07:22 +00:00
{
2015-11-11 22:22:21 +00:00
//mxd. Check bounding box first
if ( p . x < bbox . Left | | p . x > bbox . Right | | p . y < bbox . Top | | p . y > bbox . Bottom ) return false ;
2014-08-25 11:15:19 +00:00
2009-04-19 18:07:22 +00:00
uint c = 0 ;
2016-05-29 00:38:55 +00:00
Vector2D v1 , v2 ;
2009-04-19 18:07:22 +00:00
// Go for all sidedefs
foreach ( Sidedef sd in sidedefs )
{
// Get vertices
2016-05-29 00:38:55 +00:00
v1 = sd . Line . Start . Position ;
v2 = sd . Line . End . Position ;
2014-08-25 11:15:19 +00:00
//mxd. On top of a vertex?
2016-09-18 23:46:24 +00:00
if ( p = = v1 | | p = = v2 ) return countontopastrue ;
2016-05-29 00:38:55 +00:00
2009-04-19 18:07:22 +00:00
// Check for intersection
2016-05-29 00:38:55 +00:00
if ( v1 . y ! = v2 . y //mxd. If line is not horizontal...
& & p . y > ( v1 . y < v2 . y ? v1 . y : v2 . y ) //mxd. ...And test point y intersects with the line y bounds...
& & p . y < = ( v1 . y > v2 . y ? v1 . y : v2 . y ) //mxd
& & ( p . x < ( v1 . x < v2 . x ? v1 . x : v2 . x ) | | ( p . x < = ( v1 . x > v2 . x ? v1 . x : v2 . x ) //mxd. ...And test point x is to the left of the line, or is inside line x bounds and intersects it
& & ( v1 . x = = v2 . x | | p . x < = ( ( p . y - v1 . y ) * ( v2 . x - v1 . x ) / ( v2 . y - v1 . y ) + v1 . x ) ) ) ) )
c + + ; //mxd. ...Count the line as crossed
2009-04-19 18:07:22 +00:00
}
2016-05-29 00:38:55 +00:00
// Inside this polygon when we crossed odd number of polygon lines
return ( c % 2 ! = 0 ) ;
2009-04-19 18:07:22 +00:00
}
// This creates a bounding box rectangle
// This requires the sector triangulation to be up-to-date!
private RectangleF CreateBBox ( )
{
2016-05-18 20:31:40 +00:00
if ( sidedefs . Count = = 0 ) return new RectangleF ( ) ; //mxd
2013-08-29 12:07:54 +00:00
2009-04-19 18:07:22 +00:00
// Setup
float left = float . MaxValue ;
float top = float . MaxValue ;
float right = float . MinValue ;
float bottom = float . MinValue ;
2013-08-29 12:07:54 +00:00
2016-05-18 20:31:40 +00:00
HashSet < Vertex > processed = new HashSet < Vertex > ( ) ; //mxd
2013-08-29 12:07:54 +00:00
//mxd. This way bbox will be created even if triangulation failed (sector with 2 or less sidedefs and 2 vertices)
2015-12-28 15:01:53 +00:00
foreach ( Sidedef s in sidedefs )
2014-12-03 23:15:26 +00:00
{
2013-08-29 12:07:54 +00:00
//start...
2016-05-18 20:31:40 +00:00
if ( ! processed . Contains ( s . Line . Start ) )
2014-12-03 23:15:26 +00:00
{
2015-12-28 15:01:53 +00:00
if ( s . Line . Start . Position . x < left ) left = s . Line . Start . Position . x ;
if ( s . Line . Start . Position . x > right ) right = s . Line . Start . Position . x ;
if ( s . Line . Start . Position . y < top ) top = s . Line . Start . Position . y ;
if ( s . Line . Start . Position . y > bottom ) bottom = s . Line . Start . Position . y ;
2016-05-18 20:31:40 +00:00
processed . Add ( s . Line . Start ) ;
2013-08-29 12:07:54 +00:00
}
//end...
2016-05-18 20:31:40 +00:00
if ( ! processed . Contains ( s . Line . End ) )
2014-12-03 23:15:26 +00:00
{
2013-08-29 12:07:54 +00:00
if ( s . Line . End . Position . x < left ) left = s . Line . End . Position . x ;
2013-09-03 09:34:28 +00:00
if ( s . Line . End . Position . x > right ) right = s . Line . End . Position . x ;
2013-08-29 12:07:54 +00:00
if ( s . Line . End . Position . y < top ) top = s . Line . End . Position . y ;
2013-09-03 09:34:28 +00:00
if ( s . Line . End . Position . y > bottom ) bottom = s . Line . End . Position . y ;
2016-05-18 20:31:40 +00:00
processed . Add ( s . Line . End ) ;
2013-08-29 12:07:54 +00:00
}
2009-04-19 18:07:22 +00:00
}
// Return rectangle
return new RectangleF ( left , top , right - left , bottom - top ) ;
}
2016-05-29 00:38:55 +00:00
//mxd
internal void UpdateBBox ( )
{
bbox = CreateBBox ( ) ;
}
2009-04-19 18:07:22 +00:00
// This joins the sector with another sector
// This sector will be disposed
public void Join ( Sector other )
{
// Any sidedefs to move?
if ( sidedefs . Count > 0 )
{
// Change secter reference on my sidedefs
// This automatically disposes this sector
while ( sidedefs ! = null )
2009-06-11 21:21:20 +00:00
sidedefs . First . Value . SetSector ( other ) ;
2009-04-19 18:07:22 +00:00
}
else
{
// No sidedefs attached
// Dispose manually
this . Dispose ( ) ;
}
General . Map . IsChanged = true ;
}
2015-04-15 12:49:28 +00:00
//mxd
public static Geometry . Plane GetFloorPlane ( Sector s )
{
if ( General . Map . UDMF )
{
// UDMF Sector slope?
if ( s . FloorSlope . GetLengthSq ( ) > 0 & & ! float . IsNaN ( s . FloorSlopeOffset / s . FloorSlope . z ) )
return new Geometry . Plane ( s . FloorSlope , s . FloorSlopeOffset ) ;
if ( s . sidedefs . Count = = 3 )
{
Geometry . Plane floor = new Geometry . Plane ( new Vector3D ( 0 , 0 , 1 ) , - s . FloorHeight ) ;
Vector3D [ ] verts = new Vector3D [ 3 ] ;
bool sloped = false ;
int index = 0 ;
// Check vertices
foreach ( Sidedef sd in s . Sidedefs )
{
Vertex v = sd . IsFront ? sd . Line . End : sd . Line . Start ;
//create "normal" vertices
verts [ index ] = new Vector3D ( v . Position ) ;
// Check floor
if ( ! float . IsNaN ( v . ZFloor ) )
{
//vertex offset is absolute
verts [ index ] . z = v . ZFloor ;
sloped = true ;
}
else
{
verts [ index ] . z = floor . GetZ ( v . Position ) ;
}
index + + ;
}
// Have slope?
return ( sloped ? new Geometry . Plane ( verts [ 0 ] , verts [ 1 ] , verts [ 2 ] , true ) : floor ) ;
}
}
// Have line slope?
2015-12-28 15:01:53 +00:00
foreach ( Sidedef side in s . sidedefs )
2015-04-15 12:49:28 +00:00
{
// Carbon copy of EffectLineSlope class here...
if ( side . Line . Action = = 181 & & ( ( side . Line . Args [ 0 ] = = 1 & & side = = side . Line . Front ) | | side . Line . Args [ 0 ] = = 2 ) & & side . Other ! = null )
{
Linedef l = side . Line ;
// Find the vertex furthest from the line
Vertex foundv = null ;
float founddist = - 1.0f ;
foreach ( Sidedef sd in s . Sidedefs )
{
Vertex v = sd . IsFront ? sd . Line . Start : sd . Line . End ;
float d = l . DistanceToSq ( v . Position , false ) ;
if ( d > founddist )
{
foundv = v ;
founddist = d ;
}
}
Vector3D v1 = new Vector3D ( l . Start . Position . x , l . Start . Position . y , side . Other . Sector . FloorHeight ) ;
Vector3D v2 = new Vector3D ( l . End . Position . x , l . End . Position . y , side . Other . Sector . FloorHeight ) ;
Vector3D v3 = new Vector3D ( foundv . Position . x , foundv . Position . y , s . FloorHeight ) ;
return ( l . SideOfLine ( v3 ) < 0.0f ? new Geometry . Plane ( v1 , v2 , v3 , true ) : new Geometry . Plane ( v2 , v1 , v3 , true ) ) ;
}
}
//TODO: other types of slopes...
// Normal (flat) floor plane
return new Geometry . Plane ( new Vector3D ( 0 , 0 , 1 ) , - s . FloorHeight ) ;
}
//mxd
public static Geometry . Plane GetCeilingPlane ( Sector s )
{
if ( General . Map . UDMF )
{
// UDMF Sector slope?
if ( s . CeilSlope . GetLengthSq ( ) > 0 & & ! float . IsNaN ( s . CeilSlopeOffset / s . CeilSlope . z ) )
return new Geometry . Plane ( s . CeilSlope , s . CeilSlopeOffset ) ;
if ( s . sidedefs . Count = = 3 )
{
Geometry . Plane ceiling = new Geometry . Plane ( new Vector3D ( 0 , 0 , - 1 ) , s . CeilHeight ) ;
Vector3D [ ] verts = new Vector3D [ 3 ] ;
bool sloped = false ;
int index = 0 ;
// Check vertices
foreach ( Sidedef sd in s . Sidedefs )
{
Vertex v = sd . IsFront ? sd . Line . End : sd . Line . Start ;
//create "normal" vertices
verts [ index ] = new Vector3D ( v . Position ) ;
// Check floor
if ( ! float . IsNaN ( v . ZCeiling ) )
{
//vertex offset is absolute
verts [ index ] . z = v . ZCeiling ;
sloped = true ;
}
else
{
verts [ index ] . z = ceiling . GetZ ( v . Position ) ;
}
index + + ;
}
// Have slope?
return ( sloped ? new Geometry . Plane ( verts [ 0 ] , verts [ 2 ] , verts [ 1 ] , false ) : ceiling ) ;
}
}
// Have line slope?
foreach ( Sidedef side in s . sidedefs )
{
// Carbon copy of EffectLineSlope class here...
if ( side . Line . Action = = 181 & & ( ( side . Line . Args [ 1 ] = = 1 & & side = = side . Line . Front ) | | side . Line . Args [ 1 ] = = 2 ) & & side . Other ! = null )
{
Linedef l = side . Line ;
// Find the vertex furthest from the line
Vertex foundv = null ;
float founddist = - 1.0f ;
foreach ( Sidedef sd in s . Sidedefs )
{
Vertex v = sd . IsFront ? sd . Line . Start : sd . Line . End ;
float d = l . DistanceToSq ( v . Position , false ) ;
if ( d > founddist )
{
foundv = v ;
founddist = d ;
}
}
Vector3D v1 = new Vector3D ( l . Start . Position . x , l . Start . Position . y , side . Other . Sector . CeilHeight ) ;
Vector3D v2 = new Vector3D ( l . End . Position . x , l . End . Position . y , side . Other . Sector . CeilHeight ) ;
Vector3D v3 = new Vector3D ( foundv . Position . x , foundv . Position . y , s . CeilHeight ) ;
return ( l . SideOfLine ( v3 ) > 0.0f ? new Geometry . Plane ( v1 , v2 , v3 , false ) : new Geometry . Plane ( v2 , v1 , v3 , false ) ) ;
}
}
//TODO: other types of slopes...
// Normal (flat) ceiling plane
return new Geometry . Plane ( new Vector3D ( 0 , 0 , - 1 ) , s . CeilHeight ) ;
}
2009-04-19 18:07:22 +00:00
// String representation
public override string ToString ( )
{
2016-05-18 20:31:40 +00:00
#if DEBUG
return "Sector " + listindex + ( marked ? " (marked)" : "" ) ; //mxd
#else
2009-06-05 19:03:56 +00:00
return "Sector " + listindex ;
2016-05-18 20:31:40 +00:00
#endif
2009-04-19 18:07:22 +00:00
}
#endregion
#region = = = = = = = = = = = = = = = = = = Changes
2013-07-10 08:59:17 +00:00
//mxd. This updates all properties (Doom/Hexen version)
public void Update ( int hfloor , int hceil , string tfloor , string tceil , int effect , int tag , int brightness )
{
2015-07-27 21:35:42 +00:00
Update ( hfloor , hceil , tfloor , tceil , effect , new Dictionary < string , bool > ( StringComparer . Ordinal ) , new List < int > { tag } , brightness , 0 , new Vector3D ( ) , 0 , new Vector3D ( ) ) ;
2013-07-10 08:59:17 +00:00
}
//mxd. This updates all properties (UDMF version)
2015-07-27 21:35:42 +00:00
public void Update ( int hfloor , int hceil , string tfloor , string tceil , int effect , Dictionary < string , bool > flags , List < int > tags , int brightness , float flooroffset , Vector3D floorslope , float ceiloffset , Vector3D ceilslope )
2009-04-19 18:07:22 +00:00
{
2009-06-11 21:21:20 +00:00
BeforePropsChange ( ) ;
2009-04-19 18:07:22 +00:00
// Apply changes
this . floorheight = hfloor ;
this . ceilheight = hceil ;
this . effect = effect ;
2015-07-27 21:35:42 +00:00
this . tags = new List < int > ( tags ) ; //mxd
2013-07-10 08:59:17 +00:00
this . flags = new Dictionary < string , bool > ( flags ) ; //mxd
2009-04-19 18:07:22 +00:00
this . brightness = brightness ;
2014-08-25 11:15:19 +00:00
this . flooroffset = flooroffset ; //mxd
this . floorslope = floorslope ; //mxd
this . ceiloffset = ceiloffset ; //mxd
this . ceilslope = ceilslope ; //mxd
2014-12-03 09:06:05 +00:00
//mxd. Set ceil texture
if ( string . IsNullOrEmpty ( tceil ) ) tceil = "-" ;
ceiltexname = tceil ;
longceiltexname = Lump . MakeLongName ( ceiltexname ) ;
//mxd. Set floor texture
if ( string . IsNullOrEmpty ( tfloor ) ) tfloor = "-" ; //mxd
floortexname = tfloor ;
longfloortexname = Lump . MakeLongName ( tfloor ) ;
//mxd. Map is changed
General . Map . IsChanged = true ;
2009-04-19 18:07:22 +00:00
updateneeded = true ;
}
// This sets texture
public void SetFloorTexture ( string name )
{
2009-06-11 21:21:20 +00:00
BeforePropsChange ( ) ;
2014-03-05 09:21:28 +00:00
if ( string . IsNullOrEmpty ( name ) ) name = "-" ; //mxd
2009-04-19 18:07:22 +00:00
floortexname = name ;
2016-03-23 14:52:33 +00:00
longfloortexname = Lump . MakeLongName ( name ) ;
2009-04-19 18:07:22 +00:00
updateneeded = true ;
General . Map . IsChanged = true ;
}
// This sets texture
public void SetCeilTexture ( string name )
{
2009-06-11 21:21:20 +00:00
BeforePropsChange ( ) ;
2014-03-05 09:21:28 +00:00
if ( string . IsNullOrEmpty ( name ) ) name = "-" ; //mxd
2009-04-19 18:07:22 +00:00
ceiltexname = name ;
2016-03-23 14:52:33 +00:00
longceiltexname = Lump . MakeLongName ( name ) ;
2009-04-19 18:07:22 +00:00
updateneeded = true ;
General . Map . IsChanged = true ;
}
2013-09-11 08:49:45 +00:00
//mxd
2014-12-03 09:06:05 +00:00
public void UpdateFogColor ( )
{
if ( General . Map . UDMF & & Fields . ContainsKey ( "fadecolor" ) )
Fixed, Visual mode: in some cases ceiling glow effect was interfering with Transfer Brightness effect resulting in incorrectly lit sidedef geometry.
Fixed, Visual mode: UDMF sidedef brightness should be ignored when a wall section is affected by Transfer Brightness effect.
Fixed, Visual mode: any custom fog should be rendered regardless of sector brightness.
Fixed, Visual mode: "fogdensity" and "outsidefogdensity" MAPINFO values were processed incorrectly.
Fixed, Visual mode: in some cases Things were rendered twice during a render pass.
Fixed, Visual mode: floor glow effect should affect thing brightness only when applied to floor of the sector thing is in.
Fixed, TEXTURES parser: TEXTURES group was named incorrectly in the Textures Browser window when parsed from a WAD file.
Fixed, MAPINFO, GLDEFS, DECORATE parsers: "//$GZDB_SKIP" special comment was processed incorrectly.
Fixed, MAPINFO parser: "fogdensity" and "outsidefogdensity" properties are now initialized using GZDoom default value (255) instead of 0.
2016-01-25 13:42:53 +00:00
{
fogcolor = new Color4 ( ( int ) Fields [ "fadecolor" ] . Value ) ;
fogmode = SectorFogMode . FADE ;
}
// Sector uses outisde fog when it's ceiling is sky or Sector_Outside effect (87) is set
else if ( General . Map . Data . MapInfo . HasOutsideFogColor & &
( ceiltexname = = General . Map . Config . SkyFlatName | | ( effect = = 87 & & General . Map . Config . SectorEffects . ContainsKey ( effect ) ) ) )
{
fogcolor = General . Map . Data . MapInfo . OutsideFogColor ;
fogmode = SectorFogMode . OUTSIDEFOGDENSITY ;
}
2014-12-03 09:06:05 +00:00
else if ( General . Map . Data . MapInfo . HasFadeColor )
Fixed, Visual mode: in some cases ceiling glow effect was interfering with Transfer Brightness effect resulting in incorrectly lit sidedef geometry.
Fixed, Visual mode: UDMF sidedef brightness should be ignored when a wall section is affected by Transfer Brightness effect.
Fixed, Visual mode: any custom fog should be rendered regardless of sector brightness.
Fixed, Visual mode: "fogdensity" and "outsidefogdensity" MAPINFO values were processed incorrectly.
Fixed, Visual mode: in some cases Things were rendered twice during a render pass.
Fixed, Visual mode: floor glow effect should affect thing brightness only when applied to floor of the sector thing is in.
Fixed, TEXTURES parser: TEXTURES group was named incorrectly in the Textures Browser window when parsed from a WAD file.
Fixed, MAPINFO, GLDEFS, DECORATE parsers: "//$GZDB_SKIP" special comment was processed incorrectly.
Fixed, MAPINFO parser: "fogdensity" and "outsidefogdensity" properties are now initialized using GZDoom default value (255) instead of 0.
2016-01-25 13:42:53 +00:00
{
fogcolor = General . Map . Data . MapInfo . FadeColor ;
fogmode = SectorFogMode . FOGDENSITY ;
}
2014-12-03 09:06:05 +00:00
else
Fixed, Visual mode: in some cases ceiling glow effect was interfering with Transfer Brightness effect resulting in incorrectly lit sidedef geometry.
Fixed, Visual mode: UDMF sidedef brightness should be ignored when a wall section is affected by Transfer Brightness effect.
Fixed, Visual mode: any custom fog should be rendered regardless of sector brightness.
Fixed, Visual mode: "fogdensity" and "outsidefogdensity" MAPINFO values were processed incorrectly.
Fixed, Visual mode: in some cases Things were rendered twice during a render pass.
Fixed, Visual mode: floor glow effect should affect thing brightness only when applied to floor of the sector thing is in.
Fixed, TEXTURES parser: TEXTURES group was named incorrectly in the Textures Browser window when parsed from a WAD file.
Fixed, MAPINFO, GLDEFS, DECORATE parsers: "//$GZDB_SKIP" special comment was processed incorrectly.
Fixed, MAPINFO parser: "fogdensity" and "outsidefogdensity" properties are now initialized using GZDoom default value (255) instead of 0.
2016-01-25 13:42:53 +00:00
{
fogcolor = new Color4 ( ) ;
fogmode = ( brightness < 248 ? SectorFogMode . CLASSIC : SectorFogMode . NONE ) ;
}
2013-09-11 08:49:45 +00:00
}
2009-04-19 18:07:22 +00:00
#endregion
}
}