ZoneBuilder/Source/Core/ZDoom/StateGoto.cs

207 lines
4.9 KiB
C#

#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
#endregion
namespace CodeImp.DoomBuilder.ZDoom
{
internal sealed class StateGoto
{
#region ================== Constants
#endregion
#region ================== Variables
private string classname;
private string statename;
private int spriteoffset;
#endregion
#region ================== Properties
public string ClassName { get { return classname; } }
public string StateName { get { return statename; } }
public int SpriteOffset { get { return spriteoffset; } }
#endregion
#region ================== Constructor / Disposer
// Constructor
internal StateGoto(ActorStructure actor, DecorateParser parser)
{
string firsttarget = "";
string secondtarget = "";
bool commentreached = false;
bool offsetreached = false;
string offsetstr = "";
int cindex = 0;
// This is a bitch to parse because for some bizarre reason someone thought it
// was funny to allow quotes here. Read the whole line and start parsing this manually.
string line = parser.ReadLine();
// Skip whitespace
while((cindex < line.Length) && ((line[cindex] == ' ') || (line[cindex] == '\t')))
cindex++;
// Parse first target
while((cindex < line.Length) && (line[cindex] != ':'))
{
// When a comment is reached, we're done here
if(line[cindex] == '/')
{
if((cindex + 1 < line.Length) && ((line[cindex + 1] == '/') || (line[cindex + 1] == '*')))
{
commentreached = true;
break;
}
}
// Whitespace ends the string
if((line[cindex] == ' ') || (line[cindex] == '\t'))
break;
// + sign indicates offset start
if(line[cindex] == '+')
{
cindex++;
offsetreached = true;
break;
}
// Ignore quotes
if(line[cindex] != '"')
firsttarget += line[cindex];
cindex++;
}
if(!commentreached && !offsetreached)
{
// Skip whitespace
while((cindex < line.Length) && ((line[cindex] == ' ') || (line[cindex] == '\t')))
cindex++;
// Parse second target
while(cindex < line.Length)
{
// When a comment is reached, we're done here
if(line[cindex] == '/')
{
if((cindex + 1 < line.Length) && ((line[cindex + 1] == '/') || (line[cindex + 1] == '*')))
{
commentreached = true;
break;
}
}
// Whitespace ends the string
if((line[cindex] == ' ') || (line[cindex] == '\t'))
break;
// + sign indicates offset start
if(line[cindex] == '+')
{
cindex++;
offsetreached = true;
break;
}
// Ignore quotes and semicolons
if((line[cindex] != '"') && (line[cindex] != ':'))
secondtarget += line[cindex];
cindex++;
}
}
// Try to find the offset if we still haven't found it yet
if(!offsetreached)
{
// Skip whitespace
while((cindex < line.Length) && ((line[cindex] == ' ') || (line[cindex] == '\t')))
cindex++;
if((cindex < line.Length) && (line[cindex] == '+'))
{
cindex++;
offsetreached = true;
}
}
if(offsetreached)
{
// Parse offset
while(cindex < line.Length)
{
// When a comment is reached, we're done here
if(line[cindex] == '/')
{
if((cindex + 1 < line.Length) && ((line[cindex + 1] == '/') || (line[cindex + 1] == '*')))
{
commentreached = true;
break;
}
}
// Whitespace ends the string
if((line[cindex] == ' ') || (line[cindex] == '\t'))
break;
// Ignore quotes and semicolons
if((line[cindex] != '"') && (line[cindex] != ':'))
offsetstr += line[cindex];
cindex++;
}
}
// We should now have a first target, optionally a second target and optionally a sprite offset
// Check if we don't have the class specified
if(string.IsNullOrEmpty(secondtarget))
{
// First target is the state to go to
classname = actor.ClassName;
statename = firsttarget.ToLowerInvariant().Trim();
}
else
{
// First target is the base class to use
// Second target is the state to go to
classname = firsttarget.ToLowerInvariant().Trim();
statename = secondtarget.ToLowerInvariant().Trim();
}
if(offsetstr.Length > 0)
int.TryParse(offsetstr, out spriteoffset);
if((classname == "super") && (actor.BaseClass != null))
classname = actor.BaseClass.ClassName;
}
#endregion
#region ================== Methods
#endregion
}
}