swwmgz_m/zscript/hud/swwm_dialogue.zsc

176 lines
5.7 KiB
Text

// dialogue sequences
Class SWWMDialogues abstract
{
// where the magic happens
static ui void StartSeq( String dlg )
{
if ( dlg == "" )
{
if ( developer >= 2 ) Console.Printf("StartSeq: bogus call with empty dialogue name, check your code.");
return;
}
// load the lump for parsing
Array<String> lines;
Array<int> lnums;
int cur = -1;
for ( int lmp = Wads.FindLumpFullName("swwmdialogue",0,true); lmp != -1; lmp = Wads.FindLumpFullName("swwmdialogue",lmp+1,true) )
{
String dat = Wads.ReadLump(lmp);
lines.Clear();
dat.Split(lines,"\n",0);
lnums.Clear();
// for the error output
for ( int i=0; i<lines.Size(); i++ ) lnums.Push(i+1);
// strip comments and trim whitespace
for ( int i=0; i<lines.Size(); i++ )
{
if ( lines[i].Left(1) == "#" )
{
lines.Delete(i);
lnums.Delete(i);
i--;
continue;
}
lines[i].StripLeftRight();
}
cur = -1;
// locate named dialogue
for ( int i=0; i<lines.Size(); i++ )
{
if ( lines[i].Left(4) != "DLG " ) continue;
if ( lines[i].Mid(4) != dlg ) continue;
cur = i;
break;
}
if ( cur != -1 ) break;
}
if ( cur == -1 )
{
if ( developer >= 2 ) Console.Printf("ProcessDlg: sequence '%s' not found",dlg);
return;
}
// start parsing from here
cur++;
bool gotseq = false;
bool inseq = false;
String schr, sname;
int scnt, sdelay, sstartdelay, senddelay, schardelay, spausedelay;
bool sindirect, sznvspecial;
SWWMDirectMessage msg, lastmsg;
while ( cur < lines.Size() )
{
// dialogue ends here
if ( lines[cur].Left(6) == "ENDDLG" )
{
if ( inseq ) ThrowAbortException("dialogue '%s', line %d, premature end of sequence.",dlg,lnums[cur]);
if ( !gotseq ) ThrowAbortException("dialogue '%s', line %d, dialogue is empty.",dlg,lnums[cur]);
return;
}
if ( inseq )
{
// fetch params until we find ENDSEQ
if ( lines[cur].Left(6) == "ENDSEQ" )
{
// put out the sequence
if ( sname == "" ) ThrowAbortException("dialogue '%s', line %d, sequence has no name.",dlg,lnums[cur]);
msg.seqname = sname;
if ( scnt <= 0 ) ThrowAbortException("dialogue '%s', line %d, sequence has invalid count.",dlg,lnums[cur]);
msg.seqcnt = scnt;
if ( sdelay > 0 ) msg.delay = sdelay;
if ( sstartdelay > 0 ) msg.startdelay = sstartdelay;
if ( senddelay > 0 ) msg.enddelay = senddelay;
if ( schardelay > 0 ) msg.chardelay = schardelay;
if ( spausedelay > 0 ) msg.pausedelay = spausedelay;
msg.znvspecial = sznvspecial;
if ( !gotseq )
{
// first message? attach to hud here
StatusBar.AttachMessage(msg,-1232);
}
else
{
// additional message? append to last
if ( !lastmsg ) ThrowAbortException("dialogue '%s', line %d, lastmsg is null, this should not happen.",dlg,lnums[cur]);
lastmsg.nextmsg = msg;
lastmsg.nextdirect = !sindirect;
}
gotseq = true;
inseq = false;
}
else if ( lines[cur].Left(5) == "NAME " )
{
if ( sname != "" ) ThrowAbortException("dialogue '%s', line %d, duplicate 'NAME' parameter.",dlg,lnums[cur]);
sname = lines[cur].Mid(5);
}
else if ( lines[cur].Left(4) == "CNT " )
{
if ( scnt > 0 ) ThrowAbortException("dialogue '%s', line %d, duplicate 'CNT' parameter.",dlg,lnums[cur]);
scnt = lines[cur].Mid(4).ToInt();
}
else if ( lines[cur].Left(6) == "DELAY " )
{
if ( sdelay > 0 ) ThrowAbortException("dialogue '%s', line %d, duplicate 'DELAY' parameter.",dlg,lnums[cur]);
sdelay = lines[cur].Mid(6).ToInt();
}
else if ( lines[cur].Left(11) == "STARTDELAY " )
{
if ( sstartdelay > 0 ) ThrowAbortException("dialogue '%s', line %d, duplicate 'STARTDELAY' parameter.",dlg,lnums[cur]);
sstartdelay = lines[cur].Mid(11).ToInt();
}
else if ( lines[cur].Left(9) == "ENDDELAY " )
{
if ( senddelay > 0 ) ThrowAbortException("dialogue '%s', line %d, duplicate 'ENDDELAY' parameter.",dlg,lnums[cur]);
senddelay = lines[cur].Mid(9).ToInt();
}
else if ( lines[cur].Left(10) == "CHARDELAY " )
{
if ( schardelay > 0 ) ThrowAbortException("dialogue '%s', line %d, duplicate 'CHARDELAY' parameter.",dlg,lnums[cur]);
schardelay = lines[cur].Mid(10).ToInt();
}
else if ( lines[cur].Left(11) == "PAUSEDELAY " )
{
if ( spausedelay > 0 ) ThrowAbortException("dialogue '%s', line %d, duplicate 'PAUSEDELAY' parameter.",dlg,lnums[cur]);
spausedelay = lines[cur].Mid(11).ToInt();
}
else if ( lines[cur].Left(8) == "INDIRECT" )
{
if ( sindirect ) ThrowAbortException("dialogue '%s', line %d, duplicate 'INDIRECT' parameter.",dlg,lnums[cur]);
sindirect = true;
}
else if ( lines[cur].Left(10) == "ZNVSPECIAL" )
{
if ( sznvspecial ) ThrowAbortException("dialogue '%s', line %d, duplicate 'ZNVSPECIAL' parameter.",dlg,lnums[cur]);
sznvspecial = true;
}
else ThrowAbortException("dialogue '%s', line %d, parameter not recognized",dlg,lnums[cur]);
cur++;
continue;
}
if ( lines[cur].Left(4) == "SEQ " )
{
// begin dialogue
inseq = true;
schr = lines[cur].Mid(4);
if ( schr == "" ) ThrowAbortException("dialogue '%s', line %d, sequence has no character.",dlg,lnums[cur]);
lastmsg = msg;
msg = new("SWWMDirectMessage").Init(StringTable.Localize("$SWWM_"..schr.."SNAME"),StringTable.Localize("$SWWM_"..schr.."NAME"),schr);
// wipe params
sname = "";
scnt = 0;
sdelay = 0;
sstartdelay = 0;
senddelay = 0;
schardelay = 0;
spausedelay = 0;
sindirect = false;
sznvspecial = false;
cur++;
continue;
}
ThrowAbortException("dialogue '%s', line %d, expected 'SEQ' directive",dlg,lnums[cur]);
return;
}
ThrowAbortException("dialogue '%s', cursor past end of file.",dlg);
}
}