halflife-thewastes-sdk/cl_dll/vgui_ItemSelection.cpp

634 lines
17 KiB
C++

/***
*
* Copyright (C) 2002 The Wastes Project, All Rights Reserved.
*
* This product contains software technology from Valve Software, LLC,
* Copyright © 1996-2001, Valve LLC, All rights reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* The Wastes Project. All other use, distribution, or modification is prohibited
* without written permission from The Wastes Project.
*
***/
#include "VGUI_TextImage.h"
#include "hud.h"
#include "cl_util.h"
#include "tw_vgui.h"
#include "vgui_TheWastesViewport.h"
#include "tw_common.h"
#include <vector>
#define INFO_PANEL_X XRES(236)
#define INFO_PANEL_Y YRES(188)
#define INFO_PANEL_SIZE_X XRES(328)
#define INFO_PANEL_SIZE_Y YRES(220)
#define IMAGE_PANEL_X XRES(236)
#define IMAGE_PANEL_Y YRES(34)
#define IMAGE_PANEL_SIZE_X XRES(328)
#define IMAGE_PANEL_SIZE_Y YRES(76)
#define LIST_BUTTON_X XRES(68)
#define LIST_BUTTON_Y YRES(34)
#define MAIN_BUTTON_X XRES(68)
#define MAIN_BUTTON_Y YRES(416)
#define BUTTON_SIZE_X XRES(160)
//#define BUTTON_SIZE_Y YRES(30)
// Important:
// join_game -> join this game
// setweapons -> set weapons command, 5 arguments like setweapons -1 -1 -1 -1 -1
// setrandom -> random weaps
// unsetrandom -> non random weaps
// spectate -> spectate this game
class CItemList;
/*
==========
CInformationPanel
==========
*/
class CInformationPanel : public CTransparentPanel
{
public:
CInformationPanel( int x, int y, int wide, int tall );
void SetInfo( char *pszClassname );
private:
ScrollPanel *m_pScrollPanel;
TextPanel *m_pTextPanel;
CImageLabel *m_pImageLabel;
char m_szClassname[128];
};
/*
==========
CItemSelectionPanel
==========
*/
class CItemSelectionPanel : public CMenuPanel
{
public:
CItemSelectionPanel(int x,int y,int wide,int tall);
~CItemSelectionPanel();
void paintBackground();
void SetInfo(char *pszClassname);
void SetImage( const char *pszClassname, int iIndex );
void AddItem( playeritemlist_t *pList, int iSlot, int iIndex );
void SendItems();
private:
CImageLabel *m_pImageLabels[5];
CItemList *m_pItemList;
CInformationPanel *m_pInformationPanel;
int m_iWeaponIndices[5];
};
/*
==========
CItemSelectionPanel_Create
Used by external modules to spawn this item selection code
==========
*/
CMenuPanel *CItemSelectionPanel_Create(int x,int y,int wide,int tall)
{
return new CItemSelectionPanel(x,y,wide,tall);
}
/*
==========
CItemListHandler_NewItemList
==========
*/
enum e_itemcategories {
ITEM_MELEE = 0,
ITEM_SIDEARMS,
ITEM_PRIMARY,
ITEM_UNIQUE,
ITEM_EXPLOSIVES,
ITEM_BACK,
};
class CItemListHandler_NewItemList : public ActionSignal
{
public:
CItemListHandler_NewItemList(int iCategory,CItemList *pItemList);
virtual void actionPerformed(Panel *panel);
private:
int m_iCategory;
CItemList *m_pOldItemList;
};
/*
==========
CHandler_SendChanges
==========
*/
class CHandler_SendChanges : public ActionSignal
{
public:
CHandler_SendChanges(CItemSelectionPanel *pPanel)
{
m_pInfoPanel = pPanel;
}
virtual void actionPerformed(Panel *panel)
{
m_pInfoPanel->SendItems();
}
private:
CItemSelectionPanel *m_pInfoPanel;
};
/*
==========
CItemButtonHandler_SetItem
==========
*/
class CItemButtonHandler_SetItem : public ActionSignal
{
public:
CItemButtonHandler_SetItem( playeritemlist_t *pList, int iSlot, int iIndex, CItemSelectionPanel *pPanel) :
m_pList( pList ), m_iWeaponIndex( iIndex ), m_iWeaponSlot( iSlot ), m_pPanel( pPanel )
{
}
virtual void actionPerformed(Panel *panel)
{
m_pPanel->AddItem( m_pList, m_iWeaponSlot, m_iWeaponIndex );
}
private:
CItemSelectionPanel *m_pPanel;
playeritemlist_t *m_pList;
int m_iWeaponIndex;
int m_iWeaponSlot;
};
/*
==========
CommandButtonShaded
==========
*/
class CommandButtonShaded : public CommandButton
{
public:
CommandButtonShaded(const char *text,int x,int y,int wide,int tall,bool bNoHighlight);
void paint();
};
CommandButtonShaded::CommandButtonShaded(const char *text,int x,int y,int wide,int tall,bool bNoHighlight = 0) : CommandButton(text,x,y,wide,tall,bNoHighlight)
{
}
void CommandButtonShaded::paint()
{
if(!isArmed())
{
drawSetColor(TW_PANEL_BG_RGBA);
drawFilledRect(0,0,_size[0],_size[1]);
}
CommandButton::paint();
}
/*
==========
ItemButtonShaded
==========
*/
class ItemButtonShaded : public CommandButtonShaded
{
public:
ItemButtonShaded(const char *classname,int x,int y,int wide,int tall,bool bNoHighlight);
void setParent(Panel *newParent);
void paint();
private:
char m_szClassname[128];
};
ItemButtonShaded::ItemButtonShaded(const char *classname,int x,int y,int wide,int tall,bool bNoHighlight = 0) : CommandButtonShaded(classname,x,y,wide,tall,bNoHighlight)
{
char szRealText[128];
strcpy(m_szClassname,classname);
// Localize the text on the buttons
sprintf(szRealText,"#ItemList_%s",classname);
setText(CHudTextMessage::BufferedLocaliseTextString(szRealText));
}
void ItemButtonShaded::setParent(Panel *newParent)
{
CommandButtonShaded::setParent(newParent);
}
void ItemButtonShaded::paint()
{
CommandButtonShaded::paint();
if(isArmed())
{
CItemSelectionPanel *pPanel = (CItemSelectionPanel*)getParent();
if(pPanel != NULL)
pPanel->SetInfo(m_szClassname);
}
}
/*
==========
CItemList
Base class to show vgui buttons pertaining to categories of weapons
==========
*/
class CItemList
{
public:
CItemList(CItemSelectionPanel *pPanel, playeritemlist_t *pList, int iSlot, int iNextSlot ) :
m_pParentPanel( pPanel ), m_pItemArray( pList ), m_iSlot( iSlot ), m_iNextSlot( iNextSlot )
{
}
virtual ~CItemList()
{
for( int i = 0;i < m_ItemButtons.size();i++ )
{
m_pParentPanel->removeChild( m_ItemButtons[i] );
}
}
void BuildButtons()
{
int iButtonPosY = LIST_BUTTON_Y;
for( int i = 0;i < m_pItemArray->size; i++ )
{
playeritem_t *pItem = &m_pItemArray->array[i];
ItemButtonShaded *newButton;
newButton = new ItemButtonShaded( pItem->weapon_classname, LIST_BUTTON_X, iButtonPosY, BUTTON_SIZE_X, BUTTON_SIZE_Y );
newButton->setParent( m_pParentPanel );
newButton->addActionSignal( new CItemButtonHandler_SetItem( m_pItemArray, m_iSlot, i, m_pParentPanel ) );
newButton->addActionSignal( new CItemListHandler_NewItemList(m_iNextSlot,this) );
m_ItemButtons.push_back( newButton );
iButtonPosY += BUTTON_SIZE_Y + YRES(8);
}
CommandButtonShaded *backButton;
backButton = new CommandButtonShaded(CHudTextMessage::BufferedLocaliseTextString("#ItemList_Back"),LIST_BUTTON_X,iButtonPosY,BUTTON_SIZE_X,BUTTON_SIZE_Y);
backButton->setParent( m_pParentPanel );
backButton->addActionSignal(new CItemListHandler_NewItemList(ITEM_BACK,this));
m_ItemButtons.push_back( backButton );
m_iNumButtons = ++i;
}
playeritemlist_t *m_pItemArray;
int m_iSlot,m_iNextSlot;
CItemSelectionPanel *m_pParentPanel;
public:
std::vector<CommandButton*> m_ItemButtons;
int m_iNumButtons;
};
class CMainCategories : public CItemList
{
public:
CMainCategories(CItemSelectionPanel *pPanel, playeritemlist_t *pList ) : CItemList(pPanel, pList, -1, -1)
{
int iButtonPosY = LIST_BUTTON_Y;
m_pMeleeButton = new CommandButtonShaded(CHudTextMessage::BufferedLocaliseTextString("#ItemList_Melee"),LIST_BUTTON_X,iButtonPosY,BUTTON_SIZE_X,BUTTON_SIZE_Y);
m_pMeleeButton->setParent(m_pParentPanel);
m_pMeleeButton->addActionSignal(new CItemListHandler_NewItemList(ITEM_MELEE,this));
iButtonPosY += BUTTON_SIZE_Y + YRES(8);
m_pSidearmsButton = new CommandButtonShaded(CHudTextMessage::BufferedLocaliseTextString("#ItemList_Sidearms"),LIST_BUTTON_X,iButtonPosY,BUTTON_SIZE_X,BUTTON_SIZE_Y);
m_pSidearmsButton->setParent(m_pParentPanel);
m_pSidearmsButton->addActionSignal(new CItemListHandler_NewItemList(ITEM_SIDEARMS,this));
iButtonPosY += BUTTON_SIZE_Y + YRES(8);
m_pSecondaryButton = new CommandButtonShaded(CHudTextMessage::BufferedLocaliseTextString("#ItemList_Secondary"),LIST_BUTTON_X,iButtonPosY,BUTTON_SIZE_X,BUTTON_SIZE_Y);
m_pSecondaryButton->setParent(m_pParentPanel);
m_pSecondaryButton->addActionSignal(new CItemListHandler_NewItemList(ITEM_PRIMARY,this));
iButtonPosY += BUTTON_SIZE_Y + YRES(8);
m_pExplosivesButton = new CommandButtonShaded(CHudTextMessage::BufferedLocaliseTextString("#ItemList_Explosives"),LIST_BUTTON_X,iButtonPosY,BUTTON_SIZE_X,BUTTON_SIZE_Y);
m_pExplosivesButton->setParent(m_pParentPanel);
m_pExplosivesButton->addActionSignal(new CItemListHandler_NewItemList(ITEM_EXPLOSIVES,this));
// No uniques for now :|
/* iButtonPosY += BUTTON_SIZE_Y + YRES(8);
m_pUniqueButton = new CommandButtonShaded(CHudTextMessage::BufferedLocaliseTextString("#ItemList_Unique"),LIST_BUTTON_X,iButtonPosY,BUTTON_SIZE_X,BUTTON_SIZE_Y);
m_pUniqueButton->setParent(m_pParentPanel);
m_pUniqueButton->addActionSignal(new CItemListHandler_NewItemList(ITEM_UNIQUE,this));
*/
iButtonPosY += BUTTON_SIZE_Y + YRES(8);
}
~CMainCategories()
{
m_pParentPanel->removeChild(m_pMeleeButton);
m_pParentPanel->removeChild(m_pSidearmsButton);
m_pParentPanel->removeChild(m_pSecondaryButton);
m_pParentPanel->removeChild(m_pExplosivesButton);
// m_pParentPanel->removeChild(m_pUniqueButton);
}
private:
CommandButtonShaded *m_pMeleeButton;
CommandButtonShaded *m_pSidearmsButton;
CommandButtonShaded *m_pSecondaryButton;
CommandButtonShaded *m_pExplosivesButton;
// CommandButtonShaded *m_pUniqueButton;
};
/*
CItemSelectionPanel methods
*/
CItemSelectionPanel::CItemSelectionPanel(int x,int y,int wide,int tall) : CMenuPanel(100,false,x,y,wide,tall)
{
memset( m_iWeaponIndices, -1, sizeof( m_iWeaponIndices ) );
// Start up selection images
for(int i = 0;i < 5;i++)
{
m_pImageLabels[i] = new CImageLabel("",0,0);
m_pImageLabels[i]->setParent(this);
m_pImageLabels[i]->setVisible(false);
}
// Load the item manager
m_pItemList = new CMainCategories(this, NULL );
// Information Panel
m_pInformationPanel = new CInformationPanel(INFO_PANEL_X,INFO_PANEL_Y,INFO_PANEL_SIZE_X,INFO_PANEL_SIZE_Y);
m_pInformationPanel->setParent(this);
m_pInformationPanel->setVisible(true);
int iButtonPosX = MAIN_BUTTON_X;
CommandButtonShaded *pOkButton = new CommandButtonShaded(CHudTextMessage::BufferedLocaliseTextString("#Menu_JoinGame"), iButtonPosX, MAIN_BUTTON_Y, BUTTON_SIZE_X, BUTTON_SIZE_Y );
pOkButton->setParent(this);
// pOkButton->addActionSignal(new CMenuHandler_TextWindow(HIDE_TEXTWINDOW));
pOkButton->addActionSignal(new CHandler_SendChanges(this));
iButtonPosX += XRES(168);
CommandButtonShaded *pRandomButton = new CommandButtonShaded(CHudTextMessage::BufferedLocaliseTextString("#Menu_Random"), iButtonPosX,MAIN_BUTTON_Y, BUTTON_SIZE_X, BUTTON_SIZE_Y );
pRandomButton->setParent(this);
pRandomButton->addActionSignal(new CMenuHandler_TextWindow(HIDE_TEXTWINDOW));
pRandomButton->addActionSignal(new CMenuHandler_StringCommand("setrandom"));
pRandomButton->addActionSignal(new CMenuHandler_StringCommand("join_game"));
iButtonPosX += XRES(168);
CommandButtonShaded *pSpectateButton = new CommandButtonShaded(CHudTextMessage::BufferedLocaliseTextString("#Menu_Spectate"), iButtonPosX, MAIN_BUTTON_Y, BUTTON_SIZE_X,BUTTON_SIZE_Y );
pSpectateButton->setParent(this);
pSpectateButton->addActionSignal(new CMenuHandler_TextWindow(HIDE_TEXTWINDOW));
pSpectateButton->addActionSignal(new CMenuHandler_StringCommand("spectate"));
}
CItemSelectionPanel::~CItemSelectionPanel()
{
delete m_pItemList;
for( int i = 0;i < 5;i++ )
delete m_pImageLabels[i];
}
void CItemSelectionPanel::SetInfo(char *pszClassname)
{
m_pInformationPanel->SetInfo(pszClassname);
}
void CItemSelectionPanel::SetImage(const char *pszClassname,int iIndex)
{
// Show image
char szImageName[128];
sprintf(szImageName,"inv_%s",pszClassname);
m_pImageLabels[iIndex]->NewImage(szImageName);
m_pImageLabels[iIndex]->setVisible(true);
m_pImageLabels[iIndex]->setImageColor(Color(255,255,255,160)); // Slightly faded
// Set image bounds
int x, y;
int w,h;
w = m_pImageLabels[iIndex]->getImageWide();
h = m_pImageLabels[iIndex]->getImageTall();
switch( iIndex )
{
case 0:
x = IMAGE_PANEL_X;
y = IMAGE_PANEL_Y;
break;
case 1:
x = IMAGE_PANEL_X;
y = IMAGE_PANEL_Y + h + YRES(8);
break;
case 2:
x = IMAGE_PANEL_X + w + XRES(8);
y = IMAGE_PANEL_Y;
break;
case 3:
case 4:
x = IMAGE_PANEL_X + w + XRES(8);
y = IMAGE_PANEL_Y + h + YRES(8);
break;
}
m_pImageLabels[iIndex]->setPos( x, y );
}
void CItemSelectionPanel::paintBackground()
{
drawSetColor(TW_PANEL_BORDER_RGBA);
drawOutlinedRect(0,0,_size[0],_size[1]);
}
void CItemSelectionPanel::AddItem( playeritemlist_t *pList, int iSlot, int iIndex )
{
m_iWeaponIndices[iSlot] = iIndex;
SetImage( pList->array[iIndex].weapon_classname, iSlot );
}
void CItemSelectionPanel::SendItems()
{
// Must have a melee or backup weapon to spawn.
if( m_iWeaponIndices[0] == -1 )
{
gEngfuncs.pfnCenterPrint( "Must choose a melee weapon" );
return;
}
gViewPort->HideTopMenu();
char szText[64];
sprintf( szText, "setweapons %i %i %i %i %i",
m_iWeaponIndices[0], m_iWeaponIndices[1], m_iWeaponIndices[2],
m_iWeaponIndices[3], m_iWeaponIndices[4] );
gEngfuncs.pfnClientCmd( "unsetrandom" );
gEngfuncs.pfnClientCmd( szText );
gEngfuncs.pfnClientCmd( "join_game" );
}
/*
CInformationPanel methods
*/
CInformationPanel::CInformationPanel(int x,int y,int wide,int tall) : CTransparentPanel(0,x,y,wide,tall)
{
memset( m_szClassname, 0, sizeof( m_szClassname ) );
m_pImageLabel = new CImageLabel("",0,0);
m_pImageLabel->setParent(this);
m_pImageLabel->setVisible(false);
// Get the scheme used for the Titles
CSchemeManager *pSchemes = gViewPort->GetSchemeManager();
// schemes
SchemeHandle_t hTitleScheme = pSchemes->getSchemeHandle( "Title Font" );
SchemeHandle_t hMOTDText = pSchemes->getSchemeHandle( "Briefing Text" );
// color schemes
int r, g, b, a;
m_pScrollPanel = new CTFScrollPanel(XRES(16),YRES(16), wide - XRES(32), tall - YRES(32));
m_pScrollPanel->setParent(this);
// force scrollbars on to set clientClip
m_pScrollPanel->setScrollBarAutoVisible(false, false);
m_pScrollPanel->setScrollBarVisible(true, true);
m_pScrollPanel->validate();
m_pTextPanel = new TextPanel("",0,0,64,64);
m_pTextPanel->setParent(m_pScrollPanel->getClient());
// Set font
m_pTextPanel->setFont(pSchemes->getFont(hMOTDText));
pSchemes->getFgColor(hMOTDText,r,g,b,a);
m_pTextPanel->setFgColor(r,g,b,a);
pSchemes->getBgColor(hMOTDText,r,g,b,a);
m_pTextPanel->setBgColor(r,g,b,a);
}
void CInformationPanel::SetInfo( char *pszClassname )
{
// Dont update if we are already showing info
if( strcmp( pszClassname, m_szClassname ) == 0 )
return;
strcpy( m_szClassname, pszClassname );
// Show image
char szImageName[128];
sprintf(szImageName,"info_%s",pszClassname);
m_pImageLabel->NewImage(szImageName);
m_pImageLabel->setVisible(true);
m_pImageLabel->setImageColor(Color(255,255,255,160)); // Slightly faded
// Set image bounds
int w,h;
getSize(w,h);
m_pImageLabel->setPos(w/2 - m_pImageLabel->getImageWide()/2,h/2 - m_pImageLabel->getImageTall()/2);
// Set text
char szLocalizedClass[128];
sprintf(szLocalizedClass,"#Information_%s",pszClassname);
m_pTextPanel->setText(CHudTextMessage::BufferedLocaliseTextString(szLocalizedClass));
// Get the total size of the MOTD text and resize the text panel
int iScrollSizeX, iScrollSizeY;
// First, set the size so that the client's width is correct at least because the
// width is critical for getting the "wrapped" size right.
// You'll see a horizontal scroll bar if there is a single word that won't wrap in the
// specified width.
m_pTextPanel->getTextImage()->setSize(m_pScrollPanel->getClientClip()->getWide(), m_pScrollPanel->getClientClip()->getTall());
m_pTextPanel->getTextImage()->getTextSizeWrapped( iScrollSizeX, iScrollSizeY );
// Now resize the textpanel to fit the scrolled size
m_pTextPanel->setSize( iScrollSizeX , iScrollSizeY );
//turn the scrollbars back into automode
m_pScrollPanel->setScrollBarAutoVisible(true, true);
m_pScrollPanel->setScrollBarVisible(false, false);
m_pScrollPanel->validate();
}
/*
CItemListHandler_NewItemList methods
*/
CItemListHandler_NewItemList::CItemListHandler_NewItemList(int iCategory,CItemList *pItemList)
{
m_iCategory = iCategory;
m_pOldItemList = pItemList;
}
void CItemListHandler_NewItemList::actionPerformed(Panel *panel)
{
CItemSelectionPanel *pParent = m_pOldItemList->m_pParentPanel;
delete m_pOldItemList;
switch( m_iCategory )
{
case ITEM_MELEE:
m_pOldItemList = new CItemList( pParent, &g_MeleeItems, ITEM_MELEE, ITEM_SIDEARMS );
m_pOldItemList->BuildButtons();
break;
case ITEM_SIDEARMS:
m_pOldItemList = new CItemList( pParent, &g_SidearmItems, ITEM_SIDEARMS, ITEM_PRIMARY );
m_pOldItemList->BuildButtons();
break;
case ITEM_PRIMARY:
m_pOldItemList = new CItemList( pParent, &g_PrimaryItems, ITEM_PRIMARY, ITEM_EXPLOSIVES );
m_pOldItemList->BuildButtons();
break;
/* case ITEM_UNIQUE:
m_pOldItemList = new CItemList( pParent, &g_UniqueItems, 3 );
m_pOldItemList->BuildButtons();
break;*/
case ITEM_EXPLOSIVES:
m_pOldItemList = new CItemList( pParent, &g_OtherItems, ITEM_EXPLOSIVES, ITEM_BACK );
m_pOldItemList->BuildButtons();
break;
case ITEM_BACK:
m_pOldItemList = new CMainCategories( pParent, NULL );
break;
}
}