2014-02-26 14:11:06 +00:00
using System ;
using System.IO ;
2012-05-22 22:56:42 +00:00
using System.Collections.Generic ;
using System.Globalization ;
using CodeImp.DoomBuilder.ZDoom ;
2012-06-01 10:17:47 +00:00
using CodeImp.DoomBuilder.GZBuilder.Data ;
2012-05-22 22:56:42 +00:00
namespace CodeImp.DoomBuilder.GZBuilder.GZDoom {
2013-09-11 09:47:53 +00:00
public sealed class GldefsParser : ZDTextParser {
2012-06-01 10:17:47 +00:00
2013-09-11 09:47:53 +00:00
public delegate void IncludeDelegate ( GldefsParser parser , string includefile ) ;
public IncludeDelegate OnInclude ;
2012-06-01 10:17:47 +00:00
2013-09-11 09:47:53 +00:00
private Dictionary < string , DynamicLightData > lightsByName ; //LightName, light definition
private Dictionary < string , string > objects ; //ClassName, LightName
2012-06-01 10:17:47 +00:00
2013-09-11 09:47:53 +00:00
public Dictionary < string , DynamicLightData > LightsByName { get { return lightsByName ; } }
public Dictionary < string , string > Objects { get { return objects ; } }
2012-06-01 10:17:47 +00:00
2013-09-11 09:47:53 +00:00
private List < string > parsedLumps ;
2012-06-01 10:17:47 +00:00
2014-12-03 23:15:26 +00:00
private struct GldefsLightType
{
2013-09-11 09:47:53 +00:00
public const string POINT = "pointlight" ;
public const string PULSE = "pulselight" ;
public const string FLICKER = "flickerlight" ;
public const string FLICKER2 = "flickerlight2" ;
public const string SECTOR = "sectorlight" ;
2012-06-01 10:17:47 +00:00
2014-02-26 14:11:06 +00:00
public static Dictionary < string , DynamicLightType > GLDEFS_TO_GZDOOM_LIGHT_TYPE = new Dictionary < string , DynamicLightType > ( StringComparer . Ordinal ) { { POINT , DynamicLightType . NORMAL } , { PULSE , DynamicLightType . PULSE } , { FLICKER , DynamicLightType . FLICKER } , { FLICKER2 , DynamicLightType . RANDOM } , { SECTOR , DynamicLightType . SECTOR } } ;
2013-09-11 09:47:53 +00:00
}
2014-12-03 23:15:26 +00:00
public GldefsParser ( )
{
2013-09-11 09:47:53 +00:00
parsedLumps = new List < string > ( ) ;
2014-02-26 14:11:06 +00:00
lightsByName = new Dictionary < string , DynamicLightData > ( StringComparer . Ordinal ) ; //LightName, Light params
objects = new Dictionary < string , string > ( StringComparer . Ordinal ) ; //ClassName, LightName
2013-09-11 09:47:53 +00:00
}
2014-12-03 23:15:26 +00:00
public override bool Parse ( Stream stream , string sourcefilename )
{
2013-09-11 09:47:53 +00:00
base . Parse ( stream , sourcefilename ) ;
2014-12-03 23:15:26 +00:00
if ( parsedLumps . IndexOf ( sourcefilename ) ! = - 1 )
{
2013-09-11 09:47:53 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Error: already parsed '" + sourcefilename + "'. Check your #include directives!" ) ;
return false ;
}
parsedLumps . Add ( sourcefilename ) ;
// Keep local data
Stream localstream = datastream ;
string localsourcename = sourcename ;
BinaryReader localreader = datareader ;
// Continue until at the end of the stream
2014-12-03 23:15:26 +00:00
while ( SkipWhitespace ( true ) )
{
2013-09-11 09:47:53 +00:00
string token = ReadToken ( ) ;
2014-12-03 23:15:26 +00:00
if ( ! string . IsNullOrEmpty ( token ) )
{
2013-09-11 09:47:53 +00:00
token = StripTokenQuotes ( token . ToLowerInvariant ( ) ) ; //Quotes can be anywhere! ANYWHERE!!! And GZDoom will still parse data correctly
//got light structure
2014-12-03 23:15:26 +00:00
if ( token = = GldefsLightType . POINT | | token = = GldefsLightType . PULSE | | token = = GldefsLightType . FLICKER
| | token = = GldefsLightType . FLICKER2 | | token = = GldefsLightType . SECTOR )
{
2013-09-11 09:47:53 +00:00
bool gotErrors = false ;
string lightType = token ;
DynamicLightData light = new DynamicLightData ( ) ;
light . Type = GldefsLightType . GLDEFS_TO_GZDOOM_LIGHT_TYPE [ lightType ] ;
//find classname
SkipWhitespace ( true ) ;
string lightName = StripTokenQuotes ( ReadToken ( ) ) . ToLowerInvariant ( ) ;
2014-12-03 23:15:26 +00:00
if ( ! string . IsNullOrEmpty ( lightName ) )
{
2013-09-11 09:47:53 +00:00
//now find opening brace
SkipWhitespace ( true ) ;
token = ReadToken ( ) ;
2014-12-03 23:15:26 +00:00
if ( token ! = "{" )
{
2014-01-03 10:33:45 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected '{', but got '" + token + "'" ) ;
2013-09-11 09:47:53 +00:00
continue ; //something wrong with gldefs declaration, continue to next one
}
//read gldefs light structure
2014-12-03 23:15:26 +00:00
while ( SkipWhitespace ( true ) )
{
2013-09-11 09:47:53 +00:00
token = ReadToken ( ) ;
2014-12-03 23:15:26 +00:00
if ( ! string . IsNullOrEmpty ( token ) )
{
2013-09-11 09:47:53 +00:00
token = token . ToLowerInvariant ( ) ;
2012-06-01 10:17:47 +00:00
//color
2014-12-03 23:15:26 +00:00
if ( token = = "color" )
{
2013-09-11 09:47:53 +00:00
SkipWhitespace ( true ) ;
token = StripTokenQuotes ( ReadToken ( ) ) ;
2014-12-03 23:15:26 +00:00
if ( ! float . TryParse ( token , NumberStyles . Float , CultureInfo . InvariantCulture , out light . Color . Red ) )
{
2013-09-11 09:47:53 +00:00
// Not numeric!
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected Red Color value, but got '" + token + "'" ) ;
gotErrors = true ;
break ;
}
SkipWhitespace ( true ) ;
token = StripTokenQuotes ( ReadToken ( ) ) ;
2014-12-03 23:15:26 +00:00
if ( ! float . TryParse ( token , NumberStyles . Float , CultureInfo . InvariantCulture , out light . Color . Green ) )
{
2013-09-11 09:47:53 +00:00
// Not numeric!
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected Green Color value, but got '" + token + "'" ) ;
gotErrors = true ;
break ;
}
SkipWhitespace ( true ) ;
token = StripTokenQuotes ( ReadToken ( ) ) ;
2014-12-03 23:15:26 +00:00
if ( ! float . TryParse ( token , NumberStyles . Float , CultureInfo . InvariantCulture , out light . Color . Blue ) )
{
2013-09-11 09:47:53 +00:00
// Not numeric!
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected Blue Color value, but got '" + token + "'" ) ;
gotErrors = true ;
break ;
}
2012-06-01 10:17:47 +00:00
//size
2014-12-03 23:15:26 +00:00
}
else if ( token = = "size" )
{
if ( lightType ! = GldefsLightType . SECTOR )
{
2013-09-11 09:47:53 +00:00
SkipWhitespace ( true ) ;
token = StripTokenQuotes ( ReadToken ( ) ) ;
2014-12-03 23:15:26 +00:00
if ( ! int . TryParse ( token , NumberStyles . Integer , CultureInfo . InvariantCulture , out light . PrimaryRadius ) )
{
2013-09-11 09:47:53 +00:00
// Not numeric!
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected Size value, but got '" + token + "'" ) ;
gotErrors = true ;
break ;
}
light . PrimaryRadius * = 2 ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-09-11 09:47:53 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": '" + token + "' is not valid property for " + lightType ) ;
gotErrors = true ;
break ;
}
2012-06-01 10:17:47 +00:00
//offset
2014-12-03 23:15:26 +00:00
}
else if ( token = = "offset" )
{
2013-09-11 09:47:53 +00:00
SkipWhitespace ( true ) ;
token = StripTokenQuotes ( ReadToken ( ) ) ;
2014-12-03 23:15:26 +00:00
if ( ! ReadSignedFloat ( token , ref light . Offset . X ) )
{
2013-09-11 09:47:53 +00:00
// Not numeric!
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected Offset X value, but got '" + token + "'" ) ;
gotErrors = true ;
break ;
}
SkipWhitespace ( true ) ;
token = StripTokenQuotes ( ReadToken ( ) ) ;
2014-12-03 23:15:26 +00:00
if ( ! ReadSignedFloat ( token , ref light . Offset . Z ) )
{
2013-09-11 09:47:53 +00:00
// Not numeric!
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected Offset Y value, but got '" + token + "'" ) ;
gotErrors = true ;
break ;
}
SkipWhitespace ( true ) ;
token = StripTokenQuotes ( ReadToken ( ) ) ;
2014-12-03 23:15:26 +00:00
if ( ! ReadSignedFloat ( token , ref light . Offset . Y ) )
{
2013-09-11 09:47:53 +00:00
// Not numeric!
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected Offset Z value, but got '" + token + "'" ) ;
gotErrors = true ;
break ;
}
2012-06-01 10:17:47 +00:00
//subtractive
2014-12-03 23:15:26 +00:00
}
else if ( token = = "subtractive" )
{
2013-09-11 09:47:53 +00:00
SkipWhitespace ( true ) ;
token = StripTokenQuotes ( ReadToken ( ) ) ;
int i ;
2014-12-03 23:15:26 +00:00
if ( ! int . TryParse ( token , NumberStyles . Integer , CultureInfo . InvariantCulture , out i ) )
{
2013-09-11 09:47:53 +00:00
// Not numeric!
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected Subtractive value, but got '" + token + "'" ) ;
gotErrors = true ;
break ;
}
light . Subtractive = i = = 1 ;
2012-06-01 10:17:47 +00:00
//dontlightself
2014-12-03 23:15:26 +00:00
}
else if ( token = = "dontlightself" )
{
2013-09-11 09:47:53 +00:00
SkipWhitespace ( true ) ;
token = StripTokenQuotes ( ReadToken ( ) ) ;
int i ;
2014-12-03 23:15:26 +00:00
if ( ! int . TryParse ( token , NumberStyles . Integer , CultureInfo . InvariantCulture , out i ) )
{
2013-09-11 09:47:53 +00:00
// Not numeric!
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected Dontlightself value, but got '" + token + "'" ) ;
gotErrors = true ;
break ;
}
light . DontLightSelf = ( i = = 1 ) ;
2012-06-01 10:17:47 +00:00
//interval
2014-12-03 23:15:26 +00:00
}
else if ( token = = "interval" )
{
if ( lightType = = GldefsLightType . PULSE | | lightType = = GldefsLightType . FLICKER2 )
{
2013-09-11 09:47:53 +00:00
SkipWhitespace ( true ) ;
token = StripTokenQuotes ( ReadToken ( ) ) ;
float interval ;
2014-12-03 23:15:26 +00:00
if ( ! float . TryParse ( token , NumberStyles . Float , CultureInfo . InvariantCulture , out interval ) )
{
2013-09-11 09:47:53 +00:00
// Not numeric!
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected Interval value, but got '" + token + "'" ) ;
gotErrors = true ;
break ;
}
2014-12-03 23:15:26 +00:00
if ( interval = = 0 )
2014-03-11 09:44:39 +00:00
General . ErrorLogger . Add ( ErrorType . Warning , "Warning in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": Interval value should be greater than zero" ) ;
2013-09-11 09:47:53 +00:00
//I wrote logic for dynamic lights animation first, so here I modify gldefs settings to fit in existing logic
2014-12-03 23:15:26 +00:00
if ( lightType = = GldefsLightType . PULSE )
{
2013-09-11 09:47:53 +00:00
light . Interval = ( int ) ( interval * 35 ) ; //measured in tics (35 per second) in PointLightPulse, measured in seconds in gldefs' PulseLight
2014-12-03 23:15:26 +00:00
}
else //FLICKER2. Seems like PointLightFlickerRandom to me
{
2013-09-11 09:47:53 +00:00
light . Interval = ( int ) ( interval * 350 ) ; //0.1 is one second for FlickerLight2
}
2014-12-03 23:15:26 +00:00
}
else
{
2013-09-11 09:47:53 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": '" + token + "' is not valid property for " + lightType ) ;
gotErrors = true ;
break ;
}
2012-06-01 10:17:47 +00:00
//secondarysize
2014-12-03 23:15:26 +00:00
}
else if ( token = = "secondarysize" )
{
if ( lightType = = GldefsLightType . PULSE | | lightType = = GldefsLightType . FLICKER | | lightType = = GldefsLightType . FLICKER2 )
{
2013-09-11 09:47:53 +00:00
SkipWhitespace ( true ) ;
token = StripTokenQuotes ( ReadToken ( ) ) ;
2014-12-03 23:15:26 +00:00
if ( ! int . TryParse ( token , NumberStyles . Integer , CultureInfo . InvariantCulture , out light . SecondaryRadius ) )
{
2013-09-11 09:47:53 +00:00
// Not numeric!
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected SecondarySize value, but got '" + token + "'" ) ;
gotErrors = true ;
break ;
}
light . SecondaryRadius * = 2 ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-09-11 09:47:53 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": '" + token + "' is not valid property for " + lightType ) ;
gotErrors = true ;
break ;
}
2012-06-01 10:17:47 +00:00
//chance
2014-12-03 23:15:26 +00:00
}
else if ( token = = "chance" )
{
if ( lightType = = GldefsLightType . FLICKER )
{
2013-09-11 09:47:53 +00:00
SkipWhitespace ( true ) ;
token = StripTokenQuotes ( ReadToken ( ) ) ;
float chance ;
2014-12-03 23:15:26 +00:00
if ( ! float . TryParse ( token , NumberStyles . Float , CultureInfo . InvariantCulture , out chance ) )
{
2013-09-11 09:47:53 +00:00
// Not numeric!
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected Chance value, but got '" + token + "'" ) ;
gotErrors = true ;
break ;
}
//transforming from 0.0 .. 1.0 to 0 .. 359 to fit in existing logic
light . Interval = ( int ) ( chance * 359.0f ) ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-09-11 09:47:53 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": '" + token + "' is not valid property for " + lightType ) ;
gotErrors = true ;
break ;
}
2012-06-01 10:17:47 +00:00
//scale
2014-12-03 23:15:26 +00:00
}
else if ( token = = "scale" )
{
if ( lightType = = GldefsLightType . SECTOR )
{
2013-09-11 09:47:53 +00:00
SkipWhitespace ( true ) ;
token = StripTokenQuotes ( ReadToken ( ) ) ;
float scale ;
2014-12-03 23:15:26 +00:00
if ( ! float . TryParse ( token , NumberStyles . Float , CultureInfo . InvariantCulture , out scale ) )
{
2013-09-11 09:47:53 +00:00
// Not numeric!
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected Scale value, but got '" + token + "'" ) ;
gotErrors = true ;
break ;
}
2014-12-03 23:15:26 +00:00
if ( scale > 1.0f )
{
2013-09-11 09:47:53 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": scale must be in 0.0 - 1.0 range, but is " + scale ) ;
gotErrors = true ;
break ;
}
//sector light doesn't have animation, so we will store it's size in Interval
//transforming from 0.0 .. 1.0 to 0 .. 10 to preserve value.
light . Interval = ( int ) ( scale * 10.0f ) ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-09-11 09:47:53 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": '" + token + "' is not valid property for " + lightType ) ;
gotErrors = true ;
break ;
}
2014-12-03 23:15:26 +00:00
}
//end of structure
else if ( token = = "}" )
{
if ( ! gotErrors )
{
2013-09-11 09:47:53 +00:00
//general checks
2014-12-03 23:15:26 +00:00
if ( light . Color . Red = = 0.0f & & light . Color . Green = = 0.0f & & light . Color . Blue = = 0.0f )
{
2013-12-20 09:24:43 +00:00
General . ErrorLogger . Add ( ErrorType . Warning , "'" + sourcefilename + "', line " + GetCurrentLineNumber ( ) + ": light Color is " + light . Color . Red + "," + light . Color . Green + "," + light . Color . Blue + ". It won't be shown in GZDoom!" ) ;
2013-09-11 09:47:53 +00:00
gotErrors = true ;
}
//light-type specific checks
2014-12-03 23:15:26 +00:00
if ( light . Type = = DynamicLightType . NORMAL & & light . PrimaryRadius = = 0 )
{
General . ErrorLogger . Add ( ErrorType . Warning , "'" + sourcefilename + "', line " + GetCurrentLineNumber ( ) + ": light Size is 0. It won't be shown in GZDoom!" ) ;
gotErrors = true ;
2013-09-11 09:47:53 +00:00
}
2014-12-03 23:15:26 +00:00
if ( light . Type = = DynamicLightType . FLICKER | | light . Type = = DynamicLightType . PULSE | | light . Type = = DynamicLightType . RANDOM )
{
if ( light . PrimaryRadius = = 0 & & light . SecondaryRadius = = 0 )
{
2013-12-20 09:24:43 +00:00
General . ErrorLogger . Add ( ErrorType . Warning , "'" + sourcefilename + "', line " + GetCurrentLineNumber ( ) + ": 'Size' and 'SecondarySize' are 0. This light won't be shown in GZDoom!" ) ;
2013-09-11 09:47:53 +00:00
gotErrors = true ;
}
}
//offset it slightly to avoid shading glitches
2014-12-03 23:15:26 +00:00
if ( light . Offset . Z = = 0.0f ) light . Offset . Z = 0.1f ;
2013-09-11 09:47:53 +00:00
2014-12-03 23:15:26 +00:00
if ( ! gotErrors )
{
if ( lightsByName . ContainsKey ( lightName ) )
2013-09-11 09:47:53 +00:00
lightsByName [ lightName ] = light ;
2014-12-03 23:15:26 +00:00
else
2013-09-11 09:47:53 +00:00
lightsByName . Add ( lightName , light ) ;
}
}
break ; //break out of this parsing loop
}
}
}
}
2014-12-03 23:15:26 +00:00
}
else if ( token = = "object" )
{
2013-09-11 09:47:53 +00:00
SkipWhitespace ( true ) ;
//read object class
string objectClass = StripTokenQuotes ( ReadToken ( ) ) . ToLowerInvariant ( ) ;
2014-12-03 23:15:26 +00:00
if ( ! string . IsNullOrEmpty ( objectClass ) )
{
2013-09-11 09:47:53 +00:00
//now find opening brace
SkipWhitespace ( true ) ;
token = ReadToken ( ) ;
2014-12-03 23:15:26 +00:00
if ( token ! = "{" )
{
2014-01-03 10:33:45 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": expected '{', but got '" + token + "'" ) ;
2013-09-11 09:47:53 +00:00
continue ;
}
int bracesCount = 1 ;
bool foundLight = false ;
2014-03-11 12:35:26 +00:00
bool foundFrame = false ;
2013-09-11 09:47:53 +00:00
//read frames structure
2014-12-03 23:15:26 +00:00
while ( SkipWhitespace ( true ) )
{
2013-09-11 09:47:53 +00:00
token = ReadToken ( ) ;
2014-12-03 23:15:26 +00:00
if ( ! string . IsNullOrEmpty ( token ) )
{
2013-09-11 09:47:53 +00:00
token = StripTokenQuotes ( token ) . ToLowerInvariant ( ) ;
2014-12-03 23:15:26 +00:00
if ( ! foundLight & & ! foundFrame & & token = = "frame" )
{
2014-03-11 12:35:26 +00:00
SkipWhitespace ( true ) ;
token = ReadToken ( ) . ToLowerInvariant ( ) ; //should be frame name
//use this frame if it's 4 characters long or it's the first frame
foundFrame = ( token . Length = = 4 | | ( token . Length > 4 & & token [ 4 ] = = 'a' ) ) ;
2014-12-03 23:15:26 +00:00
}
else if ( ! foundLight & & foundFrame & & token = = "light" ) //just use first light and be done with it
{
2013-09-11 09:47:53 +00:00
SkipWhitespace ( true ) ;
token = ReadToken ( ) . ToLowerInvariant ( ) ; //should be light name
2014-12-03 23:15:26 +00:00
if ( ! string . IsNullOrEmpty ( token ) )
{
if ( lightsByName . ContainsKey ( token ) )
{
2013-09-11 09:47:53 +00:00
if ( objects . ContainsKey ( objectClass ) )
objects [ objectClass ] = token ;
else
objects . Add ( objectClass , token ) ;
foundLight = true ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-09-11 08:49:45 +00:00
General . ErrorLogger . Add ( ErrorType . Warning , "Light declaration not found for light '" + token + "' ('" + sourcefilename + "', line " + GetCurrentLineNumber ( ) + ")" ) ;
2013-09-11 09:47:53 +00:00
}
}
2014-12-03 23:15:26 +00:00
}
else if ( token = = "{" ) //continue in this loop until object structure ends
{
2013-09-11 09:47:53 +00:00
bracesCount + + ;
2014-12-03 23:15:26 +00:00
}
else if ( token = = "}" )
{
if ( - - bracesCount < 1 ) break ; //This was Cave Johnson. And we are done here.
2013-09-11 09:47:53 +00:00
}
}
}
}
2014-12-03 23:15:26 +00:00
}
else if ( token = = "#include" )
{
2013-09-11 09:47:53 +00:00
SkipWhitespace ( true ) ;
string includeLump = StripTokenQuotes ( ReadToken ( ) ) . ToLowerInvariant ( ) ;
2014-12-03 23:15:26 +00:00
if ( ! string . IsNullOrEmpty ( includeLump ) )
{
2013-09-11 09:47:53 +00:00
// Callback to parse this file
if ( OnInclude ! = null )
OnInclude ( this , includeLump . Replace ( Path . AltDirectorySeparatorChar , Path . DirectorySeparatorChar ) ) ;
// Set our buffers back to continue parsing
datastream = localstream ;
datareader = localreader ;
sourcename = localsourcename ;
2014-12-03 23:15:26 +00:00
}
else
{
2013-09-11 09:47:53 +00:00
General . ErrorLogger . Add ( ErrorType . Error , "Error in '" + sourcefilename + "' at line " + GetCurrentLineNumber ( ) + ": got #include directive with missing or incorrect path: '" + includeLump + "'" ) ;
}
2014-12-03 23:15:26 +00:00
}
else
{
2013-09-11 09:47:53 +00:00
// Unknown structure!
string token2 ;
2014-12-03 23:15:26 +00:00
do
{
2013-09-11 09:47:53 +00:00
if ( ! SkipWhitespace ( true ) ) break ;
token2 = ReadToken ( ) ;
if ( token2 = = null ) break ;
}
while ( token2 ! = "{" ) ;
int scopelevel = 1 ;
2014-12-03 23:15:26 +00:00
do
{
2013-09-11 09:47:53 +00:00
if ( ! SkipWhitespace ( true ) ) break ;
token2 = ReadToken ( ) ;
if ( token2 = = null ) break ;
if ( token2 = = "{" ) scopelevel + + ;
if ( token2 = = "}" ) scopelevel - - ;
}
while ( scopelevel > 0 ) ;
}
}
}
2013-12-20 09:24:43 +00:00
return objects . Count > 0 ;
2013-09-11 09:47:53 +00:00
}
}
2012-06-01 10:17:47 +00:00
}