swwmgz_m/zscript/handler/swwm_statichandler.zsc

770 lines
26 KiB
Text

// Static handler responsible for some special stuff
// save version holder
Class SWWMSaveVerData : SWWMStaticThinker
{
String ver;
int uid;
}
Class SWWMStaticHandler : StaticEventHandler
{
// crash handler
ui bool wasinmap;
ui int timer, msgpick;
// broccoli doccoli
bool isbd;
// versioning
bool tainted;
String taintver;
int uid;
int checktic;
int maptime;
bool unloading;
ui Dictionary menustate; // used by Demolitionist Menu to restore old menu positions
// title stuff
ui bool titlefirst;
// map title stuff
int mttics;
// warnings
bool mpwarned;
// checks
ThinkerIterator sti;
// for intermissions, to prevent repetition
ui Array<int> lasttip, lastart;
// stupid dumb thing
ui bool aprilfools;
ui Font aprfnt;
override void NewGame()
{
// set save version every new session
let svd = new("SWWMSaveVerData");
svd.ChangeStatNum(Thinker.STAT_STATIC);
svd.ver = StringTable.Localize("$SWWM_SHORTVER");
uid = 0;
}
override void WorldUnloaded( WorldEvent e )
{
SWWMHandler.ClearAllShaders();
unloading = true;
}
override void WorldTick()
{
if ( mttics > 0 )
{
mttics--;
if ( mttics == 0 ) EventHandler.SendInterfaceEvent(consoleplayer,"swwmmaptitle");
}
maptime++;
// in case we start late?
if ( multiplayer && !mpwarned )
{
mpwarned = true;
Console.Printf("\cgWARNING:\c- Multiplayer is no longer supported, desyncs and other issues WILL happen. You are on your own.");
S_StartSound("compat/warn",CHAN_YABLEWIT,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE);
}
// sanity check
Array<Thinker> stinkers;
if ( !sti ) sti = ThinkerIterator.Create("SWWMStaticThinker");
else sti.Reinit();
foreach ( t:sti ) stinkers.Push(t);
if ( stinkers.Size() > 0 )
{
foreach ( s:stinkers ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"%s is not STAT_STATIC!",s.GetClassName());
ThrowAbortException("Panic! %d static thinker%s been tampered with!",stinkers.Size(),(stinkers.Size()==1)?" has":"s have");
}
}
override void WorldLoaded( WorldEvent e )
{
if ( gamestate != GS_TITLELEVEL )
mttics = 10; // count down to show the "area name"
unloading = false;
maptime = 0;
if ( e.IsSavegame || e.IsReopen )
{
// restore underwater sounds for players
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] || !(players[i].mo is 'Demolitionist') ) continue;
Demolitionist(players[i].mo).CheckUnderwaterAmb(true);
}
}
SWWMHandler.ClearAllShaders();
EventHandler.SendInterfaceEvent(consoleplayer,"swwmflushhud");
EventHandler.SendInterfaceEvent(consoleplayer,"swwmaprcheck");
if ( !e.IsSaveGame ) return;
// save version checker
tainted = false;
taintver = "";
checktic = gametic+5;
let ti = ThinkerIterator.Create("SWWMSaveVerData",Thinker.STAT_STATIC);
let svd = SWWMSaveVerData(ti.Next());
if ( !svd )
{
tainted = true;
taintver = "\cg(no version info)\c-";
uid = 0;
}
else
{
String cver = StringTable.Localize("$SWWM_SHORTVER");
if ( svd.ver != cver )
{
tainted = true;
taintver = svd.ver;
}
if ( svd.uid == uid ) checktic = 0;
uid = svd.uid;
}
}
override void OnUnregister()
{
// save achievements on exit
SaveAchievements();
}
private bool CheckOtherMods()
{
// this should cover as much ground as possible, just checking for any custom player classes that are not
// part of the vanilla set (excluding ones such as, for example, morph targets)
foreach ( cls:AllActorClasses )
{
if ( !(cls is 'PlayerPawn') ) continue;
if ( cls is 'PlayerChunk' ) continue;
switch ( cls.GetClassName() )
{
case 'PlayerPawn':
case 'DoomPlayer':
case 'ChexPlayer':
case 'HereticPlayer':
case 'ChickenPlayer':
case 'FighterPlayer':
case 'ClericPlayer':
case 'MagePlayer':
case 'PigPlayer':
case 'StrifePlayer':
case 'Demolitionist':
case 'SWWMVoodooDoll':
// do nothing
break;
default:
let def = GetDefaultByType((Class<PlayerPawn>)(cls));
// if this class has a morph weapon defined, skip it
if ( def.MorphWeapon ) break;
// we have to check if there are any discrepancies between this class's start item list and
// its parents
let pdef = GetDefaultByType((Class<PlayerPawn>)(cls.GetParentClass()));
let di = def.GetDropItems();
let pdi = pdef.GetDropItems();
// no items, just skip
if ( !di ) break;
do
{
// list sizes don't match
if ( (di && !pdi) || (!di && pdi) ) return true;
// mismatch in item names
if ( di.name != pdi.name ) return true;
di = di.next;
pdi = pdi.next;
}
while ( di || pdi );
break;
}
}
return false;
}
override void OnRegister()
{
// fix voice type cvar
int lmp;
Array<String> types;
for ( lmp = Wads.FindLumpFullName("swwmvoicepack",0,true); lmp != -1; lmp = Wads.FindLumpFullName("swwmvoicepack",lmp+1,true) )
{
Array<String> lst;
lst.Clear();
String dat = Wads.ReadLump(lmp);
dat.Split(lst,"\n",0);
foreach ( l:lst )
{
if ( (l.Length() <= 0) || (l.GetNextCodePoint(0) == 0) || (l.Left(1) == "\n") || (l.Left(1) == "#") ) continue;
types.Push(l);
}
}
let cv = CVar.FindCVar('swwm_voicetype');
if ( types.Find(cv.GetString()) >= types.Size() )
cv.SetString("default");
// load up the achievements
if ( swwm_achievementstate == "" ) MigrateAchievements();
else LoadAchievements();
// precache fonts
Array<String> fonts;
for ( lmp = Wads.FindLumpFullName("precachefonts",0,true); lmp != -1; lmp = Wads.FindLumpFullName("precachefonts",lmp+1,true) )
{
Array<String> lst;
lst.Clear();
String dat = Wads.ReadLump(lmp);
dat.Split(lst,"\n",0);
foreach ( l:lst )
{
if ( (l.Length() <= 0) || (l.GetNextCodePoint(0) == 0) || (l.Left(1) == "\n") || (l.Left(1) == "#") ) continue;
fonts.Push(l);
}
}
foreach ( f:fonts ) Font.GetFont(f);
// warn: mp no longer officially maintained
if ( multiplayer )
{
mpwarned = true;
Console.Printf("\cgWARNING:\c- Multiplayer is no longer supported, desyncs and other issues WILL happen. You are on your own.");
S_StartSound("compat/warn",CHAN_YABLEWIT,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE);
}
bool checked = CheckOtherMods();
if ( checked )
{
// warn for combining with other weapon mods
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,
"\cx┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\c-\n"
"\cx┃ \cr[\cgWARNING\cr]\cx ┃\c-\n"
"\cx┃ \cjYou appear to be loading this alongside another weapon mod.\cx ┃\c-\n"
"\cx┃ \cjIssues are \cfVERY LIKELY\cj to happen.\cx ┃\c-\n"
"\cx┃ \cr[\cgYOU ARE ON YOUR OWN\cr]\cx ┃\c-\n"
"\cx┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\c-");
S_StartSound("compat/warn",CHAN_YABLEWIT,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE);
}
// warning for unsupported
if ( Wads.FindLumpFullName("swwmgamesupported",0,true) != -1 ) return;
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,
"\cx┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓\c-\n"
"\cx┃ \cr[\cgWARNING\cr]\cx ┃\c-\n"
"\cx┃ \chSWWM \czGZ \cjis \cfNOT\cj compatible with the loaded IWAD.\cx ┃\c-\n"
"\cx┃ \cjOnly \cfDoom\cj, \cfHeretic\cj and \cfHexen\cj are supported.\cx ┃\c-\n"
"\cx┃ \cjIssues \cfCAN\cj and \cfWILL\cj happen.\cx ┃\c-\n"
"\cx┃ \cr[\cgYOU ARE ON YOUR OWN\cr]\cx ┃\c-\n"
"\cx┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛\c-");
S_StartSound("compat/warn",CHAN_YABLEWIT,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE);
}
override void RenderOverlay( RenderEvent e )
{
// silly april fools thing
if ( aprilfools && (gamestate == GS_LEVEL) )
{
String str = "Unregistered Ultracam";
if ( !aprfnt ) aprfnt = Font.GetFont("TewiFontOutline");
Screen.DrawText(aprfnt,Font.CR_WHITE,(Screen.GetWidth()-aprfnt.StringWidth(str)*CleanXFac_1)/2,2*CleanYFac_1,str,DTA_CleanNoMove_1,true);
}
}
override void InterfaceProcess( ConsoleEvent e )
{
if ( e.IsManual ) return;
if ( e.Name ~== "swwmmaptitle" )
{
if ( (gamestate != GS_LEVEL) || !swwm_showmaptitle ) return;
StatusBar.AttachMessage(new("DSMapTitle").Init(),-7777);
}
else if ( e.Name ~== "swwmflushhud" )
{
if ( !(StatusBar is 'SWWMStatusBar') ) return;
SWWMStatusBar(StatusBar).Flush();
}
else if ( e.Name ~== "swwmaprcheck" )
{
if ( gamestate != GS_LEVEL ) return;
if ( SystemTime.Format("%d%m",SystemTime.Now()) == "0104" )
{
if ( !aprilfools ) SWWMDialogues.StartSeq("FOOL");
aprilfools = true;
}
else aprilfools = false;
}
}
override void ConsoleProcess( ConsoleEvent e )
{
if ( e.Name ~== "swwmresetcvars" )
{
Array<String> cvarlist;
SWWMUtility.GetCVars(cvarlist);
foreach ( cv:cvarlist )
{
// don't reset these
if ( (cv == "swwm_playtime")
|| (cv == "swwm_achievementstate")
|| (cv == "swwm_achievementprogress") )
continue;
CVar.FindCVar(cv).ResetToDefault();
}
}
else if ( e.Name ~== "swwmresettooltips" )
{
CVar.FindCVar('swwm_tooltipshown').ResetToDefault();
CVar.FindCVar('swwm_tooltipnote').ResetToDefault();
}
else if ( e.Name ~== "swwmlistcvars" )
{
// debug
Array<String> cvarlist;
SWWMUtility.GetCVars(cvarlist);
foreach ( cv:cvarlist )
{
let rcv = CVar.FindCVar(cv);
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,cv.." = "..rcv.GetString());
}
}
else if ( e.Name ~== "swwmgetplaytime" )
{
int val = swwm_playtime;
int sec = (val%60);
int min = ((val/60)%60);
int hour = ((val/3600)%24);
int day = val/86400;
String str = "";
if ( day ) str.AppendFormat("%d days",day);
if ( hour )
{
if ( str != "" ) str = str..", ";
str.AppendFormat("%d hours",hour);
}
if ( min )
{
if ( str != "" ) str = str..", ";
str.AppendFormat("%d minutes",min);
}
if ( sec )
{
if ( str != "" ) str = str..", ";
str.AppendFormat("%d seconds",sec);
}
if ( str == "" ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"No Data");
else Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,str);
}
else if ( e.Name ~== "swwmresetachievements" )
{
foreach ( inf:achievementinfo )
{
achievementstate.Insert(inf.basename,"0");
if ( inf.maxval )
achievementprogress.Insert(inf.basename,"0");
}
}
else if ( e.Name ~== "swwmdumpachievements" )
{
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"---STATE---");
let di = DictionaryIterator.Create(achievementstate);
while ( di.Next() )
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"%s = %s",di.Key(),di.Value());
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"---PROGRESS---");
di = DictionaryIterator.Create(achievementprogress);
while ( di.Next() )
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"%s = %s",di.Key(),di.Value());
}
else if ( e.Name ~== "swwmgetversion" )
{
let ti = ThinkerIterator.Create("SWWMSaveVerData",Thinker.STAT_STATIC);
let svd = SWWMSaveVerData(ti.Next());
if ( svd ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\cj%s\c-",svd.ver);
else Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\cg(no version data)\c-");
if ( tainted ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\cgversion mismatched\c-");
else Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\cdversion not mismatched\c-");
}
else if ( e.Name ~== "swwmdumpthinkers" )
{
Array<Class<Thinker> > sdefs;
foreach ( cls : AllClasses )
{
if ( !(cls is 'Thinker') || (cls is 'Actor') || (cls == 'Thinker') )
continue;
sdefs.Push((Class<Thinker>)(cls));
}
if ( !e.Args[0] )
{
// trim default gzdoom thinkers
for ( int i=0; i<sdefs.Size(); i++ )
{
if ( sdefs[i].GetClassName() != 'WallLightTransfer' )
continue;
sdefs.Delete(0,i+1);
break;
}
}
Array<int> stink;
stink.Resize(sdefs.Size());
for ( int i=Thinker.STAT_INFO; i<Thinker.MAX_STATNUM; i++ )
{
let ti = ThinkerIterator.Create("Thinker",i);
foreach ( t:ti )
{
if ( t is 'Actor' ) continue;
let cls = t.GetClass();
let p = sdefs.Find(cls);
if ( p >= sdefs.Size() ) continue;
stink[p]++;
}
ti.Destroy();
}
for ( int i=0; i<sdefs.Size(); i++ )
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"%s%s%s\c-",stink[i]?"\cj":"\cu",sdefs[i].GetClassName(),(stink[i]>1)?String.Format(" [%d]",stink[i]):"");
}
else if ( e.Name ~== "swwmdumphandlers" )
{
foreach ( cls:AllClasses )
{
if ( !(cls is 'StaticEventHandler') || (cls == 'StaticEventHandler') || (cls == 'EventHandler') )
continue;
bool reg = (cls is 'EventHandler')?EventHandler.Find((Class<EventHandler>)(cls)):StaticEventHandler.Find((Class<StaticEventHandler>)(cls));
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"%s%s\c-",reg?"\cj":"\cu",cls.GetClassName());
}
}
else if ( e.Name ~== "swwmtestdlgsize" )
{
let f = Font.GetFont('TewiFont');
let lmp = Wads.FindLumpFullName("language.def_dlg");
Array<String> lst;
lst.Clear();
String dat = Wads.ReadLump(lmp);
dat.Split(lst,"\n",0);
bool skipme = true;
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"[default]");
bool fail = false;
foreach ( l:lst )
{
if ( l.Left(7) == "// E1M8" ) skipme = false;
if ( l.Left(5) != "SWWM_" ) continue;
if ( skipme ) continue;
// extract string
int st = l.IndexOf("\"")+1;
int en = l.RightIndexOf("\"");
String line = l.Mid(st,en-st);
//line.Filter(); // DOES NOT WORK, FOR SOME REASON
line.Substitute("\\\"","\"");
line.Substitute("\\c","\c");
BrokenLines bl = f.BreakLines(line,220);
if ( bl.Count() > 4 )
{
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\cg%s [%d]\c-",l.Left(st-4),bl.Count());
fail = true;
}
bl.Destroy();
}
if ( !fail ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"ALL OK");
lmp = Wads.FindLumpFullName("language.es_dlg");
lst.Clear();
dat = Wads.ReadLump(lmp);
dat.Split(lst,"\n",0);
skipme = true;
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"[es]");
foreach ( l:lst )
{
if ( l.Left(7) == "// E1M8" ) skipme = false;
if ( l.Left(5) != "SWWM_" ) continue;
if ( skipme ) continue;
// extract string
int st = l.IndexOf("\"")+1;
int en = l.RightIndexOf("\"");
String line = l.Mid(st,en-st);
//line.Filter(); // DOES NOT WORK, FOR SOME REASON
line.Substitute("\\\"","\"");
line.Substitute("\\c","\c");
BrokenLines bl = f.BreakLines(line,220);
if ( bl.Count() > 4 )
{
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\cg%s [%d]\c-",l.Left(st-4),bl.Count());
fail = true;
}
bl.Destroy();
}
if ( !fail ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"ALL OK");
}
else if ( e.Name ~== "swwmvalidatedlgfiles" )
{
for ( int lmp = Wads.FindLumpFullName("swwmdialogue",0,true); lmp != -1; lmp = Wads.FindLumpFullName("swwmdialogue",lmp+1,true) )
{
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\ce-- PARSING FILE \cf'%s'\ce...\c-",Wads.GetLumpFullName(lmp));
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"");
String dat = Wads.ReadLump(lmp);
dat.Replace("\r",""); // just in case
Array<String> lines;
lines.Clear();
dat.Split(lines,"\n",0);
// strip comments and trim whitespace
for ( int i=0; i<lines.Size(); i++ )
{
int cmm = lines[i].IndexOf("#");
if ( cmm != -1 ) lines[i].Truncate(cmm);
lines[i].StripLeftRight();
}
int cur = 0;
bool indlg = false;
bool inseq = false, gotseq = false;
int nseq = 0;
String sdlg, schr, sname;
int scnt, sdelay, sstartdelay, senddelay, schardelay, spausedelay;
bool sindirect, sznvspecial;
while ( cur < lines.Size() )
{
// skip empty lines
if ( lines[cur] == "" )
{
cur++;
continue;
}
// sequence ends here
// dialogue ends here
if ( lines[cur].Left(6) == "ENDDLG" )
{
if ( !indlg ) ThrowAbortException("line %d, 'ENDDLG' found without start of dialogue.",cur+1);
if ( inseq ) ThrowAbortException("dialogue '%s', line %d, premature end of sequence %d.",sdlg,cur+1,nseq);
if ( !gotseq ) ThrowAbortException("dialogue '%s', line %d, dialogue is empty.",sdlg,cur+1);
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"");
indlg = false;
cur++;
continue;
}
if ( !indlg )
{
if ( lines[cur].Left(4) == "DLG " )
{
sdlg = lines[cur].Mid(4);
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\cqdialogue \cd'%s'\cq:\c-",sdlg);
indlg = true;
nseq = 1;
cur++;
continue;
}
ThrowAbortException("line %d, expected 'DLG' directive",cur+1);
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 %d has no name.",sdlg,cur+1,nseq);
if ( scnt <= 0 ) ThrowAbortException("dialogue '%s', line %d, sequence %d has invalid count.",sdlg,cur+1,nseq);
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY," \cqsequence \cd%d\cq with character \cd'%s'\cq, name \cd'%s'\cq:\c-",nseq,schr,sname);
if ( sdelay > 0 ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY," \cqdelay: \cd%d\c-",sdelay);
if ( sstartdelay > 0 ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY," \cqstartdelay: \cd%d\c-",sstartdelay);
if ( senddelay > 0 ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY," \cqenddelay: \cd%d\c-",senddelay);
if ( schardelay > 0 ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY," \cqchardelay: \cd%d\c-",schardelay);
if ( spausedelay > 0 ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY," \cqpausedelay: \cd%d\c-",spausedelay);
if ( sznvspecial ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY," \cq+\cdznvspecial\c-");
if ( sindirect ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY," \cq+\cdindirect\c-");
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY," \cqcount: \cd%d\c-\n\cd---\c-",scnt);
for ( int i=0; i<scnt; i++ )
{
String ln = StringTable.Localize("$SWWM_"..sname..(i+1));
if ( (i == 1) && sznvspecial )
{
int nyears = SystemTime.Format("%Y",SystemTime.Now()).ToInt()-2010;
ln = String.Format(ln,nyears);
}
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"%s\n\cd---\c-",ln);
}
gotseq = true;
inseq = false;
nseq++;
}
else if ( lines[cur].Left(5) == "NAME " )
{
if ( sname != "" ) ThrowAbortException("dialogue '%s', line %d, sequence %d, duplicate 'NAME' parameter.",sdlg,cur+1,nseq);
sname = lines[cur].Mid(5);
}
else if ( lines[cur].Left(4) == "CNT " )
{
if ( scnt > 0 ) ThrowAbortException("dialogue '%s', line %d, sequence %d, duplicate 'CNT' parameter.",sdlg,cur+1,nseq);
scnt = lines[cur].Mid(4).ToInt();
}
else if ( lines[cur].Left(6) == "DELAY " )
{
if ( sdelay > 0 ) ThrowAbortException("dialogue '%s', line %d, sequence %d, duplicate 'DELAY' parameter.",sdlg,cur+1,nseq);
sdelay = lines[cur].Mid(6).ToInt();
}
else if ( lines[cur].Left(11) == "STARTDELAY " )
{
if ( sstartdelay > 0 ) ThrowAbortException("dialogue '%s', line %d, sequence %d, duplicate 'STARTDELAY' parameter.",sdlg,cur+1,nseq);
sstartdelay = lines[cur].Mid(11).ToInt();
}
else if ( lines[cur].Left(9) == "ENDDELAY " )
{
if ( senddelay > 0 ) ThrowAbortException("dialogue '%s', line %d, sequence %d, duplicate 'ENDDELAY' parameter.",sdlg,cur+1,nseq);
senddelay = lines[cur].Mid(9).ToInt();
}
else if ( lines[cur].Left(10) == "CHARDELAY " )
{
if ( schardelay > 0 ) ThrowAbortException("dialogue '%s', line %d, sequence %d, duplicate 'CHARDELAY' parameter.",sdlg,cur+1,nseq);
schardelay = lines[cur].Mid(10).ToInt();
}
else if ( lines[cur].Left(11) == "PAUSEDELAY " )
{
if ( spausedelay > 0 ) ThrowAbortException("dialogue '%s', line %d, sequence %d, duplicate 'PAUSEDELAY' parameter.",sdlg,cur+1,nseq);
spausedelay = lines[cur].Mid(11).ToInt();
}
else if ( lines[cur].Left(8) == "INDIRECT" )
{
if ( sindirect ) ThrowAbortException("dialogue '%s', line %d, sequence %d, duplicate 'INDIRECT' parameter.",sdlg,cur+1,nseq);
sindirect = true;
}
else if ( lines[cur].Left(10) == "ZNVSPECIAL" )
{
if ( sznvspecial ) ThrowAbortException("dialogue '%s', line %d, sequence %d, duplicate 'ZNVSPECIAL' parameter.",sdlg,cur+1,nseq);
sznvspecial = true;
}
else ThrowAbortException("dialogue '%s', line %d, sequence %d, parameter not recognized",sdlg,cur+1,nseq);
cur++;
continue;
}
if ( lines[cur].Left(4) == "SEQ " )
{
// begin dialogue
inseq = true;
schr = lines[cur].Mid(4);
// 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",sdlg,cur+1);
return;
}
if ( indlg ) ThrowAbortException("line %d, premature end of file reached for dialogue '%s'",cur+1,sdlg);
if ( inseq ) ThrowAbortException("dialogue '%s', line %d, premature end of file reached for sequence %d",sdlg,cur+1,nseq);
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\ce-- END OF FILE \cf'%s'\ce...\c-",Wads.GetLumpFullName(lmp));
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"");
}
}
else if ( e.Name ~== "swwmdumpmonsters" )
{
int i = 0;
bool bLastVanilla = false;
foreach ( cls:AllActorClasses )
{
if ( cls.IsAbstract() ) continue;
if ( cls == 'ChexSoul' ) // last defined in gzdoom.pk3
{
bLastVanilla = true;
continue;
}
if ( !bLastVanilla ) continue;
let def = GetDefaultByType(cls);
if ( !def.bISMONSTER && !def.bCOUNTKILL ) continue;
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"%s [%s]",def.GetClassName(),def.GetTag("NO TAG"));
i++;
}
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\n%d estimated monsters defined.",i);
}
}
override void NetworkProcess( ConsoleEvent e )
{
if ( e.IsManual ) return;
if ( e.Name.Left(16) ~== "swwmachievement." )
{
let c = Actor.Spawn("PartyTime",players[e.Args[0]].mo.pos);
c.bSTANDSTILL = true;
if ( e.Args[0] == consoleplayer )
{
c.A_StartSound("misc/achievement",CHAN_ITEM,CHANF_UI|CHANF_OVERLAP,attenuation:0.);
c.A_StartSound("misc/achievement2",CHAN_VOICE,CHANF_UI|CHANF_OVERLAP,attenuation:0.);
}
else
{
Console.Printf(String.Format(StringTable.Localize("$SWWM_CHEEVOREM"),players[e.Args[0]].GetUserName(),StringTable.Localize(e.Name.Mid(16))));
c.A_StartSound("misc/achievement",CHAN_ITEM,CHANF_UI|CHANF_OVERLAP);
c.A_StartSound("misc/achievement2",CHAN_ITEM,CHANF_UI|CHANF_OVERLAP);
}
}
else if ( e.Name ~== "swwmsessionid" )
{
let ti = ThinkerIterator.Create("SWWMSaveVerData",Thinker.STAT_STATIC);
let svd = SWWMSaveVerData(ti.Next());
if ( !uid ) uid = e.Args[0];
if ( svd && !svd.uid ) svd.uid = e.Args[0];
}
}
override void PostUiTick()
{
if ( !uid ) EventHandler.SendNetworkEvent("swwmsessionid",SystemTime.Now());
if ( gamestate != GS_TITLELEVEL ) titlefirst = true; // we skip it
if ( (gametic > 0) && !(gametic%GameTicRate) )
{
let pt = CVar.FindCVar('swwm_playtime');
int ct = pt.GetInt();
pt.SetInt(ct+1);
}
if ( gamestate != GS_LEVEL ) return;
CheckAllAchievements();
if ( gametic != checktic ) return;
String cver = StringTable.Localize("$SWWM_SHORTVER");
if ( tainted )
{
let ti = ThinkerIterator.Create("SWWMSaveVerData",Thinker.STAT_STATIC);
let svd = SWWMSaveVerData(ti.Next());
if ( !svd ) Console.Printf("\cgWARNING:\n \cjSave contains no version data. Issues may happen.\c-");
else
{
Console.Printf("\cgWARNING:\n \cjVersion mismatch with save data. Issues may happen.\c-");
Console.Printf("\cgSaved:\n \cj"..svd.ver.."\c-");
Console.Printf("\cgCurrent:\n \cj"..cver.."\c-");
}
}
}
override void UiTick()
{
// Fancy crash effect
if ( (gamestate == GS_LEVEL) || (gamestate == GS_TITLELEVEL) )
{
wasinmap = true;
timer = 0;
}
else if ( (gamestate == GS_FULLCONSOLE) && ((wasinmap && !players[consoleplayer].viewheight) || (timer > 0)) )
{
wasinmap = false;
if ( timer == 1 )
{
msgpick = Random[UIStuff](1,8);
String str = StringTable.Localize("$CRASHMSG"..msgpick.."A");
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\cf%s\c-",str);
let hnd = SWWMBrutalHandler(StaticEventHandler.Find("SWWMBrutalHandler"));
if ( hnd && hnd.detected )
{
S_StartSound("crash/glass",CHAN_YABLEWIT,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE);
S_StartSound("crash/glass",CHAN_YABLEWIT,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE);
}
else S_StartSound("crash/crash",CHAN_YABLEWIT,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE);
}
else if ( timer == 70 )
{
String str = StringTable.Localize("$CRASHMSG"..msgpick.."B");
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\cf%s\c-",str);
S_StartSound("crash/curb",CHAN_YABLEWIT,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE);
}
else if ( timer == 140 )
{
if ( isbd ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\cfYou shouldn't have tried running this with Brutal Doom.\c-");
else Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\cfYou should probably screenshot this error and show it to Marisa.\c-");
Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\cfLoaded Version:\n \cj%s\c-",StringTable.Localize("$SWWM_SHORTVER"));
if ( tainted ) Console.PrintfEx(PRINT_HIGH|PRINT_NONOTIFY,"\cfSavegame Version:\n \cj%s\c-",taintver);
}
timer++;
}
}
}