From 05dadea4aeaaea1b5e024c548ad4daf8553272c6 Mon Sep 17 00:00:00 2001 From: Marisa the Magician Date: Fri, 17 Jan 2025 14:24:30 +0100 Subject: [PATCH] Add wrap-around to the alternate weapon selector, so it's a proper carousel. --- language.version | 4 +- zscript/hud/swwm_hudextra.zsc | 154 +++++++++++++++++++++------------- 2 files changed, 100 insertions(+), 58 deletions(-) diff --git a/language.version b/language.version index dc825940b..372cbfc91 100644 --- a/language.version +++ b/language.version @@ -1,3 +1,3 @@ [default] -SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r1166 \cu(Wed Jan 15 16:49:55 CET 2025)\c-"; -SWWM_SHORTVER="\cw1.3pre r1166 \cu(2025-01-15 16:49:55)\c-"; +SWWM_MODVER="\cyDEMOLITIONIST \cw1.3pre r1167 \cu(Fri Jan 17 14:24:30 CET 2025)\c-"; +SWWM_SHORTVER="\cw1.3pre r1167 \cu(2025-01-17 14:24:30)\c-"; diff --git a/zscript/hud/swwm_hudextra.zsc b/zscript/hud/swwm_hudextra.zsc index fdde726d5..bf70db407 100644 --- a/zscript/hud/swwm_hudextra.zsc +++ b/zscript/hud/swwm_hudextra.zsc @@ -1289,26 +1289,33 @@ Class SWWMWeaponSelect : HUDMessageBase return ico; } - private double CalcHeight() + private double GetHeight( Weapon w ) + { + double h = 16.; // padding + TextureID ico = GetIcon(w); + if ( ico.IsValid() ) + { + Vector2 sz = TexMan.GetScaledSize(ico); + if ( w is 'SWWMWeapon' ) // SWWM weapon icons are larger + sz *= .125; + h += sz.y; + } + else h += fnt.GetHeight(); + return h; + } + + private double CalcHeight( bool bGetTotal = false ) { double th = 0.; double cur = -1.; for ( int i=0; i= weaps.Size() ) cursel = 0; + if ( cursel >= weaps.Size() ) + { + double fh = CalcHeight(true); + smoothY -= fh; + olsmoothY -= fh; + cursel = 0; + } if ( WeaponHasAmmo(weaps[cursel]) ) break; } curY = CalcHeight(); @@ -1502,6 +1521,55 @@ Class SWWMWeaponSelect : HUDMessageBase return false; } + // simplify some code here + private bool DrawWeapon( Weapon w, int i, double x, double &y, double hs, Vector2 hss, double salph, double fractic, bool bOverflow = false, bool bUpward = false ) + { + let sw = SWWMWeapon(w); + double scl = sw?.125:1.; + y += bUpward?-8.:8.; + bool bHasAmmo = WeaponHasAmmo(w); + TextureID ico = GetIcon(w); + double fade = 0.; + if ( ico.IsValid() ) + { + Vector2 sz = TexMan.GetScaledSize(ico); + y += sz.y*scl*(bUpward?-.5:.5); + fade = clamp(.8-abs(y-hss.y)/hss.y,0.,.8)/.8; + if ( sw && sw.SisterWeapon && (sw.Amount > 1) && ((mo.player.ReadyWeapon == sw) || ((mo.player.ReadyWeapon != sw.SisterWeapon) && !swwm_singlefirst)) ) + { + // double draw + Screen.DrawTexture(ico,false,x-(4.*hs),(y-4.)*hs,DTA_ScaleX,scl*hs,DTA_ScaleY,scl*hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true,DTA_Color,bHasAmmo?0xFFFFFFFF:0xFF800000,DTA_ColorOverlay,((i==cursel)&&!bOverflow)?0x00000000:0x80000000); + Screen.DrawTexture(ico,false,x+(4.*hs),(y+4.)*hs,DTA_ScaleX,scl*hs,DTA_ScaleY,scl*hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true,DTA_Color,bHasAmmo?0xFFFFFFFF:0xFF800000,DTA_ColorOverlay,((i==cursel)&&!bOverflow)?0x00000000:0x80000000); + } + else Screen.DrawTexture(ico,false,x,y*hs,DTA_ScaleX,scl*hs,DTA_ScaleY,scl*hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true,DTA_Color,bHasAmmo?0xFFFFFFFF:0xFF800000,DTA_ColorOverlay,((i==cursel)&&!bOverflow)?0x00000000:0x80000000); + if ( (i == cursel) && !bOverflow ) + { + Screen.DrawChar(fnt,Font.CR_FIRE,x-((sz.x*scl*.5+16.+2.*sin((gametic+fractic)*8.))*hs),y*hs,0x25BA,DTA_ScaleX,hs,DTA_ScaleY,hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true); + Screen.DrawChar(fnt,Font.CR_FIRE,x+((sz.x*scl*.5+16.+2.*sin((gametic+fractic)*8.))*hs),y*hs,0x25C4,DTA_ScaleX,hs,DTA_ScaleY,hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true); + } + y += sz.y*scl*(bUpward?-.5:.5); + } + else + { + String label = "?WeaponName?"; + if ( sw && sw.SisterWeapon && (sw.Amount > 1) && ((mo.player.ReadyWeapon == sw) || ((mo.player.ReadyWeapon != sw.SisterWeapon) && !swwm_singlefirst)) ) + label = sw.SisterWeapon.GetTag(); + else label = w.GetTag(); + Vector2 sz = (fnt.StringWidth(label),fnt.GetHeight()); + Screen.DrawText(fnt,bHasAmmo?Font.CR_WHITE:Font.CR_RED,x-sz.x*.5*hs,y*hs,label,DTA_ScaleX,hs,DTA_ScaleY,hs,DTA_Alpha,salph*fade,DTA_ColorOverlay,((i==cursel)&&!bOverflow)?0x00000000:0x80000000); + y += sz.y*(bUpward?-.5:.5); + fade = clamp(.8-abs(y-hss.y)/hss.y,0.,.8)/.8; + if ( (i == cursel) && !bOverflow ) + { + Screen.DrawChar(fnt,Font.CR_FIRE,x-((sz.x*.5+16.+2.*sin((gametic+fractic)*8.))*hs),y*hs,0x25BA,DTA_ScaleX,hs,DTA_ScaleY,hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true); + Screen.DrawChar(fnt,Font.CR_FIRE,x+((sz.x*.5+16.+2.*sin((gametic+fractic)*8.))*hs),y*hs,0x25C4,DTA_ScaleX,hs,DTA_ScaleY,hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true); + } + y += sz.y*(bUpward?-.5:.5); + } + y += bUpward?-8.:8.; + return (fade <= 0.); + } + override void Draw( int bottom, int visibility ) { double fractic = System.GetTimeFrac(); @@ -1523,51 +1591,25 @@ Class SWWMWeaponSelect : HUDMessageBase Vector2 hss = ss*.5; double x = Screen.GetWidth()*.5; double y = hss.y-ssmoothY; - for ( int i=0; i 1) && ((mo.player.ReadyWeapon == sw) || ((mo.player.ReadyWeapon != sw.SisterWeapon) && !swwm_singlefirst)) ) - { - // double draw - Screen.DrawTexture(ico,false,x-(4.*hs),(y-4.)*hs,DTA_ScaleX,scl*hs,DTA_ScaleY,scl*hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true,DTA_Color,bHasAmmo?0xFFFFFFFF:0xFF800000,DTA_ColorOverlay,(i==cursel)?0x00000000:0x80000000); - Screen.DrawTexture(ico,false,x+(4.*hs),(y+4.)*hs,DTA_ScaleX,scl*hs,DTA_ScaleY,scl*hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true,DTA_Color,bHasAmmo?0xFFFFFFFF:0xFF800000,DTA_ColorOverlay,(i==cursel)?0x00000000:0x80000000); - } - else Screen.DrawTexture(ico,false,x,y*hs,DTA_ScaleX,scl*hs,DTA_ScaleY,scl*hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true,DTA_Color,bHasAmmo?0xFFFFFFFF:0xFF800000,DTA_ColorOverlay,(i==cursel)?0x00000000:0x80000000); - if ( i == cursel ) - { - Screen.DrawChar(fnt,Font.CR_FIRE,x-((sz.x*scl*.5+16.+2.*sin((gametic+fractic)*8.))*hs),y*hs,0x25BA,DTA_ScaleX,hs,DTA_ScaleY,hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true); - Screen.DrawChar(fnt,Font.CR_FIRE,x+((sz.x*scl*.5+16.+2.*sin((gametic+fractic)*8.))*hs),y*hs,0x25C4,DTA_ScaleX,hs,DTA_ScaleY,hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true); - } - y += sz.y*scl*.5; - } - else - { - String label = "?WeaponName?"; - if ( sw && sw.SisterWeapon && (sw.Amount > 1) && ((mo.player.ReadyWeapon == sw) || ((mo.player.ReadyWeapon != sw.SisterWeapon) && !swwm_singlefirst)) ) - label = sw.SisterWeapon.GetTag(); - else label = w.GetTag(); - Vector2 sz = (fnt.StringWidth(label),fnt.GetHeight()); - Screen.DrawText(fnt,bHasAmmo?Font.CR_WHITE:Font.CR_RED,x-sz.x*.5*hs,y*hs,label,DTA_ScaleX,hs,DTA_ScaleY,hs,DTA_Alpha,salph*fade,DTA_ColorOverlay,(i==cursel)?0x00000000:0x80000000); - y += sz.y*.5; - if ( i == cursel ) - { - Screen.DrawChar(fnt,Font.CR_FIRE,x-((sz.x*.5+16.+2.*sin((gametic+fractic)*8.))*hs),y*hs,0x25BA,DTA_ScaleX,hs,DTA_ScaleY,hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true); - Screen.DrawChar(fnt,Font.CR_FIRE,x+((sz.x*.5+16.+2.*sin((gametic+fractic)*8.))*hs),y*hs,0x25C4,DTA_ScaleX,hs,DTA_ScaleY,hs,DTA_Alpha,salph*fade,DTA_CenterOffset,true); - } - y += sz.y*.5; - } - y += 8.; + DrawWeapon(weaps[i],i,x,y,hs,hss,salph,fractic); } + // continue drawing downwards until alpha is zero + i = 0; + while ( !DrawWeapon(weaps[i],i,x,y,hs,hss,salph,fractic,true) ) + { + if ( ++i >= weaps.Size() ) i = 0; + } + // reposition and draw upwards until alpha is zero + y = hss.y-ssmoothY; + i = weaps.Size()-1; + while ( !DrawWeapon(weaps[i%weaps.Size()],i%weaps.Size(),x,y,hs,hss,salph,fractic,true,true) ) + { + if ( --i < 0 ) i = weaps.Size()-1; + } + } }