// 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; String bdname; // 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 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 officially supported, desyncs and other issues may potentially happen. You are on your own."); S_StartSound("compat/warn",CHAN_YABLEWIT,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE); } // sanity check Array stinkers; if ( !sti ) sti = ThinkerIterator.Create("SWWMStaticThinker"); else sti.Reinit(); Thinker t; while ( t = sti.Next() ) stinkers.Push(t); if ( stinkers.Size() > 0 ) { foreach ( s:stinkers ) Console.Printf("%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= 2.) ) mmz = 2.; else if ( mmz >= 1. ) mmz = 1.; else mmz = .5; CVar.FindCVar('swwm_mm_zoom').SetFloat(mmz); 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(); } override void OnRegister() { // fix voice type cvar int lmp; Array types; for ( lmp = Wads.FindLumpFullName("swwmvoicepack",0,true); lmp != -1; lmp = Wads.FindLumpFullName("swwmvoicepack",lmp+1,true) ) { Array 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 fonts; for ( lmp = Wads.FindLumpFullName("precachefonts",0,true); lmp != -1; lmp = Wads.FindLumpFullName("precachefonts",lmp+1,true) ) { Array 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 officially supported, desyncs and other issues may potentially happen. You are on your own."); 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.Printf( "\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 ~== "swwmflushud" ) { 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(SWWMDLG_FOOL); aprilfools = true; } else aprilfools = false; } } override void ConsoleProcess( ConsoleEvent e ) { if ( e.Name ~== "swwmresetmmcolors" ) { Array cvarlist; SWWMUtility.GetCVars(cvarlist); foreach ( cv:cvarlist ) { if ( (cv.Left(8) != "swwm_mm_") || (cv.IndexOf("color") == -1) || (cv == "swwm_mm_colorset") ) continue; CVar.FindCVar(cv).ResetToDefault(); } } else if ( e.Name ~== "swwmresetcvars" ) { Array 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 cvarlist; SWWMUtility.GetCVars(cvarlist); foreach ( cv:cvarlist ) { let rcv = CVar.FindCVar(cv); Console.Printf(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.Printf("No Data"); else Console.Printf(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.Printf("---STATE---"); let di = DictionaryIterator.Create(achievementstate); while ( di.Next() ) Console.Printf("%s = %s",di.Key(),di.Value()); Console.Printf("---PROGRESS---"); di = DictionaryIterator.Create(achievementprogress); while ( di.Next() ) Console.Printf("%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.Printf("\cj%s\c-",svd.ver); else Console.Printf("\cg(no version data)\c-"); if ( tainted ) Console.Printf("\cgversion mismatched\c-"); else Console.Printf("\cdversion not mismatched\c-"); } else if ( e.Name ~== "swwmdumpthinkers" ) { Array > sdefs; foreach ( cls : AllClasses ) { if ( !(cls is 'Thinker') || (cls is 'Actor') || (cls == 'Thinker') ) continue; sdefs.Push((Class)(cls)); } if ( !e.Args[0] ) { // trim default gzdoom thinkers for ( int i=0; i stink; stink.Resize(sdefs.Size()); for ( int i=Thinker.STAT_INFO; i= sdefs.Size() ) continue; stink[p]++; } ti.Destroy(); } for ( int i=0; i1)?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)(cls)):StaticEventHandler.Find((Class)(cls)); Console.Printf("%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 lst; lst.Clear(); String dat = Wads.ReadLump(lmp); dat.Split(lst,"\n",0); bool skipme = true; Console.Printf("[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.Printf("\cg%s [%d]\c-",l.Left(st-4),bl.Count()); fail = true; } bl.Destroy(); } if ( !fail ) Console.Printf("ALL OK"); lmp = Wads.FindLumpFullName("language.es_dlg"); lst.Clear(); dat = Wads.ReadLump(lmp); dat.Split(lst,"\n",0); skipme = true; Console.Printf("[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.Printf("\cg%s [%d]\c-",l.Left(st-4),bl.Count()); fail = true; } bl.Destroy(); } if ( !fail ) Console.Printf("ALL OK"); } } 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); Console.Printf("\cf%s\c-",StringTable.Localize("$CRASHMSG"..msgpick.."A")); 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 ) { Console.Printf("\cf%s\c-",StringTable.Localize("$CRASHMSG"..msgpick.."B")); S_StartSound("crash/curb",CHAN_YABLEWIT,CHANF_UI|CHANF_NOPAUSE|CHANF_OVERLAP,1,ATTN_NONE); } else if ( timer == 140 ) { if ( isbd ) Console.Printf("\cfYou shouldn't have tried running this with "..bdname..".\c-"); else Console.Printf("\cfYou should probably screenshot this error and show it to Marisa.\c-"); Console.Printf("\cfLoaded Version:\n \cj%s\c-",StringTable.Localize("$SWWM_SHORTVER")); if ( tainted ) Console.Printf("\cfSavegame Version:\n \cj%s\c-",taintver); } timer++; } } }