Add wrap-around to the alternate weapon selector, so it's a proper carousel.

This commit is contained in:
Mari the Deer 2025-01-17 14:24:30 +01:00
commit 05dadea4ae
2 changed files with 100 additions and 58 deletions

View file

@ -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-";

View file

@ -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(); i++ )
{
if ( !weaps[i] ) continue;
double h = 16.; // padding
TextureID ico = GetIcon(weaps[i]);
if ( ico.IsValid() )
{
Vector2 sz = TexMan.GetScaledSize(ico);
if ( weaps[i] is 'SWWMWeapon' ) // SWWM weapon icons are larger
sz *= .125;
h += sz.y;
}
else h += fnt.GetHeight();
double h = GetHeight(weaps[i]);
if ( i == cursel ) cur = th+(h*.5);
th += h;
}
if ( bGetTotal ) return th;
return (cur<0.)?(th*.5):cur;
}
@ -1392,7 +1399,13 @@ Class SWWMWeaponSelect : HUDMessageBase
for ( int i=0; i<weaps.Size(); i++ )
{
cursel--;
if ( cursel < 0 ) cursel = weaps.Size()-1;
if ( cursel < 0 )
{
double fh = CalcHeight(true);
smoothY += fh;
olsmoothY += fh;
cursel = weaps.Size()-1;
}
if ( WeaponHasAmmo(weaps[cursel]) ) break;
}
curY = CalcHeight();
@ -1407,7 +1420,13 @@ Class SWWMWeaponSelect : HUDMessageBase
for ( int i=0; i<weaps.Size(); i++ )
{
cursel++;
if ( cursel >= 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<weaps.Size(); i++ )
int i;
for ( i=0; i<weaps.Size(); i++ )
{
if ( !weaps[i] ) continue;
let w = weaps[i];
let sw = SWWMWeapon(weaps[i]);
double scl = sw?.125:1.;
y += 8.;
double fade = clamp(.8-abs(y-hss.y)/hss.y,0.,.8)/.8;
bool bHasAmmo = WeaponHasAmmo(w);
TextureID ico = GetIcon(w);
if ( ico.IsValid() )
{
Vector2 sz = TexMan.GetScaledSize(ico);
y += sz.y*scl*.5;
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)?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;
}
}
}