swwmgz_m/zscript/swwm_inter.zsc
Marisa Kirisame 163fdce33b Intermission displays for Coop and DM are now added.
Tweaks/fixes for dash slam and ground pound.
Score numbers will pop up in the world for count items, secrets, and others.
Fonts are now preloaded at launch, to reduce freezes. This obviously increases load times.
Berserk punches now have additional splash damage.
2020-04-26 18:26:36 +02:00

898 lines
32 KiB
Text

Class SWWMStatScreen : StatusScreen abstract
{
transient TextureID bgtex, arttex;
transient Font TewiFont, MPlusFont;
int whichart, whichtip;
transient CVar intertype, lang;
double hs, hs2;
Vector2 ss, ss2, origin, origin2;
// returns MPlus if we're playing in Japanese, otherwise returns the requested font
Font LangFont( Font req )
{
if ( !lang ) lang = CVar.GetCVar('language',players[consoleplayer]);
if ( lang.GetString() ~== "jp" ) return MPlusFont;
return req;
}
override void StartMusic()
{
S_ChangeMusic("music/DRAGONY.XM");
}
private void drawSWWMBg()
{
if ( !intertype ) intertype = CVar.GetCVar('swwm_intertype',players[consoleplayer]);
if ( !whichart )
{
int no = 0;
if ( intertype.GetInt() == 1 ) no = StringTable.Localize("$SWWM_NFANART").ToInt();
//else if ( intertype.GetInt() == 2 ) no = StringTable.Localize("$SWWM_N4KOMA").ToInt();
whichart = Random[InterArt](1,no);
}
if ( !bgtex ) bgtex = TexMan.CheckForTexture("graphics/InterBG.png",TexMan.Type_MiscPatch);
double ar = Screen.GetAspectRatio();
Vector2 tsize = TexMan.GetScaledSize(bgtex);
double sar = tsize.x/tsize.y;
Vector2 vsize;
if ( sar > ar ) vsize = (tsize.y*ar,tsize.y);
else if ( sar < ar ) vsize = (tsize.x,tsize.x/ar);
else vsize = tsize;
Screen.DrawTexture(bgtex,false,(vsize.x-tsize.x)/2,(vsize.y-tsize.y)/2,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true);
Font fnt = LangFont(TewiFont);
// background pics (fanart, 4komas)
if ( intertype.GetInt() == 1 )
{
String artstr = StringTable.Localize(String.Format("$SWWM_FANART%d",whichart));
int semic = artstr.IndexOf(";");
if ( !arttex ) arttex = TexMan.CheckForTexture(String.Format("graphics/Fanart/%s",artstr.Left(semic)),TexMan.Type_MiscPatch);
tsize = TexMan.GetScaledSize(arttex);
sar = tsize.x/tsize.y;
if ( sar > ar ) vsize = (tsize.y*ar,tsize.y);
else if ( sar < ar ) vsize = (tsize.x,tsize.x/ar);
else vsize = tsize;
Screen.DrawTexture(arttex,false,(vsize.x-tsize.x)/2,(vsize.y-tsize.y)/2,DTA_VirtualWidthF,vsize.x,DTA_VirtualHeightF,vsize.y,DTA_KeepRatio,true);
String bstr = String.Format("\cx%s\c- %s",StringTable.Localize("$SWWM_FANART"),artstr.Mid(semic+1));
int len = fnt.StringWidth(bstr);
int bw = int((len+8)*hs), bh = int((fnt.GetHeight()+4)*hs);
Screen.Dim("Black",.8,Screen.GetWidth()-bw,Screen.GetHeight()-bh,bw,bh);
Screen.DrawText(fnt,Font.CR_GOLD,ss.x-(len+4),ss.y-(fnt.GetHeight()+2),bstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
/*else if ( intertype.GetInt() == 2 )
{
// TBD when there's art
}*/
// intermission tips at the bottom
if ( !whichtip )
{
int maxtip = StringTable.Localize("$SWWM_NINTERTIP").ToInt();
whichtip = Random[InterArt](1,maxtip);
}
String tipstr = "\cd"..String.Format(StringTable.Localize("$SWWM_INTERTIP"),whichtip).."\c-\n"..StringTable.Localize(String.Format("$SWWM_INTERTIP%d",whichtip));
BrokenLines l = fnt.BreakLines(tipstr,300);
int bw = int(308*hs), bh = int((fnt.GetHeight()*l.Count()+12)*hs);
double xx = 10, yy = (ss.y-10)-(fnt.GetHeight()*l.Count()+4);
Screen.Dim("Black",.8,int((xx-4)*hs),int((yy-4)*hs),bw,bh);
for ( int i=0; i<l.Count(); i++ )
{
Screen.DrawText(fnt,Font.CR_WHITE,xx,yy,l.StringAt(i),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += fnt.GetHeight();
if ( !i ) yy += 4;
}
}
override int DrawLF()
{
Font fnt = LangFont(TewiFont);
int len[2];
len[0] = fnt.StringWidth(lnametexts[0]);
len[1] = fnt.StringWidth(authortexts[0]);
int dimlen = max(int((len[0]+8)*hs2),int((len[1]+8)*hs));
bool auth = (authortexts[0].Length()>0);
Screen.Dim("Black",.8,int((Screen.GetWidth()-dimlen)/2.),int(4*hs2),dimlen,int((fnt.GetHeight()+(auth?2:4))*hs2));
Screen.DrawText(fnt,Font.CR_GREEN,(ss2.x-len[0])/2.,6,lnametexts[0],DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
double foy = fnt.GetHeight()+(auth?6:8);
if ( auth )
{
double oy = foy*(hs2/hs);
Screen.Dim("Black",.8,int((Screen.GetWidth()-dimlen)/2.),int(oy*hs),dimlen,int((fnt.GetHeight()+2)*hs));
Screen.DrawText(fnt,Font.CR_WHITE,(ss.x-len[1])/2.,oy,authortexts[0],DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
foy += (fnt.GetHeight()+2)*(hs/hs2);
}
foy += 8.;
String str = StringTable.Localize("$WI_FINISHED");
len[0] = fnt.StringWidth(str);
Screen.Dim("Black",.8,int((ss2.x-len[0]-8)/2*hs2),int(foy*hs2),int((len[0]+8)*hs2),int((fnt.GetHeight()+4)*hs2));
Screen.DrawText(fnt,Font.CR_FIRE,(ss2.x-len[0])/2.,foy+2,str,DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
// return not used
return 0;
}
override void DrawEL()
{
Font fnt = LangFont(TewiFont);
String str = StringTable.Localize("$WI_ENTERING");
int len[2];
len[0] = fnt.StringWidth(str);
Screen.Dim("Black",.8,int((ss2.x-len[0]-8)/2*hs2),int(4*hs2),int((len[0]+8)*hs2),int((fnt.GetHeight()+4)*hs2));
Screen.DrawText(fnt,Font.CR_FIRE,(ss2.x-len[0])/2.,6,str,DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
double foy = fnt.GetHeight()+16;
len[0] = fnt.StringWidth(lnametexts[1]);
len[1] = fnt.StringWidth(authortexts[1]);
int dimlen = max(int((len[0]+8)*hs2),int((len[1]+8)*hs));
bool auth = (authortexts[1].Length()>0);
Screen.Dim("Black",.8,int((Screen.GetWidth()-dimlen)/2.),int(foy*hs2),dimlen,int((fnt.GetHeight()+(auth?2:4))*hs2));
Screen.DrawText(fnt,Font.CR_GREEN,(ss2.x-len[0])/2.,foy+2,lnametexts[1],DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
if ( auth )
{
double oy = (foy+fnt.GetHeight()+2)*(hs2/hs);
Screen.Dim("Black",.8,int((Screen.GetWidth()-dimlen)/2.),int(oy*hs),dimlen,int((fnt.GetHeight()+2)*hs));
Screen.DrawText(fnt,Font.CR_WHITE,(ss.x-len[1])/2.,oy,authortexts[1],DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
}
override void drawShowNextLoc( void )
{
drawSWWMBg();
drawEL();
}
override void Drawer( void )
{
if ( !TewiFont ) TewiFont = Font.GetFont('TewiShaded');
if ( !MPlusFont ) MPlusFont = Font.GetFont('MPlusShaded');
hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/400.)),1.);
hs2 = max(min(floor(Screen.GetWidth()/320.),floor(Screen.GetHeight()/200.)),1.);
ss = (Screen.GetWidth(),Screen.GetHeight())/hs;
ss2 = (Screen.GetWidth(),Screen.GetHeight())/hs2;
origin = (ss.x-640,ss.y-400)/2.;
origin2 = (ss2.x-320,ss2.y-200)/2.;
switch ( CurState )
{
case StatCount:
drawSWWMBg();
drawStats();
break;
case ShowNextLoc:
drawShowNextLoc();
break;
case LeavingIntermission:
break;
default:
drawNoState();
break;
}
}
protected String TimeStr( int secs )
{
secs = max(secs,0);
int h = secs/3600;
int m = (secs/60)%60;
int s = secs%60;
if ( h ) return String.Format("%d\cu:\c-%02d\cu:\c-%02d",h,m,s);
if ( m ) return String.Format("%d\cu:\c-%02d",m,s);
return String.Format("%d",s);
}
protected int GetPct( int a, int b, bool inv = false )
{
if ( a < 0 ) return 0;
if ( b <= 0 ) return inv?0:100; // for "missed" percentage
return (a*100)/b;
}
}
Class SWWMStatScreen_SP : SWWMStatScreen
{
int intermissioncounter;
override void initStats()
{
intermissioncounter = gameinfo.intermissioncounter;
CurState = StatCount;
acceleratestage = 0;
sp_state = 1;
cnt_kills[0] = cnt_items[0] = cnt_secret[0] = -1;
cnt_time = cnt_par = -1;
cnt_pause = Thinker.TICRATE;
cnt_total_time = -1;
}
override void updateStats()
{
if ( acceleratestage && (sp_state != 10) )
{
acceleratestage = 0;
sp_state = 10;
PlaySound("menu/buyinv");
cnt_kills[0] = Plrs[me].skills;
cnt_items[0] = Plrs[me].sitems;
cnt_secret[0] = Plrs[me].ssecret;
cnt_time = Thinker.Tics2Seconds(Plrs[me].stime);
cnt_par = wbs.partime/Thinker.TICRATE;
cnt_total_time = Thinker.Tics2Seconds(wbs.totaltime);
}
if ( sp_state == 2 )
{
if ( intermissioncounter )
{
cnt_kills[0] += max((Plrs[me].skills-cnt_kills[0])/10,2);
if ( !(bcnt%2) ) PlaySound("menu/demoscroll");
}
if ( !intermissioncounter || (cnt_kills[0] >= Plrs[me].skills) )
{
cnt_kills[0] = Plrs[me].skills;
PlaySound("menu/buyinv");
sp_state++;
}
}
else if ( sp_state == 4 )
{
if ( intermissioncounter )
{
cnt_items[0] += max((Plrs[me].sitems-cnt_items[0])/10,2);
if ( !(bcnt%2) ) PlaySound("menu/demoscroll");
}
if ( !intermissioncounter || (cnt_items[0] >= Plrs[me].sitems) )
{
cnt_items[0] = Plrs[me].sitems;
PlaySound("menu/buyinv");
sp_state++;
}
}
else if ( sp_state == 6 )
{
if ( intermissioncounter )
{
cnt_secret[0] += max((Plrs[me].ssecret-cnt_secret[0])/10,2);
if ( !(bcnt%2) ) PlaySound("menu/demoscroll");
}
if ( !intermissioncounter || (cnt_secret[0] >= Plrs[me].ssecret) )
{
cnt_secret[0] = Plrs[me].ssecret;
PlaySound("menu/buyinv");
sp_state++;
}
}
else if ( sp_state == 8 )
{
int sec = Thinker.Tics2Seconds(Plrs[me].stime);
int tsec = Thinker.Tics2Seconds(wbs.totaltime);
int psec = wbs.partime/Thinker.TICRATE;
if ( intermissioncounter )
{
if ( !(bcnt%2) ) PlaySound("menu/demoscroll");
cnt_time += max((sec-cnt_time)/10,3);
cnt_par += max((psec-cnt_par)/10,3);
cnt_total_time += max((tsec-cnt_total_time)/10,3);
}
if ( !intermissioncounter || (cnt_time >= sec) )
cnt_time = sec;
if ( !intermissioncounter || (cnt_total_time >= tsec) )
cnt_total_time = tsec;
if ( !intermissioncounter || (cnt_par >= psec) )
{
cnt_par = psec;
if ( cnt_time >= sec )
{
cnt_total_time = tsec;
PlaySound("menu/buyinv");
sp_state++;
}
}
}
else if ( sp_state == 10 )
{
if ( acceleratestage )
{
PlaySound("misc/w_pkup");
initShowNextLoc();
}
}
else if ( sp_state&1 )
{
if ( !--cnt_pause )
{
sp_state++;
cnt_pause = Thinker.TICRATE;
}
}
}
override void drawStats( void )
{
drawLF();
Font fnt = LangFont(TewiFont);
// estimate max width of the whole stat counter
int maxlen, maxlenl = 0, maxlenr = 0;
// left strings
String str = StringTable.Localize("$TXT_IMKILLS")..":";
int len = fnt.StringWidth(str);
maxlenl = len;
str = StringTable.Localize("$TXT_IMITEMS")..":";
len = fnt.StringWidth(str);
if ( len > maxlenl ) maxlenl = len;
str = StringTable.Localize("$TXT_IMSECRETS")..":";
len = fnt.StringWidth(str);
if ( len > maxlenl ) maxlenl = len;
str = StringTable.Localize("$TXT_IMTIME")..":";
len = fnt.StringWidth(str);
if ( len > maxlenl ) maxlenl = len;
if ( wi_showtotaltime )
{
str = StringTable.Localize("$SCORE_TOTAL")..":"; // hey, as long as it works
len = fnt.StringWidth(str);
if ( len > maxlenl ) maxlenl = len;
}
if ( wbs.partime )
{
str = StringTable.Localize("$TXT_IMPAR")..":";
len = fnt.StringWidth(str);
if ( len > maxlenl ) maxlenl = len;
}
// right strings
if ( wi_percents )
{
str = String.Format("%d%%",GetPct(Plrs[me].skills,wbs.maxkills));
len = fnt.StringWidth(str);
maxlenr = len;
str = String.Format("%d%%",GetPct(Plrs[me].sitems,wbs.maxitems));
len = fnt.StringWidth(str);
if ( len > maxlenr ) maxlenr = len;
str = String.Format("%d%%",GetPct(Plrs[me].ssecret,wbs.maxsecret));
len = fnt.StringWidth(str);
if ( len > maxlenr ) maxlenr = len;
}
else
{
str = String.Format("%d / %d",Plrs[me].skills,wbs.maxkills);
len = fnt.StringWidth(str);
maxlenr = len;
str = String.Format("%d / %d",Plrs[me].sitems,wbs.maxitems);
len = fnt.StringWidth(str);
if ( len > maxlenr ) maxlenr = len;
str = String.Format("%d / %d",Plrs[me].ssecret,wbs.maxsecret);
len = fnt.StringWidth(str);
if ( len > maxlenr ) maxlenr = len;
}
str = TimeStr(Thinker.Tics2Seconds(Plrs[me].stime));
len = fnt.StringWidth(str);
if ( len > maxlenr ) maxlenr = len;
if ( wi_showtotaltime )
{
str = TimeStr(Thinker.Tics2Seconds(wbs.totaltime));
len = fnt.StringWidth(str);
if ( len > maxlenr ) maxlenr = len;
}
if ( wbs.partime )
{
str = TimeStr(wbs.partime/Thinker.TICRATE);
len = fnt.StringWidth(str);
if ( len > maxlenr ) maxlenr = len;
}
int step = fnt.GetHeight()+1;
int nl = clamp(sp_state/2,0,4);
if ( (nl == 4) )
{
if ( wi_showtotaltime ) nl++;
if ( wbs.partime ) nl++;
}
nl *= step;
maxlen = maxlenl+max(100,maxlenr);
// draw the whole damn thing
if ( sp_state >= 2 ) Screen.Dim("Black",.8,int((ss2.x-maxlen-8)*.5*hs2),int((ss2.y-nl-8)*.5*hs2),int((maxlen+8)*hs2),int((nl+8)*hs2));
double xx = (ss2.x-maxlen)/2., yy = (ss2.y-nl)/2.;
if ( sp_state >= 2 ) Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,StringTable.Localize("$TXT_IMKILLS")..":",DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
yy += step;
if ( sp_state >= 4 ) Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,StringTable.Localize("$TXT_IMITEMS")..":",DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
yy += step;
if ( sp_state >= 6 ) Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,StringTable.Localize("$TXT_IMSECRETS")..":",DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
yy += step;
if ( sp_state >= 8 ) Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,StringTable.Localize("$TXT_IMTIME")..":",DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
yy += step;
if ( wi_showtotaltime )
{
if ( sp_state >= 8 ) Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,StringTable.Localize("$SCORE_TOTAL")..":",DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
yy += step;
}
if ( wbs.partime && (sp_state >= 8) ) Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,StringTable.Localize("$TXT_IMPAR")..":",DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
xx = (ss2.x+maxlen)/2.;
yy = (ss2.y-nl)/2.;
if ( wi_percents )
{
if ( cnt_kills[0] >= 0 )
{
str = String.Format("%d\cu%%\c-",GetPct(cnt_kills[0],wbs.maxkills));
len = fnt.StringWidth(str);
Screen.DrawText(fnt,(!wbs.maxkills||(cnt_kills[0]>=wbs.maxkills))?Font.CR_GOLD:Font.CR_WHITE,xx-len,yy,str,DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
}
yy += step;
if ( cnt_items[0] >= 0 )
{
str = String.Format("%d\cu%%\c-",GetPct(cnt_items[0],wbs.maxitems));
len = fnt.StringWidth(str);
Screen.DrawText(fnt,(!wbs.maxitems||(cnt_items[0]>=wbs.maxitems))?Font.CR_GOLD:Font.CR_WHITE,xx-len,yy,str,DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
}
yy += step;
if ( cnt_secret[0] >= 0 )
{
str = String.Format("%d\cu%%\c-",GetPct(cnt_secret[0],wbs.maxsecret));
len = fnt.StringWidth(str);
Screen.DrawText(fnt,(!wbs.maxsecret||(cnt_secret[0]>=wbs.maxsecret))?Font.CR_GOLD:Font.CR_WHITE,xx-len,yy,str,DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
}
yy += step;
}
else
{
if ( cnt_kills[0] >= 0 )
{
str = String.Format("%d \cu/\c- \cj%d\c-",max(cnt_kills[0],0),wbs.maxkills);
len = fnt.StringWidth(str);
Screen.DrawText(fnt,(wbs.maxkills&&(cnt_kills[0]>=wbs.maxkills))?Font.CR_GOLD:Font.CR_WHITE,xx-len,yy,str,DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
}
yy += step;
if ( cnt_items[0] >= 0 )
{
str = String.Format("%d \cu/\c- \cj%d\c-",max(cnt_items[0],0),wbs.maxitems);
len = fnt.StringWidth(str);
Screen.DrawText(fnt,(wbs.maxitems&&(cnt_items[0]>=wbs.maxitems))?Font.CR_GOLD:Font.CR_WHITE,xx-len,yy,str,DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
}
yy += step;
if ( cnt_secret[0] >= 0 )
{
str = String.Format("%d \cu/\c- \cj%d\c-",max(cnt_secret[0],0),wbs.maxsecret);
len = fnt.StringWidth(str);
Screen.DrawText(fnt,(wbs.maxsecret&&(cnt_secret[0]>=wbs.maxsecret))?Font.CR_GOLD:Font.CR_WHITE,xx-len,yy,str,DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
}
yy += step;
}
if ( cnt_time >= 0 )
{
str = TimeStr(cnt_time);
len = fnt.StringWidth(str);
Screen.DrawText(fnt,(wbs.partime&&(cnt_time<=(wbs.partime/Thinker.TICRATE)))?Font.CR_GOLD:(cnt_time>3600)?Font.CR_RED:Font.CR_WHITE,xx-len,yy,str,DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
}
yy += step;
if ( wi_showtotaltime )
{
if ( cnt_total_time >= 0 )
{
str = TimeStr(cnt_total_time);
len = fnt.StringWidth(str);
Screen.DrawText(fnt,Font.CR_WHITE,xx-len,yy,str,DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
}
yy += step;
}
if ( wbs.partime && (cnt_par >= 0) )
{
str = TimeStr(cnt_par);
len = fnt.StringWidth(str);
Screen.DrawText(fnt,Font.CR_WHITE,xx-len,yy,str,DTA_VirtualWidthF,ss2.x,DTA_VirtualHeightF,ss2.y,DTA_KeepRatio,true);
}
}
}
Class SWWMStatScreen_Coop : SWWMStatScreen
{
override void initStats()
{
CurState = StatCount;
acceleratestage = 0;
ng_state = 1;
cnt_pause = Thinker.TICRATE;
for ( int i=0; i<MAXPLAYERS; i++ )
{
playerready[i] = false;
cnt_kills[i] = cnt_items[i] = cnt_secret[i] = cnt_frags[i] = 0;
if ( !playeringame[i] ) continue;
dofrags += fragSum(i);
}
dofrags = !!dofrags;
}
override void updateStats()
{
int fsum;
bool stillticking;
bool autoskip = autoSkip();
if ( (acceleratestage || autoskip) && (ng_state != 10) )
{
acceleratestage = 0;
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
cnt_kills[i] = Plrs[i].skills;
cnt_items[i] = Plrs[i].sitems;
cnt_secret[i] = Plrs[i].ssecret;
if ( dofrags ) cnt_frags[i] = fragSum(i);
}
PlaySound("menu/buyinv");
ng_state = 10;
}
if ( ng_state == 2 )
{
if ( !(bcnt&2) ) PlaySound("menu/demoscroll");
stillticking = false;
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
cnt_kills[i] += max((Plrs[i].skills-cnt_kills[i])/10,2);
if ( cnt_kills[i] > Plrs[i].skills ) cnt_kills[i] = Plrs[i].skills;
else stillticking = true;
}
if ( !stillticking )
{
PlaySound("menu/buyinv");
ng_state++;
}
}
else if ( ng_state == 4 )
{
if ( !(bcnt&2) ) PlaySound("menu/demoscroll");
stillticking = false;
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
cnt_items[i] += max((Plrs[i].sitems-cnt_items[i])/10,2);
if ( cnt_items[i] > Plrs[i].sitems ) cnt_items[i] = Plrs[i].sitems;
else stillticking = true;
}
if ( !stillticking )
{
PlaySound("menu/buyinv");
ng_state++;
}
}
else if ( ng_state == 6 )
{
if ( !(bcnt&2) ) PlaySound("menu/demoscroll");
stillticking = false;
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
cnt_secret[i] += max((Plrs[i].ssecret-cnt_secret[i])/10,2);
if ( cnt_secret[i] > Plrs[i].ssecret ) cnt_secret[i] = Plrs[i].ssecret;
else stillticking = true;
}
if ( !stillticking )
{
PlaySound("menu/buyinv");
ng_state += 1+2*!dofrags;
}
}
else if ( ng_state == 8 )
{
if ( !(bcnt&2) ) PlaySound("menu/demoscroll");
stillticking = false;
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
fsum = fragSum(i);
cnt_frags[i] += max((fsum-cnt_frags[i])/10,1);
if ( cnt_frags[i] >= fsum ) cnt_frags[i] = fsum;
else stillticking = true;
}
if ( !stillticking )
{
PlaySound("menu/buyinv");
ng_state++;
}
}
else if ( ng_state == 10 )
{
int i;
for ( i=0; i<MAXPLAYERS; i++ )
{
// If the player is in the game and not ready, stop checking
if ( playeringame[i] && !players[i].Bot && !playerready[i] )
break;
}
// All players are ready; proceed.
if ( ((i == MAXPLAYERS) && acceleratestage) || autoskip )
{
PlaySound("misc/w_pkup");
initShowNextLoc();
}
}
else if ( ng_state&1 )
{
if ( !--cnt_pause )
{
ng_state++;
cnt_pause = Thinker.TICRATE;
}
}
}
override void drawStats( void )
{
drawLF();
Font fnt = LangFont(TewiFont);
int checkmark = 0x2714; // "✔", only available on Tewi
String namestr = StringTable.Localize("$SCORE_NAME");
String itemsstr = StringTable.Localize((gameinfo.gametype&GAME_Raven)?"$SCORE_BONUS":"$SCORE_ITEMS");
String secretstr = StringTable.Localize("$SCORE_SECRET");
String killsstr = StringTable.Localize("$SCORE_KILLS");
String missedstr = StringTable.Localize("$SCORE_MISSED");
String totalstr = StringTable.Localize("$SCORE_TOTAL");
int namelen = max(max(fnt.StringWidth(namestr),fnt.StringWidth("XXXXXXXXXX")),max(fnt.StringWidth(missedstr),fnt.StringWidth(totalstr)));
int nplayers = 0;
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
namelen = max(namelen,fnt.StringWidth(players[i].GetUserName()));
nplayers++;
}
int misseditems = wbs.maxitems;
int missedsecret = wbs.maxsecret;
int missedkills = wbs.maxkills;
String itemstotal = String.Format("%d",misseditems);
String secrettotal = String.Format("%d",missedsecret);
String killstotal = String.Format("%d",missedkills);
int itemslen = max(fnt.StringWidth("100%"),max(fnt.StringWidth(itemstotal),fnt.StringWidth(itemsstr)));
int secretlen = max(fnt.StringWidth("100%"),max(fnt.StringWidth(secrettotal),fnt.StringWidth(secretstr)));
int killslen = max(fnt.StringWidth("100%"),max(fnt.StringWidth(killstotal),fnt.StringWidth(killsstr)));
int pad = 4;
int spc = 12;
int lspc = 4;
int rwidth = TewiFont.GetCharWidth(checkmark)+4;
int ryofs = (fnt.GetHeight()-TewiFont.GetHeight())/2;
int linew = pad+rwidth+namelen+spc+itemslen+spc+secretlen+spc+killslen+pad;
int boxwidth = pad+linew+pad;
int lineh = fnt.GetHeight();
int boxheight = pad+lineh+spc+(lineh+lspc)*nplayers+spc+lineh+lspc+lineh+pad;
Screen.Dim("Black",.8,int((ss.x-boxwidth)*hs)/2,int((ss.y-boxheight)*hs)/2,int(boxwidth*hs),int(boxheight*hs));
// header
double xx = (ss.x-boxwidth)/2.+pad+pad+rwidth;
double yy = (ss.y-boxheight)/2.+pad;
Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,namestr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
xx += namelen+spc;
Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,itemsstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
xx += itemslen+spc;
Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,secretstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
xx += secretlen+spc;
Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,killsstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += lineh+spc;
String str;
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
xx = (ss.x-boxwidth)/2.+pad;
Screen.Dim(players[i].GetDisplayColor(),.4,int(xx*hs),int(yy*hs),int(linew*hs),int(lineh*hs));
xx += pad;
if ( playerready[i] || players[i].Bot ) Screen.DrawChar(TewiFont,Font.CR_GREEN,xx,yy+ryofs,checkmark,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
xx += rwidth;
Screen.DrawText(fnt,GetRowColor(players[i],i==consoleplayer),xx,yy,players[i].GetUserName(),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
xx += namelen+spc;
if ( ng_state >= 4 )
{
str = String.Format("%3d\cu%%\c-",GetPct(cnt_items[i],wbs.maxitems));
Screen.DrawText(fnt,(!wbs.maxitems||(cnt_items[i]>=wbs.maxitems))?Font.CR_GOLD:Font.CR_WHITE,xx+itemslen-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
misseditems -= cnt_items[i];
}
xx += itemslen+spc;
if ( ng_state >= 6 )
{
str = String.Format("%3d\cu%%\c-",GetPct(cnt_secret[i],wbs.maxsecret));
Screen.DrawText(fnt,(!wbs.maxsecret||(cnt_secret[i]>=wbs.maxsecret))?Font.CR_GOLD:Font.CR_WHITE,xx+secretlen-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
missedsecret -= cnt_secret[i];
}
xx += secretlen+spc;
str = String.Format("%3d\cu%%\c-",GetPct(cnt_kills[i],wbs.maxkills));
Screen.DrawText(fnt,(!wbs.maxkills||(cnt_kills[i]>=wbs.maxkills))?Font.CR_GOLD:Font.CR_WHITE,xx+killslen-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
missedkills -= cnt_kills[i];
yy += lineh+lspc;
}
xx = (ss.x-boxwidth)/2.+pad+pad+rwidth;
yy += spc;
Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,missedstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
xx += namelen+spc;
if ( ng_state >= 4 )
{
str = String.Format("%3d\cu%%\c-",GetPct(misseditems,wbs.maxitems,true));
Screen.DrawText(fnt,(wbs.maxitems&&(misseditems>0))?Font.CR_WHITE:Font.CR_GOLD,xx+itemslen-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
xx += itemslen+spc;
if ( ng_state >= 6 )
{
str = String.Format("%3d\cu%%\c-",GetPct(missedsecret,wbs.maxsecret,true));
Screen.DrawText(fnt,(wbs.maxsecret&&(missedsecret>0))?Font.CR_WHITE:Font.CR_GOLD,xx+secretlen-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
xx += secretlen+spc;
str = String.Format("%3d\cu%%\c-",GetPct(missedkills,wbs.maxkills,true));
Screen.DrawText(fnt,(wbs.maxkills&&(missedkills>0))?Font.CR_WHITE:Font.CR_GOLD,xx+killslen-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += lineh+lspc;
xx = (ss.x-boxwidth)/2.+pad+pad+rwidth;
Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,totalstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
xx += namelen+spc;
if ( ng_state >= 4 )
{
str = String.Format("%d",wbs.maxitems);
Screen.DrawText(fnt,Font.CR_WHITE,xx+itemslen-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
xx += itemslen+spc;
if ( ng_state >= 6 )
{
str = String.Format("%d",wbs.maxsecret);
Screen.DrawText(fnt,Font.CR_WHITE,xx+secretlen-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
xx += secretlen+spc;
str = String.Format("%d",wbs.maxkills);
Screen.DrawText(fnt,Font.CR_WHITE,xx+killslen-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
}
Class SWWMStatScreen_DM : SWWMStatScreen
{
override void initStats()
{
CurState = StatCount;
acceleratestage = 0;
for( int i=0; i<MAXPLAYERS; i++ )
{
playerready[i] = false;
cnt_frags[i] = cnt_deaths[i] = player_deaths[i] = 0;
}
total_frags = 0;
total_deaths = 0;
ng_state = 1;
cnt_pause = Thinker.TICRATE;
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
for ( int j=0; j<MAXPLAYERS; j++ )
{
if ( !playeringame[j] ) continue;
player_deaths[i] += Plrs[j].frags[i];
}
total_deaths += player_deaths[i];
total_frags += Plrs[i].fragcount;
}
}
override void updateStats()
{
bool stillticking;
bool doautoskip = autoSkip();
if ( (acceleratestage || doautoskip) && (ng_state != 6) )
{
acceleratestage = 0;
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
cnt_frags[i] = Plrs[i].fragcount;
cnt_deaths[i] = player_deaths[i];
}
PlaySound("menu/buyinv");
ng_state = 6;
}
if ( ng_state == 2 )
{
if ( !(bcnt&2) ) PlaySound("menu/demoscroll");
stillticking = false;
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
cnt_frags[i] += max((Plrs[i].fragcount-cnt_frags[i])/10,2);
if ( cnt_frags[i] > Plrs[i].fragcount ) cnt_frags[i] = Plrs[i].fragcount;
else stillticking = true;
}
if ( !stillticking )
{
PlaySound("menu/buyinv");
ng_state++;
}
}
else if ( ng_state == 4 )
{
if ( !(bcnt&2) ) PlaySound("menu/demoscroll");
stillticking = false;
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
cnt_deaths[i] += max((player_deaths[i]-cnt_deaths[i])/10,2);
if ( cnt_deaths[i] > player_deaths[i] ) cnt_deaths[i] = player_deaths[i];
else stillticking = true;
}
if ( !stillticking )
{
PlaySound("menu/buyinv");
ng_state++;
}
}
else if ( ng_state == 6 )
{
int i;
for ( i=0; i<MAXPLAYERS; i++ )
{
// If the player is in the game and not ready, stop checking
if ( playeringame[i] && !players[i].Bot && !playerready[i] )
break;
}
// All players are ready; proceed.
if ( ((i == MAXPLAYERS) && acceleratestage) || doautoskip )
{
PlaySound("misc/w_pkup");
initShowNextLoc();
}
}
else if ( ng_state&1 )
{
if ( !--cnt_pause )
{
ng_state++;
cnt_pause = Thinker.TICRATE;
}
}
}
override void drawStats( void )
{
drawLF();
Font fnt = LangFont(TewiFont);
int checkmark = 0x2714; // "✔", only available on Tewi
String namestr = StringTable.Localize("$SCORE_NAME");
String deathsstr = StringTable.Localize("$SCORE_DEATHS");
String fragsstr = StringTable.Localize("$SCORE_FRAGS");
String totalstr = StringTable.Localize("$SCORE_TOTAL");
int namelen = max(max(fnt.StringWidth(namestr),fnt.StringWidth("XXXXXXXXXX")),fnt.StringWidth(totalstr));
int nplayers = 0;
for ( int i=0; i<MAXPLAYERS; i++ )
{
if ( !playeringame[i] ) continue;
namelen = max(namelen,fnt.StringWidth(players[i].GetUserName()));
nplayers++;
}
String deathstotal = String.Format("%d",total_deaths);
String fragstotal = String.Format("%d",total_frags);
int deathslen = max(fnt.StringWidth(deathstotal),fnt.StringWidth(deathsstr));
int fragslen = max(fnt.StringWidth(fragstotal),fnt.StringWidth(fragsstr));
int pad = 4;
int spc = 12;
int lspc = 4;
int rwidth = TewiFont.GetCharWidth(checkmark)+4;
int ryofs = (fnt.GetHeight()-TewiFont.GetHeight())/2;
int linew = pad+rwidth+namelen+spc+deathslen+spc+fragslen+pad;
int boxwidth = pad+linew+pad;
int lineh = fnt.GetHeight();
int boxheight = pad+lineh+spc+(lineh+lspc)*nplayers+spc+lineh+pad;
Screen.Dim("Black",.8,int((ss.x-boxwidth)*hs)/2,int((ss.y-boxheight)*hs)/2,int(boxwidth*hs),int(boxheight*hs));
// header
double xx = (ss.x-boxwidth)/2.+pad+pad+rwidth;
double yy = (ss.y-boxheight)/2.+pad;
Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,namestr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
xx += namelen+spc;
Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,deathsstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
xx += deathslen+spc;
Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,fragsstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += lineh+spc;
String str;
Array<Int> sorted;
GetSortedPlayers(sorted,teamplay);
for ( int j=0; j<sorted.Size(); j++ )
{
int i = sorted[j];
if ( !playeringame[i] ) continue;
xx = (ss.x-boxwidth)/2.+pad;
Screen.Dim(players[i].GetDisplayColor(),.4,int(xx*hs),int(yy*hs),int(linew*hs),int(lineh*hs));
xx += pad;
if ( playerready[i] || players[i].Bot ) Screen.DrawChar(TewiFont,Font.CR_GREEN,xx,yy+ryofs,checkmark,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
xx += rwidth;
Screen.DrawText(fnt,GetRowColor(players[i],i==consoleplayer),xx,yy,players[i].GetUserName(),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
xx += namelen+spc;
if ( ng_state >= 2 )
{
str = String.Format("%d",cnt_deaths[i]);
Screen.DrawText(fnt,Font.CR_WHITE,xx+deathslen-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
xx += deathslen+spc;
str = String.Format("%d",cnt_frags[i]);
Screen.DrawText(fnt,Font.CR_WHITE,xx+fragslen-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
yy += lineh+lspc;
}
xx = (ss.x-boxwidth)/2.+pad+pad+rwidth;
yy += spc;
Screen.DrawText(fnt,Font.CR_GREEN,xx,yy,totalstr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
xx += namelen+spc;
if ( ng_state >= 4 )
{
str = String.Format("%d",total_deaths);
Screen.DrawText(fnt,Font.CR_WHITE,xx+deathslen-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
xx += deathslen+spc;
str = String.Format("%d",total_frags);
Screen.DrawText(fnt,Font.CR_WHITE,xx+fragslen-fnt.StringWidth(str),yy,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
}
}