- Try to get rid of all implicit casts from string to name, color or class. - Use FindClass where needed. - Used a map in a case where a dictionary was unneeded. - Use new bounce flags where needed. - Replace Legacy of Rust weapons/ammo.
770 lines
26 KiB
Text
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 Map<String, String> 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++;
|
|
}
|
|
}
|
|
}
|
|
|