You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
415 lines
11 KiB
415 lines
11 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
// $NoKeywords: $ |
|
//============================================================================= |
|
|
|
#include "cbase.h" |
|
#include "hud.h" |
|
#include "hudelement.h" |
|
#include "c_tf_player.h" |
|
#include "iclientmode.h" |
|
#include <vgui/ILocalize.h> |
|
#include <vgui/ISurface.h> |
|
#include <vgui/IVGui.h> |
|
#include "c_baseobject.h" |
|
#include "inputsystem/iinputsystem.h" |
|
|
|
#include "tf_hud_menu_eureka_teleport.h" |
|
|
|
// NVNT haptics for buildings |
|
#include "haptics/haptic_utils.h" |
|
|
|
// memdbgon must be the last include file in a .cpp file!!! |
|
#include "tier0/memdbgon.h" |
|
|
|
using namespace vgui; |
|
|
|
// Set to 1 to simulate xbox-style menu interaction |
|
extern ConVar tf_build_menu_controller_mode; |
|
|
|
|
|
DECLARE_HUDELEMENT_DEPTH( CHudEurekaEffectTeleportMenu, 41 ); // in front of engy building status |
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
CHudEurekaEffectTeleportMenu::CHudEurekaEffectTeleportMenu( const char *pElementName ) |
|
: CHudElement( pElementName ) |
|
, BaseClass( NULL, "HudEurekaEffectTeleportMenu" ) |
|
, m_bWantsToTeleport( false ) |
|
, m_eSelectedTeleportTarget( EUREKA_TELEPORT_HOME ) |
|
, m_eCurrentBuildMenuLayout( BUILDMENU_DEFAULT ) |
|
{ |
|
Panel *pParent = g_pClientMode->GetViewport(); |
|
SetParent( pParent ); |
|
|
|
SetHiddenBits( HIDEHUD_MISCSTATUS ); |
|
|
|
vgui::ivgui()->AddTickSignal( GetVPanel() ); |
|
|
|
for( int i=0; i < EUREKA_NUM_TARGETS; ++i ) |
|
{ |
|
m_pAvilableTargets[ i ] = new EditablePanel( this, VarArgs( "available_target_%d", i+1 ) ); |
|
m_pUnavailableTargets[ i ] = new EditablePanel( this, VarArgs( "unavailable_target_%d", i+1 ) ); |
|
} |
|
|
|
RegisterForRenderGroup( "mid" ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudEurekaEffectTeleportMenu::ApplySchemeSettings( IScheme *pScheme ) |
|
{ |
|
const char *pszCustomDir = NULL; |
|
switch( m_eCurrentBuildMenuLayout ) |
|
{ |
|
case BUILDMENU_PIPBOY: |
|
pszCustomDir = "resource/UI/build_menu/pipboy"; |
|
break; |
|
|
|
default: |
|
case BUILDMENU_DEFAULT: |
|
if ( ::input->IsSteamControllerActive() ) |
|
{ |
|
pszCustomDir = "resource/UI/build_menu_sc"; |
|
} |
|
else |
|
{ |
|
pszCustomDir = "resource/UI/build_menu"; |
|
} |
|
break; |
|
} |
|
|
|
LoadControlSettings( VarArgs( "%s/HudMenuEurekaEffect.res", pszCustomDir) ); |
|
|
|
m_pAvilableTargets[ EUREKA_TELEPORT_HOME ]->LoadControlSettings( VarArgs( "%s/eureka_target_home_avail.res", pszCustomDir ) ); |
|
m_pAvilableTargets[ EUREKA_TELEPORT_TELEPORTER_EXIT ]->LoadControlSettings( VarArgs( "%s/eureka_target_tele_exit_avail.res", pszCustomDir ) ); |
|
|
|
m_pUnavailableTargets[ EUREKA_TELEPORT_HOME ]->LoadControlSettings( VarArgs( "%s/eureka_target_home_unavail.res", pszCustomDir ) ); |
|
m_pUnavailableTargets[ EUREKA_TELEPORT_TELEPORTER_EXIT ]->LoadControlSettings( VarArgs( "%s/eureka_target_tele_exit_unavail.res", pszCustomDir ) ); |
|
|
|
BaseClass::ApplySchemeSettings( pScheme ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CHudEurekaEffectTeleportMenu::ShouldDraw( void ) |
|
{ |
|
if ( !CanTeleport() ) |
|
{ |
|
m_bWantsToTeleport = false; |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudEurekaEffectTeleportMenu::SetVisible( bool bState ) |
|
{ |
|
if ( bState == true ) |
|
{ |
|
// close the weapon selection menu |
|
engine->ClientCmd( "cancelselect" ); |
|
|
|
// See if our layout needs to change, due to equipped items |
|
buildmenulayouts_t eDesired = CHudMenuEngyBuild::CalcCustomBuildMenuLayout(); |
|
if ( eDesired != m_eCurrentBuildMenuLayout ) |
|
{ |
|
m_eCurrentBuildMenuLayout = eDesired; |
|
InvalidateLayout( true, true ); |
|
} |
|
|
|
const char* key = engine->Key_LookupBinding( "lastinv" ); |
|
if ( !key ) |
|
{ |
|
key = "< not bound >"; |
|
} |
|
|
|
SetDialogVariable( "lastinv", key ); |
|
|
|
// Set selection to the first available building that we can build |
|
|
|
C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); |
|
|
|
if ( !pLocalPlayer ) |
|
return; |
|
|
|
m_eSelectedTeleportTarget = EUREKA_TELEPORT_HOME; |
|
SetSelectedItem( m_eSelectedTeleportTarget ); |
|
|
|
HideLowerPriorityHudElementsInGroup( "mid" ); |
|
} |
|
else |
|
{ |
|
UnhideLowerPriorityHudElementsInGroup( "mid" ); |
|
} |
|
|
|
BaseClass::SetVisible( bState ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
bool CHudEurekaEffectTeleportMenu::CanTeleport() const |
|
{ |
|
if ( !m_bWantsToTeleport ) |
|
return false; |
|
|
|
CTFPlayer *pPlayer = C_TFPlayer::GetLocalTFPlayer(); |
|
if ( !pPlayer ) |
|
return false; |
|
|
|
CTFWeaponBase *pWpn = pPlayer->GetActiveTFWeapon(); |
|
|
|
if ( !pWpn ) |
|
return false; |
|
|
|
// Don't show the menu for first person spectator |
|
if ( pPlayer != pWpn->GetOwner() ) |
|
return false; |
|
|
|
if ( !const_cast<CHudEurekaEffectTeleportMenu*>(this)->CHudElement::ShouldDraw() ) |
|
return false; |
|
|
|
return ( pWpn->GetWeaponID() == TF_WEAPON_WRENCH ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudEurekaEffectTeleportMenu::SendTeleportMessage( eEurekaTeleportTargets eTeleportTarget ) |
|
{ |
|
// They've made their selection. Setting this to false will close this panel. |
|
m_bWantsToTeleport = false; |
|
|
|
C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); |
|
|
|
if ( !pLocalPlayer ) |
|
return; |
|
|
|
// We do code elsewhere that set the available targets panel visible if they're available. |
|
// If it's not visible, it's not available. |
|
|
|
// Can not use while karting |
|
if ( !m_pAvilableTargets[ eTeleportTarget ]->IsVisible() || pLocalPlayer->m_Shared.InCond( TF_COND_HALLOWEEN_KART ) ) |
|
{ |
|
pLocalPlayer->EmitSound( "Player.DenyWeaponSelection" ); |
|
return; |
|
} |
|
|
|
char szCmd[128]; |
|
Q_snprintf( szCmd, sizeof(szCmd), "eureka_teleport %d", (int)eTeleportTarget ); |
|
engine->ClientCmd( szCmd ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
int CHudEurekaEffectTeleportMenu::HudElementKeyInput( int down, ButtonCode_t keynum, const char *pszCurrentBinding ) |
|
{ |
|
if ( !ShouldDraw() ) |
|
{ |
|
return 1; |
|
} |
|
|
|
if ( !down ) |
|
{ |
|
return 1; |
|
} |
|
|
|
bool bConsoleController = ( IsConsole() || ( keynum >= JOYSTICK_FIRST && !IsSteamControllerCode(keynum)) ); |
|
|
|
if ( bConsoleController ) |
|
{ |
|
int nNewSelection = m_eSelectedTeleportTarget; |
|
|
|
switch( keynum ) |
|
{ |
|
case KEY_XBUTTON_UP: |
|
// jump to last |
|
nNewSelection = EUREKA_LAST_TARGET; |
|
break; |
|
|
|
case KEY_XBUTTON_DOWN: |
|
// jump to first |
|
nNewSelection = EUREKA_FIRST_TARGET; |
|
break; |
|
|
|
case KEY_XBUTTON_RIGHT: |
|
// move selection to the right |
|
nNewSelection++; |
|
if ( nNewSelection > EUREKA_LAST_TARGET ) |
|
nNewSelection = EUREKA_FIRST_TARGET; |
|
break; |
|
|
|
case KEY_XBUTTON_LEFT: |
|
// move selection to the left |
|
nNewSelection--; |
|
if ( nNewSelection <= 0 ) |
|
nNewSelection = EUREKA_LAST_TARGET; |
|
break; |
|
|
|
case KEY_XBUTTON_A: |
|
case KEY_XBUTTON_RTRIGGER: |
|
case KEY_XBUTTON_Y: |
|
case KEY_XBUTTON_LTRIGGER: |
|
// build selected item |
|
SendTeleportMessage( (eEurekaTeleportTargets)nNewSelection ); |
|
return 0; |
|
|
|
case KEY_XBUTTON_B: |
|
// cancel, close the menu |
|
engine->ExecuteClientCmd( "lastinv" ); |
|
return 0; |
|
|
|
default: |
|
return 1; // key not handled |
|
} |
|
|
|
SetSelectedItem( (eEurekaTeleportTargets)nNewSelection ); |
|
|
|
return 0; |
|
} |
|
else |
|
{ |
|
int iSlot = 0; |
|
|
|
// convert slot1, slot2 etc to 1,2,3,4 |
|
if( pszCurrentBinding && ( !Q_strncmp( pszCurrentBinding, "slot", NUM_ENGY_BUILDINGS ) && Q_strlen(pszCurrentBinding) > NUM_ENGY_BUILDINGS ) ) |
|
{ |
|
const char *pszNum = pszCurrentBinding+NUM_ENGY_BUILDINGS; |
|
iSlot = atoi(pszNum); |
|
|
|
// slot10 cancels |
|
if ( iSlot == 10 ) |
|
{ |
|
engine->ExecuteClientCmd( "lastinv" ); |
|
return 0; |
|
} |
|
|
|
// allow slot1 - slot4 |
|
if ( iSlot < 1 || iSlot > EUREKA_NUM_TARGETS ) |
|
return 1; |
|
} |
|
else |
|
{ |
|
switch( keynum ) |
|
{ |
|
case KEY_1: |
|
iSlot = 1; |
|
break; |
|
case KEY_2: |
|
iSlot = 2; |
|
break; |
|
case KEY_3: |
|
case KEY_4: |
|
case KEY_5: |
|
case KEY_6: |
|
case KEY_7: |
|
case KEY_8: |
|
case KEY_9: |
|
// Eat these keys |
|
return 0; |
|
|
|
case KEY_0: |
|
case KEY_XBUTTON_B: |
|
case STEAMCONTROLLER_B: |
|
// cancel, close the menu |
|
engine->ExecuteClientCmd( "lastinv" ); |
|
return 0; |
|
|
|
case STEAMCONTROLLER_DPAD_LEFT: |
|
SendTeleportMessage( EUREKA_TELEPORT_HOME ); |
|
return 0; |
|
|
|
case STEAMCONTROLLER_DPAD_RIGHT: |
|
SendTeleportMessage( EUREKA_TELEPORT_TELEPORTER_EXIT ); |
|
return 0; |
|
|
|
default: |
|
return 1; // key not handled |
|
} |
|
} |
|
|
|
if ( iSlot > 0 ) |
|
{ |
|
SendTeleportMessage( (eEurekaTeleportTargets)(iSlot-1) ); |
|
return 0; |
|
} |
|
} |
|
|
|
return 1; // key not handled |
|
} |
|
|
|
|
|
void CHudEurekaEffectTeleportMenu::WantsToTeleport() |
|
{ |
|
m_bWantsToTeleport = true; |
|
InvalidateLayout( true, true ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudEurekaEffectTeleportMenu::SetSelectedItem( eEurekaTeleportTargets eSelectedTeleportTarget ) |
|
{ |
|
if ( m_eSelectedTeleportTarget != eSelectedTeleportTarget ) |
|
{ |
|
m_eSelectedTeleportTarget = eSelectedTeleportTarget; |
|
|
|
// move the selection item to the new position |
|
if ( m_pActiveSelection ) |
|
{ |
|
// move the selection background |
|
int x, y; |
|
m_pAvilableTargets[m_eSelectedTeleportTarget]->GetPos( x, y ); |
|
|
|
x -= XRES(4); |
|
y -= XRES(4); |
|
|
|
m_pActiveSelection->SetPos( x, y ); |
|
|
|
UpdateHintLabels(); |
|
} |
|
} |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudEurekaEffectTeleportMenu::OnTick( void ) |
|
{ |
|
if ( !IsVisible() ) |
|
return; |
|
|
|
C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); |
|
|
|
if ( !pLocalPlayer ) |
|
return; |
|
|
|
m_pAvilableTargets[ EUREKA_TELEPORT_HOME ]->SetVisible( true ); |
|
m_pUnavailableTargets[ EUREKA_TELEPORT_HOME ]->SetVisible( false ); |
|
|
|
const C_BaseObject *pObj = pLocalPlayer->GetObjectOfType( OBJ_TELEPORTER, MODE_TELEPORTER_EXIT ); |
|
bool bTeleAvailable = pObj |
|
&& !pObj->IsBuilding() |
|
&& !pObj->IsPlacing() |
|
&& !pObj->IsUpgrading() |
|
&& !pObj->IsCarried(); |
|
|
|
m_pAvilableTargets[ EUREKA_TELEPORT_TELEPORTER_EXIT ]->SetVisible( bTeleAvailable ); |
|
m_pUnavailableTargets[ EUREKA_TELEPORT_TELEPORTER_EXIT ]->SetVisible( !bTeleAvailable ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CHudEurekaEffectTeleportMenu::UpdateHintLabels( void ) |
|
{ |
|
} |