swwmgz_m/zscript/menu/swwm_title.zsc
Marisa the Magician 80db58b0d0 Bump zscript ver to 4.14.1, plus a whole lot of stuff.
- 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.
2025-03-13 14:50:58 +01:00

352 lines
14 KiB
Text

// Things for the titlemap
Struct TitleExplosion
{
bool bInit;
int frame;
Vector2 pos;
double scale;
bool flipx, flipy;
double angle;
}
Class SWWMTitleStuff : EventHandler
{
ui bool bInitialized;
ui TextureID tex[6];
ui TextureID letters[13];
ui Canvas lfade;
ui BrokenLines stitle;
ui Array<String> scrolls;
ui int sline;
ui double sbase;
ui String lastlang, lastlang2;
ui TitleExplosion smk[64];
ui TextureID smk_frame[19];
ui int titletimer;
ui int rss;
ui int stopinit_t;
ui bool bFadeIn;
ui Font mSmallFont, mBigFont;
private ui int GetUIRandom()
{
return (rss = (rss<<1)*35447+(rss/87));
}
private ui double RandomShiver()
{
int sd = GetUIRandom();
return ((abs(sd)%11)-5)*.1;
}
private ui void TickExplosions()
{
if ( stopinit_t > 0 ) stopinit_t--;
bool stopinit = (stopinit_t>0);
for ( int i=0; i<64; i++ )
{
if ( (!smk[i].bInit && !stopinit) || (smk[i].frame > 18) )
{
smk[i].frame = Random[UIStuff](smk[i].bInit?-20:-4,0);
smk[i].pos = (FRandom[UIStuff](0.,1.),FRandom[UIStuff](0.,1.));
smk[i].scale = FRandom[UIStuff](3.,6.);
smk[i].angle = FRandom[UIStuff](0.,360.);
smk[i].flipx = Random[UIStuff](0,1);
smk[i].flipy = Random[UIStuff](0,1);
if ( !smk[i].bInit )
{
smk[i].bInit = true;
stopinit = true;
stopinit_t = 4;
}
}
if ( !smk[i].bInit ) continue;
if ( (smk[i].frame == 0) && (titletimer < -20 ) )
S_StartSound("title/explo",CHAN_WEAPON,CHANF_UI|CHANF_OVERLAP,.35,ATTN_NONE,FRandom[UIStuff](.95,1.05));
smk[i].frame++;
}
}
override void UiTick()
{
// you're not supposed to be here
if ( gamestate == GS_LEVEL )
ThrowAbortException("Attempted to warp into TITLEMAP");
if ( !bInitialized )
{
bInitialized = true;
titletimer = -300;
// birthday event
if ( SystemTime.Format("%d%m",SystemTime.Now()) == "2001" )
titletimer = -500;
let shnd = SWWMStaticHandler(StaticEventHandler.Find('SWWMStaticHandler'));
if ( shnd )
{
if ( shnd.titlefirst )
{
titletimer = GameTicRate*22; // skip to logo
S_ChangeMusic("music/TRAUMATI.XM",1); // skip to order 1
bFadeIn = true;
}
shnd.titlefirst = true;
}
}
if ( swwm_nointroex && (titletimer >= -300) && (titletimer < 0) ) titletimer = 0;
if ( titletimer == -250 )
{
// this would be much simpler if we had a way to access the mapinfo variable
// (obviously, with this naive method, any custom music that doesn't use the
// vanilla filename won't be used)
if ( gameinfo.gametype&GAME_Hexen ) S_ChangeMusic("HEXEN");
else if ( gameinfo.gametype&GAME_Heretic ) S_ChangeMusic("MUS_TITL");
else
{
// check if the doom 1 music exists
if ( Wads.FindLump("D_INTRO",ns:wads.ns_music) != -1 )
S_ChangeMusic("D_INTRO");
else S_ChangeMusic("D_DM2TTL");
}
}
if ( titletimer == -75 ) S_ChangeMusic("");
if ( (titletimer > -80) && (titletimer < -20) ) TickExplosions();
if ( titletimer == 0 ) S_ChangeMusic("music/TRAUMATI.XM");
// title lettering
if ( ((double(titletimer)/GameTicRate) >= 23.) && ((double(titletimer)/GameTicRate) <= 25.4) && !(titletimer%5) )
S_StartSound("title/thump",CHAN_WEAPON,CHANF_UI|CHANF_OVERLAP,1.,ATTN_NONE);
titletimer++;
EventHandler.SendNetworkEvent("swwmtitle.timer",titletimer);
if ( menuactive && (titletimer < -80) && (titletimer >= -300) ) titletimer = -80;
}
private ui void RenderExplosions()
{
for ( int i=0; i<64; i++ )
{
int frm = smk[i].frame;
if ( (frm < 0) || (frm > 18) ) continue;
if ( !smk_frame[frm] ) smk_frame[frm] = TexMan.CheckForTexture(String.Format("XEX0%c0",0x41+frm),TexMan.Type_Sprite);
Vector2 vpos;
vpos.x = smk[i].pos.x*Screen.GetWidth();
vpos.y = smk[i].pos.y*Screen.GetHeight();
Screen.DrawTexture(smk_frame[frm],false,vpos.x,vpos.y,DTA_ScaleX,smk[i].scale*CleanXFac,DTA_ScaleY,smk[i].scale*CleanYFac,DTA_FlipX,smk[i].flipx,DTA_FlipY,smk[i].flipy,DTA_Rotate,smk[i].angle,DTA_LegacyRenderStyle,STYLE_Add);
}
}
override void RenderUnderlay( RenderEvent e )
{
if ( !mSmallFont ) mSmallFont = Font.GetFont('TewiFont');
if ( !mBigFont ) mBigFont = Font.GetFont('TewiFontOutline');
if ( !lfade ) lfade = TexMan.GetCanvas("LOGOFADE");
if ( !tex[2] ) tex[2] = TexMan.CheckForTexture("graphics/tempbg.png");
if ( !tex[5] ) tex[5] = TexMan.CheckForTexture("graphics/DemoIcon.png");
Vector2 tsize, vsize;
if ( titletimer < -300 )
{
Screen.Dim(0xFF000000,1.,0,0,Screen.GetWidth(),Screen.GetHeight());
double alf;
if ( titletimer < -420 ) alf = clamp((titletimer+450)/30.,0.,1.);
else if ( titletimer > -330 ) alf = clamp(1.-(titletimer+330)/30.,0.,1.);
else alf = 1.;
double xx, yy;
Screen.DrawTexture(tex[5],false,Screen.GetWidth()/2,Screen.GetHeight()/2,DTA_CleanNoMove_1,true,DTA_Alpha,alf);
String str = "2148-01-20";
xx = int(Screen.GetWidth()-mBigFont.StringWidth(str)*CleanXFac_1*3.)/2;
yy = Screen.GetHeight()/2-(72.+mBigFont.GetHeight()*3.)*CleanYFac_1;
Screen.DrawText(mBigFont,Font.CR_WHITE,xx,yy,str,DTA_Alpha,alf,DTA_ScaleX,CleanXFac_1*3.,DTA_ScaleY,CleanYFac_1*3.);
str = "Happy Birthday, \cdDemo-chan\c-!";
xx = int(Screen.GetWidth()-mBigFont.StringWidth(str)*CleanXFac_1*2.)/2;
yy = Screen.GetHeight()/2+72.*CleanYFac_1;
Screen.DrawText(mBigFont,Font.CR_WHITE,xx,yy,str,DTA_Alpha,alf,DTA_ScaleX,CleanXFac_1*2.,DTA_ScaleY,CleanYFac_1*2.);
return;
}
if ( !tex[3] ) tex[3] = TexMan.CheckForTexture((gameinfo.gametype&GAME_Raven)?"TITLE":"TITLEPIC",TexMan.Type_MiscPatch);
if ( titletimer < 0 )
{
Screen.Dim(0xFF000000,1.,0,0,Screen.GetWidth(),Screen.GetHeight());
if ( titletimer < -20 )
{
rss = int(MSTime()*(GameTicRate/1000.));
Vector2 ofs = (RandomShiver(),RandomShiver())*clamp((80+titletimer+e.FracTic)/50.,0.,1.);
tsize = TexMan.GetScaledSize(tex[3]);
ofs *= tsize.y/10.;
Screen.DrawTexture(tex[3],true,ofs.x,ofs.y,DTA_VirtualWidthF,tsize.x,DTA_VirtualHeightF,tsize.y,DTA_FullscreenScale,FSMode_ScaleToFit43,DTA_TopLeft,true);
RenderExplosions();
}
if ( titletimer > -20 ) Screen.Dim(0xFFFFFFFF,1.-clamp((20+titletimer+e.FracTic)/20.,0.,1.),0,0,Screen.GetWidth(),Screen.GetHeight());
else if ( titletimer > -80 ) Screen.Dim(0xFFFFFFFF,clamp((80+titletimer+e.FracTic)/50.,0.,1.),0,0,Screen.GetWidth(),Screen.GetHeight());
if ( titletimer <= -250 ) Screen.Dim(0xFF000000,1.-clamp((270+titletimer+e.FracTic)/20.,0.,1.),0,0,Screen.GetWidth(),Screen.GetHeight());
return;
}
double GameSecs = (titletimer+e.FracTic)/GameTicRate;
if ( swwm_fuzz )
{
tsize = TexMan.GetScaledSize(tex[2]);
double zoom = max(ceil(Screen.GetWidth()/tsize.x),ceil(Screen.GetHeight()/tsize.y));
vsize = (Screen.GetWidth(),Screen.GetHeight())/zoom;
Screen.DrawTexture(tex[2],false,(vsize.x-tsize.x)/2,(vsize.y-tsize.y)/2,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true,DTA_ColorOverlay,Color(192,0,0,0));
Screen.Dim(0xFF000000,clamp(1.-GameSecs*.05,0.,1.),0,0,Screen.GetWidth(),Screen.GetHeight());
}
else Screen.Dim(0xFF000000,1.,0,0,Screen.GetWidth(),Screen.GetHeight());
double hs = max(min(floor(Screen.GetWidth()/320.),floor(Screen.GetHeight()/200.)),1.);
Vector2 ss = (Screen.GetWidth(),Screen.GetHeight())/hs;
Render_NewTitle(e,GameSecs);
if ( GameSecs < 30 ) return;
// scrolls
if ( (scrolls.Size() <= 0 ) || (lastlang != language) )
{
scrolls.Clear();
int nstr = StringTable.Localize("$SWWM_NTITLESCROLL").ToInt();
for ( int i=1; i<=nstr; i++ ) scrolls.Push(StringTable.Localize("$SWWM_TITLESCROLL"..i));
sbase = GameSecs;
if ( sline >= scrolls.Size() ) sline = 0;
}
lastlang = language;
// estimate scroll length
double llen = mSmallFont.StringWidth(scrolls[sline]);
double soffset = 40*(GameSecs-sbase);
if ( soffset > llen+ss.x )
{
sline++;
if ( sline >= scrolls.Size() ) sline = 0;
sbase = GameSecs;
soffset = 0;
}
double xx = ss.x-soffset;
int tlen = scrolls[sline].CodePointCount();
double alf;
for ( int i=0, pos=0; i<tlen; i++ )
{
int ch;
[ch, pos] = scrolls[sline].GetNextCodePoint(pos);
if ( (xx > -8) && (xx < ss.x) )
{
for ( double trl = .1; trl < 1.; trl += .04 )
{
double yy = (ss.y-35)+10*sin(15*i+160*GameSecs-90.*(1.-trl));
alf = max(0,1.-abs((ss.x/2)-xx)/(ss.x/2))**.5;
alf *= .2*trl;
double xxofs = 5*sin(15*i+120*GameSecs-90.*(1.-trl))-16*(1.-trl);
Screen.DrawChar(mSmallFont,Font.CR_BLUE,xx-xxofs,yy,ch,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alf,DTA_LegacyRenderStyle,STYLE_Add);
}
double yy = (ss.y-35)+10*sin(15*i+160*GameSecs);
alf = max(0,1.-abs((ss.x/2)-xx)/(ss.x/2))**.5;
double xxofs = 5*sin(15*i+120*GameSecs);
Color c = Color(int(127.5+127.5*sin(10*i+80*GameSecs)),0,0);
Screen.DrawChar(mSmallFont,Font.CR_SAPPHIRE,xx-xxofs,yy,ch,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_Alpha,alf);
}
xx += mSmallFont.GetCharWidth(ch)+mSmallFont.GetDefaultKerning();
}
}
private ui void Render_NewTitle( RenderEvent e, double GameSecs )
{
if ( !tex[4] ) tex[4] = TexMan.CheckForTexture("graphics/NewLogo.png");
for ( int i=0; i<13; i++ )
{
if ( !letters[i] ) letters[i] = TexMan.CheckForTexture("graphics/NewLogo_Letter"..i..".png");
}
double alf = clamp(GameSecs-1,0.,1.);
alf *= 1.-clamp(GameSecs-4,0.,1.);
String str = StringTable.Localize("$SWWM_TITLEPRESENTSA");
Screen.DrawText(mSmallFont,Font.CR_SAPPHIRE,(Screen.GetWidth()-mSmallFont.StringWidth(str)*CleanXFac)/2,(Screen.GetHeight()/2)-(mSmallFont.GetHeight()*CleanYFac),str,DTA_CleanNoMove,true,DTA_Alpha,alf);
str = StringTable.Localize("$SWWM_TITLEPRESENTSB");
Screen.DrawText(mSmallFont,Font.CR_WHITE,(Screen.GetWidth()-mSmallFont.StringWidth(str)*CleanXFac)/2,(Screen.GetHeight()/2),str,DTA_CleanNoMove,true,DTA_Alpha,alf);
alf = clamp(GameSecs-5,0.,1.);
alf *= 1.-clamp(GameSecs-8,0.,1.);
str = StringTable.Localize("$SWWM_TITLEMODBYA");
Screen.DrawText(mSmallFont,Font.CR_WHITE,(Screen.GetWidth()-mSmallFont.StringWidth(str)*CleanXFac)/2,(Screen.GetHeight()/2)-(mSmallFont.GetHeight()*CleanYFac),str,DTA_CleanNoMove,true,DTA_Alpha,alf);
str = StringTable.Localize("$SWWM_TITLEMODBYB");
Screen.DrawText(mSmallFont,Font.CR_SAPPHIRE,(Screen.GetWidth()-mSmallFont.StringWidth(str)*CleanXFac)/2,(Screen.GetHeight()/2),str,DTA_CleanNoMove,true,DTA_Alpha,alf);
alf = clamp(GameSecs-10,0.,1.);
alf *= 1.-clamp(GameSecs-21,0.,1.);
str = StringTable.Localize("$SWWM_TITLEINTROA");
Screen.DrawText(mSmallFont,Font.CR_WHITE,(Screen.GetWidth()-mSmallFont.StringWidth(str)*CleanXFac)/2,(Screen.GetHeight()/2)-(mSmallFont.GetHeight()*CleanYFac*3)/2,str,DTA_CleanNoMove,true,DTA_Alpha,alf);
str = StringTable.Localize("$SWWM_TITLEINTROB");
Screen.DrawText(mSmallFont,Font.CR_WHITE,(Screen.GetWidth()-mSmallFont.StringWidth(str)*CleanXFac)/2,(Screen.GetHeight()/2)-(mSmallFont.GetHeight()*CleanYFac)/2,str,DTA_CleanNoMove,true,DTA_Alpha,alf);
str = StringTable.Localize("$SWWM_TITLEINTROC");
Screen.DrawText(mSmallFont,Font.CR_WHITE,(Screen.GetWidth()-mSmallFont.StringWidth(str)*CleanXFac)/2,(Screen.GetHeight()/2)+(mSmallFont.GetHeight()*CleanYFac)/2,str,DTA_CleanNoMove,true,DTA_Alpha,alf);
double ar = Screen.GetAspectRatio();
Vector2 tsize = TexMan.GetScaledSize(tex[4]);
double sar = tsize.x/tsize.y;
Vector2 vsize;
if ( sar > ar ) vsize = (tsize.x,tsize.x/ar);
else if ( sar < ar ) vsize = (tsize.y*ar,tsize.y);
else vsize = tsize;
if ( GameSecs < 22 ) return;
double alf1 = clamp((GameSecs-26.5)*.5,0.,1.);
double alf2 = (GameSecs>28)?clamp((GameSecs-3)%5,0.,1.):0.;
lfade.Clear(0,0,4,4,Color(int(255*alf1),int(255*alf2),0));
if ( bFadeIn ) Screen.Dim(0xFF000000,1.-clamp(GameSecs-22,0.,1.),0,0,Screen.GetWidth(),Screen.GetHeight());
if ( GameSecs < 27 )
{
static const int lofs[] =
{
153, 311, 489, 690, 844, 946, 1065, 1186, 1319, 1493, 1626, 1754, 1910
};
// draw letters one by one
double alph = 1.-clamp(GameSecs-26.5,0.,1.);
for ( int i=0; i<13; i++ )
{
if ( GameSecs < (23.+i*.2) ) continue;
double alf = 1.-clamp((GameSecs-(23+i*.2))*5.,0.,1.);
double zoom = 1.+.2*alf;
Screen.DrawTexture(letters[i],false,(vsize.x-tsize.x)/2+lofs[i],(vsize.y-tsize.y)/2+513,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true,DTA_ScaleX,zoom,DTA_ScaleY,zoom,DTA_ColorOverlay,Color(int(128*(alf**2)),255,255,255),DTA_Alpha,alph);
}
}
if ( GameSecs > 25 )
{
alf = clamp(GameSecs-25.5,0.,1.);
Screen.DrawTexture(tex[4],false,(vsize.x-tsize.x)/2,(vsize.y-tsize.y)/2,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true,DTA_Alpha,alf);
}
double scl = Screen.GetHeight()/vsize.y;
double tscl1 = max(1.,floor((Screen.GetHeight()*4.)/vsize.y)+3.);
str = "CODENAME";
alf = clamp(GameSecs-22,0.,1.);
Screen.DrawText(mBigFont,Font.CR_SAPPHIRE,int(Screen.GetWidth()-tscl1*mBigFont.StringWidth(str))/2,int(Screen.GetHeight()-(scl*400+mBigFont.GetHeight()*tscl1))/2,str,DTA_ScaleX,tscl1,DTA_ScaleY,tscl1,DTA_Alpha,alf);
double tscl2 = max(1.,floor((Screen.GetHeight()*4.)/vsize.y));
if ( !stitle || (lastlang2 != language) )
{
Array<String> done;
Array<int> candidates;
let c = CVar.FindCVar('swwm_titlesubhistory');
String cstr = c.GetString();
int which = 1;
if ( cstr != "" )
{
cstr.Split(done,";");
int nsub = StringTable.Localize("$SWWM_NTITLESUB").ToInt();
for ( int i=1; i<=nsub; i++ )
{
String sn = String.Format("%d",i);
if ( done.Find(sn) < done.Size() ) continue;
candidates.Push(i);
}
if ( candidates.Size() == 0 ) c.SetString("1");
else
{
which = candidates[Random[UIStuff](0,candidates.Size()-1)];
c.SetString(cstr..";"..which);
}
}
else c.SetString("1");
if ( stitle ) stitle.Destroy();
stitle = mBigFont.BreakLines(StringTable.Localize("$SWWM_TITLESUB"..which),int.max);
}
lastlang2 = language;
alf = clamp(GameSecs-27,0.,1.);
double xx;
double yy = int(Screen.GetHeight()+(scl*360+(1.-alf)*80*tscl2))/2;
for ( int i=0; i<stitle.Count(); i++ )
{
xx = int(Screen.GetWidth()-tscl2*mBigFont.StringWidth(stitle.StringAt(i)))/2;
Screen.DrawText(mBigFont,Font.CR_SAPPHIRE,xx,yy,stitle.StringAt(i),DTA_ScaleX,tscl2,DTA_ScaleY,tscl2,DTA_Alpha,alf);
yy += int(tscl2*mBigFont.GetHeight());
}
if ( (GameSecs >= 23.) && (GameSecs < 25.6) )
{
double alf = 1.-SWWMUtility.fract(GameSecs*5.);
Screen.Dim(0xFFFFFFFF,.05*alf,0,0,Screen.GetWidth(),Screen.GetHeight());
}
}
}