From 00790e9cd274e66e9e806dcf5690314bf0d8f555 Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Tue, 14 Dec 2021 22:45:29 +0100 Subject: [PATCH] Add kills and level stats to Stats tab. --- language.version | 4 +- zscript/kbase/swwm_kbase_list.zsc | 60 ++++++- zscript/kbase/swwm_kbase_textbox.zsc | 4 + zscript/kbase/swwm_kbasetab_help.zsc | 4 + zscript/kbase/swwm_kbasetab_mission.zsc | 5 + zscript/kbase/swwm_kbasetab_stats.zsc | 224 +++++++++++++++++++++--- 6 files changed, 269 insertions(+), 32 deletions(-) diff --git a/language.version b/language.version index 083001c88..527f7fc03 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\chSWWM \czGZ\c- \cw1.2pre r79 \cu(Tue 14 Dec 22:44:47 CET 2021)\c-"; -SWWM_SHORTVER="\cw1.2pre r79 \cu(2021-12-14 22:44:47)\c-"; +SWWM_MODVER="\chSWWM \czGZ\c- \cw1.2pre r80 \cu(Tue 14 Dec 22:45:29 CET 2021)\c-"; +SWWM_SHORTVER="\cw1.2pre r80 \cu(2021-12-14 22:45:29)\c-"; diff --git a/zscript/kbase/swwm_kbase_list.zsc b/zscript/kbase/swwm_kbase_list.zsc index 8dc0967aa..cb7f2c6a2 100644 --- a/zscript/kbase/swwm_kbase_list.zsc +++ b/zscript/kbase/swwm_kbase_list.zsc @@ -6,6 +6,16 @@ Class DemolitionistMenuList ui Array items; int selected; + override void OnDestroy() + { + for ( int i=0; i(width-(maxlen[3]+maxlen[2]+maxlen[1]+maxlen[0]+24)); + Screen.DrawText(smallname?master.SmallFont:master.LargeFont,Font.CR_FIRE,master.origin.x+pos.x,master.origin.y+pos.y+smallname*2,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright); + double xx = pos.x+width; + double yy = pos.y+2; + int sec = Thinker.Tics2Seconds(s.time); + str = String.Format("%02d\cu:\c-%02d\cu:\c-%02d",sec/3600,(sec%3600)/60,sec%60); + Screen.DrawText(master.SmallFont,((s.suck>0)&&(sec>=(s.suck*3600)))?Font.CR_RED:(sec<=s.par)?Font.CR_GOLD:Font.CR_WHITE,master.origin.x+xx-master.SmallFont.StringWidth(str),master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright); + Screen.DrawText(master.SmallFont,Font.CR_FIRE,master.origin.x+xx-maxlen[0],master.origin.y+yy,"T",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright); + xx -= maxlen[0]+8; + str = String.Format("%d\cu/\c-%d",s.scount,s.stotal); + Screen.DrawText(master.SmallFont,(s.scount>=s.stotal)?Font.CR_GOLD:Font.CR_WHITE,master.origin.x+xx-master.SmallFont.StringWidth(str),master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright); + Screen.DrawText(master.SmallFont,Font.CR_FIRE,master.origin.x+xx-maxlen[1],master.origin.y+yy,"S",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright); + xx -= maxlen[1]+8; + str = String.Format("%d\cu/\c-%d",s.icount,s.itotal); + Screen.DrawText(master.SmallFont,(s.icount>=s.itotal)?Font.CR_GOLD:Font.CR_WHITE,master.origin.x+xx-master.SmallFont.StringWidth(str),master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright); + Screen.DrawText(master.SmallFont,Font.CR_FIRE,master.origin.x+xx-maxlen[2],master.origin.y+yy,"I",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright); + xx -= maxlen[2]+8; + str = String.Format("%d\cu/\c-%d",s.kcount,s.ktotal); + Screen.DrawText(master.SmallFont,(s.kcount>=s.ktotal)?Font.CR_GOLD:Font.CR_WHITE,master.origin.x+xx-master.SmallFont.StringWidth(str),master.origin.y+yy,str,DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright); + Screen.DrawText(master.SmallFont,Font.CR_FIRE,master.origin.x+xx-maxlen[3],master.origin.y+yy,"K",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true,DTA_ClipTop,cliptop,DTA_ClipBottom,clipbottom,DTA_ClipLeft,clipleft,DTA_ClipRight,clipright); + } } // achievement item @@ -128,7 +180,7 @@ Class DemolitionistMenuAchievementItem : DemolitionistMenuListItem SWWMAchievementInfo a; int width; - DemolitionistMenuAchievementItem Init( DemolitionistMenu master, SWWMAchievementInfo a, int width ) + DemolitionistMenuAchievementItem Init( DemolitionistMenu master, SWWMAchievementInfo a, int width = 0 ) { Super.Init(master,""); self.a = a; diff --git a/zscript/kbase/swwm_kbase_textbox.zsc b/zscript/kbase/swwm_kbase_textbox.zsc index d7de424f2..2ec44fe06 100644 --- a/zscript/kbase/swwm_kbase_textbox.zsc +++ b/zscript/kbase/swwm_kbase_textbox.zsc @@ -33,6 +33,10 @@ Class DemolitionistMenuTextBox ui } return self; } + override void OnDestroy() + { + l.Destroy(); + } // called when sending a scroll input // returns true if the position actually changed diff --git a/zscript/kbase/swwm_kbasetab_help.zsc b/zscript/kbase/swwm_kbasetab_help.zsc index 2c454ff26..0aacc947b 100644 --- a/zscript/kbase/swwm_kbasetab_help.zsc +++ b/zscript/kbase/swwm_kbasetab_help.zsc @@ -16,6 +16,10 @@ Class DemolitionistHelpTab : DemolitionistMenuTab mtext = new("DemolitionistMenuTextBox").Init(master,str); return Super.Init(master); } + override void OnDestroy() + { + mtext.Destroy(); + } override void MenuInput( int key ) { switch ( key ) diff --git a/zscript/kbase/swwm_kbasetab_mission.zsc b/zscript/kbase/swwm_kbasetab_mission.zsc index 859913c54..3e555b6a5 100644 --- a/zscript/kbase/swwm_kbasetab_mission.zsc +++ b/zscript/kbase/swwm_kbasetab_mission.zsc @@ -128,6 +128,11 @@ Class DemolitionistMissionTab : DemolitionistMenuTab } return Super.Init(master); } + override void OnDestroy() + { + for ( int i=0; i tagb; + } + return a.kills < b.kills; + } + + private int partition_mstats( Array a, int l, int h ) + { + DemolitionistMenuListItem pv = a[h]; + int i = (l-1); + for ( int j=l; j<=(h-1); j++ ) + { + if ( CmpMonsterKill(DemolitionistMenuKillItem(pv).s,DemolitionistMenuKillItem(a[j]).s) ) + { + i++; + DemolitionistMenuListItem tmp = a[j]; + a[j] = a[i]; + a[i] = tmp; + } + } + DemolitionistMenuListItem tmp = a[h]; + a[h] = a[i+1]; + a[i+1] = tmp; + return i+1; + } + private void qsort_mstats( Array a, int l, int h ) + { + if ( l >= h ) return; + int p = partition_mstats(a,l,h); + qsort_mstats(a,l,p-1); + qsort_mstats(a,p+1,h); + } + override void Ticker() { + if ( !stats ) return; // update list contents + String str; + int w; switch ( section ) { case 0: - if ( !stats ) stats = Demolitionist(players[consoleplayer].mo)?Demolitionist(players[consoleplayer].mo).mystats:null; if ( lists[0].items.Size() == 0 ) // allocate first { for ( int i=0; i<31; i++ ) { let li = new("DemolitionistMenuListItem").Init(master,""); - li.xpos = 0; li.ypos = i*16; lists[0].items.Push(li); } } - maxofs = int(16*lists[0].items.Size()-(master.ws.y-46)); - if ( !stats ) break; + maxofs[0] = int(16*lists[0].items.Size()-(master.ws.y-46)); // oof int thour = ((level.totaltime-stats.lastspawn)/(3600*GameTicRate)); int tmin = ((level.totaltime-stats.lastspawn)/(60*GameTicRate))%60; int tsec = ((level.totaltime-stats.lastspawn)/GameTicRate)%60; - String str = String.Format("\cx%s\c-%02d\cu:\c-%02d\cu:\c-%02d",StringTable.Localize("$SWWM_STATUPTIME"),thour,tmin,tsec); + str = String.Format("\cx%s\c-%02d\cu:\c-%02d\cu:\c-%02d",StringTable.Localize("$SWWM_STATUPTIME"),thour,tmin,tsec); lists[0].items[0].label = str; if ( stats.grounddist > 32000. ) str = String.Format("\cx%s\c-%g\cu%s\c-",StringTable.Localize("$SWWM_STATONFOOT"),stats.grounddist/32000.,StringTable.Localize("$SWWM_UNIT_KILOMETER")); else str = String.Format("\cx%s\c-%g\cu%s\c-",StringTable.Localize("$SWWM_STATONFOOT"),stats.grounddist/32.,StringTable.Localize("$SWWM_UNIT_METER")); @@ -141,10 +237,78 @@ Class DemolitionistStatsTab : DemolitionistMenuTab else str = String.Format("\cx%s\cu¥\c-%09d",StringTable.Localize("$SWWM_STATHISCORE"),stats.hiscore); lists[0].items[30].label = str; break; + case 1: + // theoretically we can assume that the monster stats list will never shrink in the middle of gameplay, only grow + // also the array only ever has elements pushed, never inserted in-between + // if this somehow breaks, I don't know what the hell can do that + if ( lists[1].items.Size() < stats.mstats.Size() ) + { + int oldindex = lists[1].items.Size(); + lists[1].items.Resize(stats.mstats.Size()); + for ( int i=oldindex; i 0 ) w -= 8; + for ( int i=0; i 0 ) w -= 8; + int len[4], maxlen[4]; + for ( int i=0; i<4; i++ ) maxlen[i] = 0; + for ( int i=0; i maxlen[0] ) maxlen[0] = len[0]; + str = String.Format("S %d/%d",l.s.scount,l.s.stotal); + len[1] = master.SmallFont.StringWidth(str); + if ( len[1] > maxlen[1] ) maxlen[1] = len[1]; + str = String.Format("I %d/%d",l.s.icount,l.s.itotal); + len[2] = master.SmallFont.StringWidth(str); + if ( len[2] > maxlen[2] ) maxlen[2] = len[2]; + str = String.Format("K %d/%d",l.s.kcount,l.s.ktotal); + len[3] = master.SmallFont.StringWidth(str); + if ( len[3] > maxlen[3] ) maxlen[3] = len[3]; + } + // second pass to propagate the "max lengths" + for ( int i=0; i 3 ) section = 0; - smofs = ofs = 0; + smofs[section] = ofs[section]; break; case MK_DOWN: if ( Scroll(16) ) master.MenuSound("menu/demoscroll"); @@ -219,8 +385,9 @@ Class DemolitionistStatsTab : DemolitionistMenuTab if ( section != i ) { master.MenuSound("menu/demoscroll"); + smofs[section] = ofs[section]; section = i; - smofs = ofs = 0; + smofs[section] = ofs[section]; } break; } @@ -232,12 +399,13 @@ Class DemolitionistStatsTab : DemolitionistMenuTab MenuInput(MK_RIGHT); break; } + return; } switch ( btn ) { case MB_LEFT: // see if we're clicking the scrollbar (if it exists) - if ( (maxofs > 0) && (pos.x > (master.ws.x-8)) ) + if ( (maxofs[section] > 0) && (pos.x > (master.ws.x-8)) ) { SetOffset(pos.y); master.MenuSound("menu/demoscroll"); @@ -254,6 +422,7 @@ Class DemolitionistStatsTab : DemolitionistMenuTab } override void Drawer() { + if ( !stats ) return; double xx = 9; double yy = 23; for ( int i=0; i<4; i++ ) @@ -262,7 +431,11 @@ Class DemolitionistStatsTab : DemolitionistMenuTab yy += 16; } master.DrawVSeparator(lwidth,14,master.ws.y-28); - if ( section == 0 ) + if ( section == 3 ) + { + // TODO achievement drawer has different margins + } + else { xx = lwidth+9; yy = 23; @@ -270,16 +443,15 @@ Class DemolitionistStatsTab : DemolitionistMenuTab int clipbottom = int((master.origin.y+master.ws.y-23)*master.hs); int clipleft = int((master.origin.x+lwidth+9)*master.hs); int clipright = int((master.origin.x+master.ws.x-9)*master.hs); - lists[0].Drawer((xx,yy-smofs),cliptop,clipbottom,clipleft,clipright); - if ( maxofs > 0 ) + lists[section].Drawer((xx,yy-smofs[section]),cliptop,clipbottom,clipleft,clipright); + if ( maxofs[section] > 0 ) { xx = master.ws.x-8; master.DrawVSeparator(xx,14,master.ws.y-28); xx += 2; - yy = floor(smofs*((master.ws.y-39)/maxofs))+13; + yy = floor(smofs[section]*((master.ws.y-39)/maxofs[section]))+13; Screen.DrawText(master.TewiFont,Font.CR_FIRE,master.origin.x+xx,master.origin.y+yy,"▮",DTA_VirtualWidthF,master.ss.x,DTA_VirtualHeightF,master.ss.y,DTA_KeepRatio,true); } } - } }