swwmgz_m/zscript/weapons/swwm_cbt_ui.zsc
Marisa the Magician 5488bfce5d Remove code built on incorrect assumptions about UI events.
That is, remove code for closing menus with the key that's bound to open them.
As it turns out, UIEvent.keystring isn't 1:1 with key binds for a command.
This SEEMINGLY worked since the Demolitionist Menu is by default bound to Q,
and pressing Q does send an UIEvent to the menu with the string "Q". But if,
for example, the menu had been bound to Tab, this would fall apart because then
the key string sent is "	" (a literal tab character).
If there is a way to do this properly, I don't know about it. I've looked
everywhere in GZDoom's code for a solution, something that would let me do what
I need, but alas, there is nothing there. Better to get rid of this in its
entirety than keep the flaky code in the mod until someone with a special
setup that breaks it shows up to complain.
2022-08-13 14:28:09 +02:00

382 lines
10 KiB
Text

// when you need a whole-ass menu to reload a weapon
Class WallbusterReloadMenu : GenericMenu
{
TextureID MainWindow, AmmoIcon[4];
int sel0;
Array<int> queue;
int AmmoSets[4];
bool isrclick, multiclk;
Vector2 curmouse;
String ttl;
BrokenLines keyl;
Font mSmallFont, mTinyFont;
double hs;
Vector2 ss, origin;
override void Init( Menu parent )
{
Super.Init(parent);
Animated = true;
if ( (gamestate != GS_LEVEL) || (players[consoleplayer].Health <= 0) || !(players[consoleplayer].ReadyWeapon is 'Wallbuster') )
{
EventHandler.SendNetworkEvent("swwmcbt.",consoleplayer);
Close();
return;
}
MainWindow = TexMan.CheckForTexture("graphics/HUD/WallbusterMenu.png",TexMan.Type_Any);
AmmoIcon[0] = TexMan.CheckForTexture("graphics/HUD/MenuShellRed.png",TexMan.Type_Any);
AmmoIcon[1] = TexMan.CheckForTexture("graphics/HUD/MenuShellGreen.png",TexMan.Type_Any);
AmmoIcon[2] = TexMan.CheckForTexture("graphics/HUD/MenuShellBlue.png",TexMan.Type_Any);
AmmoIcon[3] = TexMan.CheckForTexture("graphics/HUD/MenuShellPurple.png",TexMan.Type_Any);
mSmallFont = Font.GetFont('TewiFont');
mTinyFont = Font.GetFont('MiniwiFont');
MenuSound("menu/demotab");
queue.Clear();
sel0 = swwm_cbtlast;
ttl = StringTable.Localize("$SWWM_BUSTERTITLE");
keyl = mTinyFont.BreakLines(StringTable.Localize("$SWWM_BUSTERKEYS"),300);
hs = max(min(floor(Screen.GetWidth()/640.),floor(Screen.GetHeight()/400.)),1.);
ss = (Screen.GetWidth(),Screen.GetHeight())/hs;
origin = (ss.x-120,ss.y-28)/2.;
}
override void Ticker()
{
Super.Ticker();
if ( swwm_menupause ) menuactive = Menu.On;
else menuactive = Menu.OnNoPause;
if ( (players[consoleplayer].Health > 0) && (players[consoleplayer].ReadyWeapon is 'Wallbuster') && (gamestate == GS_LEVEL) ) return;
MenuEvent(MKEY_BACK,false);
}
private bool IsDone()
{
static const Class<Ammo> types[] = {"RedShell","GreenShell","BlueShell","PurpleShell"};
if ( queue.Size() >= 25 ) return true;
for ( int i=0; i<4; i++ )
{
if ( (players[consoleplayer].mo.CountInv(types[i])-AmmoSets[i]) > 0 )
return false;
}
return true;
}
private bool PushAmmo( bool autoshift = false, bool usebest = false )
{
static const Class<Ammo> types[] = {"RedShell","GreenShell","BlueShell","PurpleShell"};
if ( queue.Size() >= 25 ) return true;
if ( autoshift && usebest ) sel0 = 3; // ensure it prioritizes best ammo
if ( (players[consoleplayer].mo.CountInv(types[sel0])-AmmoSets[sel0]) <= 0 )
{
if ( autoshift )
{
if ( usebest ) for ( int i=3; i>=0; i-- )
{
int idx = (sel0+i)%4;
if ( (players[consoleplayer].mo.CountInv(types[idx])-AmmoSets[idx]) > 0 )
{
sel0 = idx;
CVar.FindCVar('swwm_cbtlast').SetInt(sel0);
return PushAmmo(true);
}
}
else for ( int i=0; i<4; i++ )
{
int idx = (sel0+i)%4;
if ( (players[consoleplayer].mo.CountInv(types[idx])-AmmoSets[idx]) > 0 )
{
sel0 = idx;
CVar.FindCVar('swwm_cbtlast').SetInt(sel0);
return PushAmmo(true);
}
}
}
MenuSound("menu/noinvuse");
return false;
}
if ( !autoshift ) MenuSound("menu/demosel");
AmmoSets[sel0]++;
queue.Push(sel0);
return true;
}
private bool PopAmmo()
{
if ( queue.Size() <= 0 ) return false;
AmmoSets[queue[queue.Size()-1]]--;
queue.Pop();
return true;
}
override bool MenuEvent( int mkey, bool fromcontroller )
{
switch ( mkey )
{
case MKEY_BACK:
queue.Clear();
for ( int i=0; i<4; i++ ) AmmoSets[i] = 0;
MenuSound("menu/democlose");
EventHandler.SendNetworkEvent("swwmcbt.",consoleplayer);
Close();
return true;
case MKEY_ENTER:
if ( queue.Size() <= 0 )
{
int oldsel = sel0;
while ( queue.Size() < 25 )
{
if ( !PushAmmo(true,true) )
break;
}
sel0 = oldsel;
}
String cbt = "swwmcbt.";
for ( int i=0; i<queue.Size(); i++ )
cbt.AppendFormat("%d,",queue[i]);
MenuSound("menu/democlose");
EventHandler.SendNetworkEvent(cbt,consoleplayer);
Close();
return true;
case MKEY_UP:
if ( queue.Size() <= 0 )
{
MenuSound("menu/noinvuse");
return true;
}
PopAmmo();
MenuSound("menu/demoscroll");
return true;
case MKEY_DOWN:
if ( IsDone() )
{
MenuSound("menu/noinvuse");
return true;
}
PushAmmo();
return true;
case MKEY_RIGHT:
MenuSound("menu/demotab");
sel0++;
if ( sel0 > 3 ) sel0 = 0;
CVar.FindCVar('swwm_cbtlast').SetInt(sel0);
return true;
case MKEY_LEFT:
MenuSound("menu/demotab");
sel0--;
if ( sel0 < 0 ) sel0 = 3;
CVar.FindCVar('swwm_cbtlast').SetInt(sel0);
return true;
case MKEY_PAGEUP:
if ( queue.Size() <= 0 )
{
MenuSound("menu/noinvuse");
return true;
}
int i = 0;
while ( (queue.Size() > 0) && (i++ < 5) )
{
if ( !PopAmmo() )
break;
}
MenuSound("menu/demoscroll");
return true;
case MKEY_PAGEDOWN:
if ( IsDone() )
{
MenuSound("menu/noinvuse");
return true;
}
int j = 0;
while ( (queue.Size() < 25) && (j++ < 5) )
{
if ( !PushAmmo(true) )
return true;
}
MenuSound("menu/demosel");
return true;
case MKEY_CLEAR:
if ( queue.Size() <= 0 ) MenuSound("menu/noinvuse");
else
{
MenuSound("menu/demoscroll");
queue.Clear();
for ( int i=0; i<4; i++ ) AmmoSets[i] = 0;
}
return true;
}
return Super.MenuEvent(mkey,fromcontroller);
}
override bool MouseEvent( int type, int mx, int my )
{
if ( (type != MOUSE_CLICK) && (type != MOUSE_RELEASE) ) return false;
Vector2 mpos = (mx/hs,my/hs)-origin;
int wset = -1;
int ox = 6;
for ( int i=0; i<4; i++ )
{
if ( (mpos.x >= ox) && (mpos.x < ox+27) && (mpos.y >= 0) && (mpos.y < 13) )
{
wset = i;
break;
}
ox += 27;
}
if ( (wset != -1) && (type == MOUSE_CLICK) && (wset != sel0) )
{
MenuSound("menu/demotab");
sel0 = wset;
CVar.FindCVar('swwm_cbtlast').SetInt(sel0);
}
bool inside = (wset!=-1);
if ( type != MOUSE_RELEASE ) return false;
if ( (mpos.x >= 0) && (mpos.x < 120) && (mpos.y >= 15) && (mpos.y < 28) ) inside = true;
if ( isrclick )
{
// right click inside: pop
// right click outside: clear (empty if already clear)
if ( inside || multiclk ) MenuEvent(multiclk?MKEY_PAGEUP:MKEY_UP,false);
else
{
if ( queue.Size() == 0 )
{
for ( int i=0; i<4; i++ ) AmmoSets[i] = 0;
MenuSound("menu/democlose");
EventHandler.SendNetworkEvent("swwmcbt.EMPTY",consoleplayer);
Close();
}
else MenuEvent(MKEY_CLEAR,false);
}
}
else
{
// left click inside: push
// left click outside: commit
if ( inside || multiclk ) MenuEvent(multiclk?MKEY_PAGEDOWN:MKEY_DOWN,false);
else MenuEvent(MKEY_ENTER,false);
}
return false;
}
override bool OnUiEvent( UIEvent ev )
{
int y;
bool res;
switch ( ev.type )
{
case UIEvent.Type_KeyDown:
if ( ev.keychar == UiEvent.Key_Del )
{
// empty it out
queue.Clear();
for ( int i=0; i<4; i++ ) AmmoSets[i] = 0;
MenuSound("menu/democlose");
EventHandler.SendNetworkEvent("swwmcbt.EMPTY",consoleplayer);
Close();
}
break;
case UIEvent.Type_LButtonDown:
isrclick = false;
multiclk = false;
MouseEvent(MOUSE_Click,ev.MouseX,ev.MouseY);
break;
case UIEvent.Type_LButtonUp:
isrclick = false;
multiclk = false;
MouseEvent(MOUSE_Release,ev.MouseX,ev.MouseY);
break;
case UIEvent.Type_RButtonDown:
isrclick = true;
multiclk = false;
MouseEvent(MOUSE_Click,ev.MouseX,ev.MouseY);
break;
case UIEvent.Type_RButtonUp:
isrclick = true;
multiclk = false;
MouseEvent(MOUSE_Release,ev.MouseX,ev.MouseY);
break;
case UIEvent.Type_WheelDown:
// wheel down: push 5
isrclick = false;
multiclk = true;
MouseEvent(MOUSE_Click,int(curmouse.x),int(curmouse.y));
MouseEvent(MOUSE_Release,int(curmouse.x),int(curmouse.y));
break;
case UIEvent.Type_WheelUp:
// wheel up: pop 5
isrclick = true;
multiclk = true;
MouseEvent(MOUSE_Click,int(curmouse.x),int(curmouse.y));
MouseEvent(MOUSE_Release,int(curmouse.x),int(curmouse.y));
break;
case UIEvent.Type_MouseMove:
curmouse = (ev.MouseX,ev.MouseY);
break;
}
return false;
}
override void Drawer()
{
static const Class<Ammo> types[] = {"RedShell","GreenShell","BlueShell","PurpleShell"};
Super.Drawer();
Screen.DrawTexture(MainWindow,false,origin.x,origin.y,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
int ox = 27, oy = 2;
for ( int i=0; i<4; i++ )
{
Screen.DrawTexture(AmmoIcon[i],false,origin.x+ox,origin.y+oy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i==sel0)?Color(0,0,0,0):Color(128,0,0,0));
String astr = String.Format("%3d",players[consoleplayer].mo.CountInv(types[i])-AmmoSets[i]);
Screen.DrawText(mSmallFont,Font.CR_FIRE,origin.x+ox-(mSmallFont.StringWidth(astr)+1),origin.y+oy-1,astr,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true,DTA_ColorOverlay,(i==sel0)?Color(0,0,0,0):Color(128,0,0,0));
ox += 27;
}
int siz = queue.Size()-1;
ox = 2;
oy = 17;
for ( int i=siz; i>=0; i-- )
{
Screen.DrawTexture(AmmoIcon[queue[i]],false,origin.x+ox,origin.y+oy,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
ox += 4;
if ( !((siz-(i-1))%5) ) ox += 4;
}
// text stuff
String str;
int boxw, sw;
double x, y;
str = ttl;
sw = mSmallFont.StringWidth(str);
boxw = sw;
str = "(C)2148 Akari Labs";
sw = mTinyFont.StringWidth(str);
if ( sw > boxw ) boxw = sw;
x = floor((ss.x-boxw)/2.);
y = origin.y-30;
Screen.Dim("Black",.8,int((x-2)*hs),int((y-1)*hs),int((boxw+4)*hs),int(25*hs));
str = ttl;
sw = mSmallFont.StringWidth(str);
x = floor((ss.x-sw)/2.);
Screen.DrawText(mSmallFont,Font.CR_FIRE,x,y,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
y += 14;
str = "(C)2148 Akari Labs";
sw = mTinyFont.StringWidth(str);
x = floor((ss.x-sw)/2.);
Screen.DrawText(mTinyFont,Font.CR_GOLD,x,y,str,DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
y = origin.y+38;
boxw = 0;
for ( int i=0; i<keyl.Count(); i++ )
{
sw = keyl.StringWidth(i);
if ( sw > boxw ) boxw = sw;
}
x = floor((ss.x-boxw)/2.);
Screen.Dim("Black",.8,int((x-2)*hs),int((y-2)*hs),int((boxw+4)*hs),int((9*keyl.Count()+2)*hs));
for ( int i=0; i<keyl.Count(); i++ )
{
Screen.DrawText(mTinyFont,Font.CR_WHITE,x,y,keyl.StringAt(i),DTA_VirtualWidthF,ss.x,DTA_VirtualHeightF,ss.y,DTA_KeepRatio,true);
y += 9;
}
}
}