2007-06-14 14:44:18 +00:00
2007-06-14 23:31:57 +00:00
#region = = = = = = = = = = = = = = = = = = Copyright ( c ) 2007 Pascal vd Heiden
2007-06-14 14:44:18 +00:00
/ *
* 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 .
*
* /
2007-06-14 23:31:57 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Namespaces
2007-06-14 12:37:46 +00:00
using System ;
using System.Collections ;
using System.Collections.Generic ;
using System.Globalization ;
using System.Text ;
2007-11-04 22:19:30 +00:00
using CodeImp.DoomBuilder.IO ;
2008-01-13 21:23:59 +00:00
using CodeImp.DoomBuilder.Geometry ;
2008-04-12 16:07:10 +00:00
using System.Drawing ;
2008-05-18 11:43:28 +00:00
using CodeImp.DoomBuilder.Rendering ;
2008-10-07 12:54:15 +00:00
using System.Collections.ObjectModel ;
2008-10-15 11:46:43 +00:00
using SlimDX.Direct3D9 ;
using SlimDX ;
2007-06-14 12:37:46 +00:00
2007-06-14 23:31:57 +00:00
#endregion
2007-06-14 12:37:46 +00:00
namespace CodeImp.DoomBuilder.Map
{
2008-10-16 08:45:23 +00:00
public sealed class Sector : SelectableElement , ID3DResource
2007-06-14 12:37:46 +00:00
{
#region = = = = = = = = = = = = = = = = = = Constants
#endregion
#region = = = = = = = = = = = = = = = = = = Variables
// Map
2007-06-14 13:09:55 +00:00
private MapSet map ;
2007-06-14 12:37:46 +00:00
// List items
private LinkedListNode < Sector > mainlistitem ;
2009-03-30 07:45:39 +00:00
private LinkedListNode < Sector > selecteditem ;
2007-06-14 12:37:46 +00:00
// Sidedefs
private LinkedList < Sidedef > sidedefs ;
// Properties
2009-03-10 06:46:02 +00:00
private int fixedindex ;
2007-06-14 12:37:46 +00:00
private int floorheight ;
private int ceilheight ;
private string floortexname ;
private string ceiltexname ;
2007-11-04 22:19:30 +00:00
private long longfloortexname ;
private long longceiltexname ;
2007-10-24 17:25:03 +00:00
private int effect ;
2007-06-14 12:37:46 +00:00
private int tag ;
2007-10-14 15:44:55 +00:00
private int brightness ;
2007-06-14 12:37:46 +00:00
2007-11-23 09:33:56 +00:00
// Cloning
private Sector clone ;
2008-12-06 13:20:47 +00:00
private int serializedindex ;
2007-11-23 09:33:56 +00:00
2008-01-13 21:23:59 +00:00
// Triangulation
private bool updateneeded ;
2008-05-18 11:43:28 +00:00
private bool triangulationneeded ;
2008-11-26 22:56:53 +00:00
private RectangleF bbox ;
2008-10-07 05:50:39 +00:00
private Triangulation triangles ;
private FlatVertex [ ] flatvertices ;
2008-10-07 12:54:15 +00:00
private ReadOnlyCollection < LabelPositionInfo > labels ;
2008-10-15 11:46:43 +00:00
private VertexBuffer flatceilingbuffer ;
private VertexBuffer flatfloorbuffer ;
2008-10-07 12:54:15 +00:00
2007-06-14 12:37:46 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Properties
2007-07-07 09:40:34 +00:00
public MapSet Map { get { return map ; } }
2007-10-20 19:50:03 +00:00
public ICollection < Sidedef > Sidedefs { get { return sidedefs ; } }
2009-03-10 06:46:02 +00:00
/// <summary>
/// An unique index that does not change when other sectors are removed.
/// </summary>
public int FixedIndex { get { return fixedindex ; } }
2008-02-22 17:11:29 +00:00
public int FloorHeight { get { return floorheight ; } set { floorheight = value ; } }
public int CeilHeight { get { return ceilheight ; } set { ceilheight = value ; } }
2007-10-14 15:44:55 +00:00
public string FloorTexture { get { return floortexname ; } }
public string CeilTexture { get { return ceiltexname ; } }
2007-11-04 22:19:30 +00:00
public long LongFloorTexture { get { return longfloortexname ; } }
public long LongCeilTexture { get { return longceiltexname ; } }
2008-02-22 17:11:29 +00:00
public int Effect { get { return effect ; } set { effect = value ; } }
2009-04-09 11:46:51 +00:00
public int Tag { get { return tag ; } set { tag = value ; if ( ( tag < General . Map . FormatInterface . MinTag ) | | ( tag > General . Map . FormatInterface . MaxTag ) ) throw new ArgumentOutOfRangeException ( "Tag" , "Invalid tag number" ) ; } }
2008-05-18 11:43:28 +00:00
public int Brightness { get { return brightness ; } set { brightness = value ; updateneeded = true ; } }
public bool UpdateNeeded { get { return updateneeded ; } set { updateneeded | = value ; triangulationneeded | = value ; } }
2008-11-26 22:56:53 +00:00
public RectangleF BBox { get { return bbox ; } }
2008-12-06 13:20:47 +00:00
internal Sector Clone { get { return clone ; } set { clone = value ; } }
internal int SerializedIndex { get { return serializedindex ; } set { serializedindex = value ; } }
2008-10-07 05:50:39 +00:00
public Triangulation Triangles { get { return triangles ; } }
public FlatVertex [ ] FlatVertices { get { return flatvertices ; } }
2008-10-15 11:46:43 +00:00
internal VertexBuffer FlatCeilingBuffer { get { return flatceilingbuffer ; } }
internal VertexBuffer FlatFloorBuffer { get { return flatfloorbuffer ; } }
2008-10-07 12:54:15 +00:00
public ReadOnlyCollection < LabelPositionInfo > Labels { get { return labels ; } }
2007-06-14 12:37:46 +00:00
#endregion
#region = = = = = = = = = = = = = = = = = = Constructor / Disposer
// Constructor
2008-05-10 16:09:45 +00:00
internal Sector ( MapSet map , LinkedListNode < Sector > listitem , int index )
2007-06-14 12:37:46 +00:00
{
// Initialize
this . map = map ;
this . mainlistitem = listitem ;
this . sidedefs = new LinkedList < Sidedef > ( ) ;
2009-03-10 06:46:02 +00:00
this . fixedindex = index ;
2008-04-19 15:44:05 +00:00
this . floortexname = "-" ;
this . ceiltexname = "-" ;
2008-09-17 19:21:45 +00:00
this . longfloortexname = MapSet . EmptyLongName ;
this . longceiltexname = MapSet . EmptyLongName ;
2008-06-11 05:02:48 +00:00
this . triangulationneeded = true ;
2008-10-15 11:46:43 +00:00
General . Map . Graphics . RegisterResource ( this ) ;
2007-06-14 12:37:46 +00:00
// We have no destructor
GC . SuppressFinalize ( this ) ;
}
2008-12-06 13:20:47 +00:00
// Constructor
internal Sector ( MapSet map , LinkedListNode < Sector > listitem , IReadWriteStream stream )
{
// Initialize
this . map = map ;
this . mainlistitem = listitem ;
this . sidedefs = new LinkedList < Sidedef > ( ) ;
this . triangulationneeded = true ;
ReadWrite ( stream ) ;
General . Map . Graphics . RegisterResource ( this ) ;
// We have no destructor
GC . SuppressFinalize ( this ) ;
}
2008-01-02 21:49:43 +00:00
// Disposer
2008-05-30 08:41:13 +00:00
public override void Dispose ( )
2007-06-14 12:37:46 +00:00
{
// Not already disposed?
if ( ! isdisposed )
{
// Already set isdisposed so that changes can be prohibited
isdisposed = true ;
// Remove from main list
mainlistitem . List . Remove ( mainlistitem ) ;
2007-12-27 01:24:11 +00:00
// Register the index as free
2009-03-10 06:46:02 +00:00
map . AddSectorIndexHole ( fixedindex ) ;
2007-06-14 12:37:46 +00:00
// Dispose the sidedefs that are attached to this sector
// because a sidedef cannot exist without reference to its sector.
foreach ( Sidedef sd in sidedefs ) sd . Dispose ( ) ;
2008-10-15 11:46:43 +00:00
General . Map . Graphics . UnregisterResource ( this ) ;
2007-06-14 12:37:46 +00:00
// Clean up
2008-10-15 11:46:43 +00:00
if ( flatceilingbuffer ! = null ) flatceilingbuffer . Dispose ( ) ;
if ( flatfloorbuffer ! = null ) flatfloorbuffer . Dispose ( ) ;
flatceilingbuffer = null ;
flatfloorbuffer = null ;
2007-06-14 12:37:46 +00:00
mainlistitem = null ;
sidedefs = null ;
map = null ;
2008-05-30 08:41:13 +00:00
// Dispose base
base . Dispose ( ) ;
2007-06-14 12:37:46 +00:00
}
}
#endregion
#region = = = = = = = = = = = = = = = = = = Management
2008-12-06 13:20:47 +00:00
// Serialize / deserialize
internal void ReadWrite ( IReadWriteStream s )
{
base . ReadWrite ( s ) ;
2009-03-10 06:46:02 +00:00
s . rwInt ( ref fixedindex ) ;
2008-12-06 13:20:47 +00:00
s . rwInt ( ref floorheight ) ;
s . rwInt ( ref ceilheight ) ;
s . rwString ( ref floortexname ) ;
s . rwString ( ref ceiltexname ) ;
2009-02-20 19:06:38 +00:00
//s.rwLong(ref longfloortexname);
//s.rwLong(ref longceiltexname);
2008-12-06 13:20:47 +00:00
s . rwInt ( ref effect ) ;
s . rwInt ( ref tag ) ;
s . rwInt ( ref brightness ) ;
2009-02-20 19:06:38 +00:00
2009-02-20 15:59:55 +00:00
// Use a new triangulator when reading from stream
if ( ! s . IsWriting & & ( triangles = = null ) ) triangles = new Triangulation ( ) ;
triangles . ReadWrite ( s ) ;
if ( s . IsWriting )
{
s . wInt ( labels . Count ) ;
for ( int i = 0 ; i < labels . Count ; i + + )
{
s . wVector2D ( labels [ i ] . position ) ;
s . wFloat ( labels [ i ] . radius ) ;
}
}
else
{
2009-02-20 19:06:38 +00:00
longfloortexname = Lump . MakeLongName ( floortexname ) ;
longceiltexname = Lump . MakeLongName ( ceiltexname ) ;
2009-02-20 15:59:55 +00:00
int c ; s . rInt ( out c ) ;
LabelPositionInfo [ ] labelsarray = new LabelPositionInfo [ c ] ;
for ( int i = 0 ; i < c ; i + + )
{
s . rVector2D ( out labelsarray [ i ] . position ) ;
s . rFloat ( out labelsarray [ i ] . radius ) ;
}
labels = Array . AsReadOnly < LabelPositionInfo > ( labelsarray ) ;
}
}
// After deserialization
internal void PostDeserialize ( MapSet map )
{
triangles . PostDeserialize ( map ) ;
// We need to rebuild the vertex buffer,
// but the triangulation was deserialized
updateneeded = true ;
triangulationneeded = false ;
2008-12-06 13:20:47 +00:00
}
2007-11-12 22:43:01 +00:00
// This copies all properties to another sector
public void CopyPropertiesTo ( Sector s )
{
// Copy properties
s . ceilheight = ceilheight ;
s . ceiltexname = ceiltexname ;
s . longceiltexname = longceiltexname ;
s . floorheight = floorheight ;
s . floortexname = floortexname ;
s . longfloortexname = longfloortexname ;
s . effect = effect ;
s . tag = tag ;
s . brightness = brightness ;
2008-05-18 11:43:28 +00:00
s . updateneeded = true ;
2008-10-16 08:45:23 +00:00
base . CopyPropertiesTo ( s ) ;
2007-11-12 22:43:01 +00:00
}
2009-03-10 17:22:22 +00:00
/// <summary>
/// Returns the index of this sector. This is a O(n) operation.
/// </summary>
public int GetIndex ( )
{
return map . GetIndexForSector ( this ) ;
}
2007-11-12 22:43:01 +00:00
2007-06-14 12:37:46 +00:00
// This attaches a sidedef and returns the listitem
2008-01-13 21:23:59 +00:00
public LinkedListNode < Sidedef > AttachSidedef ( Sidedef sd )
{
updateneeded = true ;
2008-05-18 11:43:28 +00:00
triangulationneeded = true ;
2008-01-13 21:23:59 +00:00
return sidedefs . AddLast ( sd ) ;
}
2007-06-14 12:37:46 +00:00
// This detaches a sidedef
public void DetachSidedef ( LinkedListNode < Sidedef > l )
{
// Not disposing?
if ( ! isdisposed )
{
// Remove sidedef
2008-01-13 21:23:59 +00:00
updateneeded = true ;
2008-05-18 11:43:28 +00:00
triangulationneeded = true ;
2007-06-14 12:37:46 +00:00
sidedefs . Remove ( l ) ;
// No more sidedefs left?
if ( sidedefs . Count = = 0 )
{
// This sector is now useless, dispose it
this . Dispose ( ) ;
}
}
}
2008-10-07 12:54:15 +00:00
2008-01-13 21:23:59 +00:00
// This updates the sector when changes have been made
public void UpdateCache ( )
{
// Update if needed
if ( updateneeded )
{
2008-05-18 11:43:28 +00:00
// Triangulate again?
2008-10-07 05:50:39 +00:00
if ( triangulationneeded | | ( triangles = = null ) )
2008-05-18 11:43:28 +00:00
{
// Triangulate sector
2008-10-07 05:50:39 +00:00
triangles = Triangulation . Create ( this ) ;
2008-10-15 11:46:43 +00:00
triangulationneeded = false ;
2008-10-07 12:54:15 +00:00
// Make label positions
labels = Array . AsReadOnly < LabelPositionInfo > ( Tools . FindLabelPositions ( this ) . ToArray ( ) ) ;
2008-05-18 11:43:28 +00:00
}
// Brightness color (alpha is opaque)
byte clampedbright = 0 ;
if ( ( brightness > = 0 ) & & ( brightness < = 255 ) ) clampedbright = ( byte ) brightness ;
else if ( brightness > 255 ) clampedbright = 255 ;
PixelColor brightcolor = new PixelColor ( 255 , clampedbright , clampedbright , clampedbright ) ;
int brightint = brightcolor . ToInt ( ) ;
// Make vertices
2008-10-07 08:20:29 +00:00
flatvertices = new FlatVertex [ triangles . Vertices . Count ] ;
for ( int i = 0 ; i < triangles . Vertices . Count ; i + + )
2008-05-18 11:43:28 +00:00
{
2008-10-07 05:50:39 +00:00
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 ;
2008-05-18 11:43:28 +00:00
}
2008-11-26 22:56:53 +00:00
// Create bounding box
bbox = CreateBBox ( ) ;
2008-01-13 21:23:59 +00:00
// Updated
updateneeded = false ;
2008-10-15 11:46:43 +00:00
// Update buffers
UpdateFloorSurface ( ) ;
UpdateCeilingSurface ( ) ;
}
}
// This updates the buffer with flat vertices
public void UpdateFloorSurface ( )
{
// Trash buffer, if any
if ( flatfloorbuffer ! = null )
{
flatfloorbuffer . Dispose ( ) ;
flatfloorbuffer = null ;
}
// Not updated?
if ( updateneeded )
{
// Make sure the sector is up-to-date
// This will automatically call this function again
UpdateCache ( ) ;
}
// Any vertices?
else if ( flatvertices . Length > 0 )
{
2009-01-13 06:31:53 +00:00
if ( General . Map . Graphics . CheckAvailability ( ) )
{
FlatVertex [ ] buffervertices = new FlatVertex [ triangles . Vertices . Count ] ;
flatvertices . CopyTo ( buffervertices , 0 ) ;
2008-10-15 11:46:43 +00:00
2009-01-13 06:31:53 +00:00
// Raise event to allow plugins to modify this data
General . Plugins . OnSectorFloorSurfaceUpdate ( this , ref buffervertices ) ;
2008-10-15 11:46:43 +00:00
2009-01-13 06:31:53 +00:00
// Make the buffer
flatfloorbuffer = new VertexBuffer ( General . Map . Graphics . Device , FlatVertex . Stride * buffervertices . Length ,
Usage . WriteOnly | Usage . Dynamic , VertexFormat . None , Pool . Default ) ;
2008-10-15 11:46:43 +00:00
2009-01-13 06:31:53 +00:00
// Fill it
DataStream bufferstream = flatfloorbuffer . Lock ( 0 , FlatVertex . Stride * buffervertices . Length , LockFlags . Discard ) ;
bufferstream . WriteRange < FlatVertex > ( buffervertices ) ;
flatfloorbuffer . Unlock ( ) ;
bufferstream . Dispose ( ) ;
}
2008-10-15 11:46:43 +00:00
}
}
// This updates the buffer with flat vertices
public void UpdateCeilingSurface ( )
{
// Trash buffer, if any
if ( flatceilingbuffer ! = null )
{
flatceilingbuffer . Dispose ( ) ;
flatceilingbuffer = null ;
}
// Not updated?
if ( updateneeded )
{
// Make sure the sector is up-to-date
// This will automatically call this function again
UpdateCache ( ) ;
}
// Any vertices?
else if ( flatvertices . Length > 0 )
{
2009-01-13 06:31:53 +00:00
if ( General . Map . Graphics . CheckAvailability ( ) )
{
FlatVertex [ ] buffervertices = new FlatVertex [ triangles . Vertices . Count ] ;
flatvertices . CopyTo ( buffervertices , 0 ) ;
2008-10-15 11:46:43 +00:00
2009-01-13 06:31:53 +00:00
// Raise event to allow plugins to modify this data
General . Plugins . OnSectorCeilingSurfaceUpdate ( this , ref buffervertices ) ;
2008-10-15 11:46:43 +00:00
2009-01-13 06:31:53 +00:00
// Make the buffer
flatceilingbuffer = new VertexBuffer ( General . Map . Graphics . Device , FlatVertex . Stride * buffervertices . Length ,
Usage . WriteOnly | Usage . Dynamic , VertexFormat . None , Pool . Default ) ;
2008-10-15 11:46:43 +00:00
2009-01-13 06:31:53 +00:00
// Fill it
DataStream bufferstream = flatceilingbuffer . Lock ( 0 , FlatVertex . Stride * buffervertices . Length , LockFlags . Discard ) ;
bufferstream . WriteRange < FlatVertex > ( buffervertices ) ;
flatceilingbuffer . Unlock ( ) ;
bufferstream . Dispose ( ) ;
}
2008-01-13 21:23:59 +00:00
}
}
2008-10-15 11:46:43 +00:00
// Unload unstable resources
public void UnloadResource ( )
{
// Trash buffer, if any
if ( flatfloorbuffer ! = null )
{
flatfloorbuffer . Dispose ( ) ;
flatfloorbuffer = null ;
}
// Trash buffer, if any
if ( flatceilingbuffer ! = null )
{
flatceilingbuffer . Dispose ( ) ;
flatceilingbuffer = null ;
}
}
// Reload unstable resources
public void ReloadResource ( )
{
UpdateFloorSurface ( ) ;
UpdateCeilingSurface ( ) ;
}
2009-03-30 07:45:39 +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 ;
}
2007-06-14 12:37:46 +00:00
#endregion
2008-11-26 14:52:39 +00:00
2008-05-16 20:00:49 +00:00
#region = = = = = = = = = = = = = = = = = = Methods
2008-10-03 14:31:25 +00:00
2008-11-26 14:52:39 +00:00
// This checks if the given point is inside the sector polygon
public bool Intersect ( Vector2D p )
{
uint c = 0 ;
// Go for all sidedefs
foreach ( Sidedef sd in sidedefs )
{
// Get vertices
Vector2D v1 = sd . Line . Start . Position ;
Vector2D v2 = sd . Line . End . Position ;
// Determine min/max values
float miny = Math . Min ( v1 . y , v2 . y ) ;
float maxy = Math . Max ( v1 . y , v2 . y ) ;
float maxx = Math . Max ( v1 . x , v2 . x ) ;
// Check for intersection
if ( ( p . y > miny ) & & ( p . y < = maxy ) )
{
if ( p . x < = maxx )
{
if ( v1 . y ! = v2 . y )
{
float xint = ( p . y - v1 . y ) * ( v2 . x - v1 . x ) / ( v2 . y - v1 . y ) + v1 . x ;
if ( ( v1 . x = = v2 . x ) | | ( p . x < = xint ) ) c + + ;
}
}
}
}
// Inside this polygon?
return ( ( c & 0x00000001 UL ) ! = 0 ) ;
}
2008-10-03 14:31:25 +00:00
// This creates a bounding box rectangle
2008-10-07 05:50:39 +00:00
// This requires the sector triangulation to be up-to-date!
2008-11-26 22:56:53 +00:00
private RectangleF CreateBBox ( )
2008-10-03 14:31:25 +00:00
{
// Setup
float left = float . MaxValue ;
float top = float . MaxValue ;
float right = float . MinValue ;
float bottom = float . MinValue ;
// Go for vertices
2008-10-07 05:50:39 +00:00
foreach ( Vector2D v in triangles . Vertices )
2008-10-03 14:31:25 +00:00
{
// Update rect
if ( v . x < left ) left = v . x ;
if ( v . y < top ) top = v . y ;
if ( v . x > right ) right = v . x ;
if ( v . y > bottom ) bottom = v . y ;
}
// Return rectangle
return new RectangleF ( left , top , right - left , bottom - top ) ;
}
2008-05-16 20:00:49 +00:00
// This joins the sector with another sector
// This sector will be disposed
public void Join ( Sector other )
{
2008-05-16 21:48:23 +00:00
// Any sidedefs to move?
if ( sidedefs . Count > 0 )
{
// Change secter reference on my sidedefs
// This automatically disposes this sector
while ( sidedefs ! = null )
sidedefs . First . Value . ChangeSector ( other ) ;
}
else
{
// No sidedefs attached
// Dispose manually
this . Dispose ( ) ;
}
2009-01-03 22:18:59 +00:00
General . Map . IsChanged = true ;
2008-05-16 20:00:49 +00:00
}
2009-03-11 20:21:50 +00:00
// String representation
public override string ToString ( )
{
return "Sector " + GetIndex ( ) ;
}
2008-01-25 19:12:34 +00:00
2008-05-16 20:00:49 +00:00
#endregion
2007-06-24 18:56:43 +00:00
#region = = = = = = = = = = = = = = = = = = Changes
// This updates all properties
2007-10-24 17:25:03 +00:00
public void Update ( int hfloor , int hceil , string tfloor , string tceil , int effect , int tag , int brightness )
2007-06-24 18:56:43 +00:00
{
// Apply changes
this . floorheight = hfloor ;
this . ceilheight = hceil ;
2007-11-04 22:19:30 +00:00
SetFloorTexture ( tfloor ) ;
SetCeilTexture ( tceil ) ;
2007-10-24 17:25:03 +00:00
this . effect = effect ;
2007-06-24 18:56:43 +00:00
this . tag = tag ;
2007-10-14 15:44:55 +00:00
this . brightness = brightness ;
2008-05-18 11:43:28 +00:00
updateneeded = true ;
2007-06-24 18:56:43 +00:00
}
2007-11-04 22:19:30 +00:00
// This sets texture
public void SetFloorTexture ( string name )
{
floortexname = name ;
longfloortexname = Lump . MakeLongName ( name ) ;
2008-05-18 11:43:28 +00:00
updateneeded = true ;
2009-01-03 22:18:59 +00:00
General . Map . IsChanged = true ;
2007-11-04 22:19:30 +00:00
}
// This sets texture
public void SetCeilTexture ( string name )
{
ceiltexname = name ;
longceiltexname = Lump . MakeLongName ( name ) ;
2008-05-18 11:43:28 +00:00
updateneeded = true ;
2009-01-03 22:18:59 +00:00
General . Map . IsChanged = true ;
2007-11-04 22:19:30 +00:00
}
2007-06-24 18:56:43 +00:00
#endregion
2007-06-14 12:37:46 +00:00
}
}