diff --git a/dlls/multiplay_gamerules.cpp b/dlls/multiplay_gamerules.cpp index 20203d15..e5483255 100644 --- a/dlls/multiplay_gamerules.cpp +++ b/dlls/multiplay_gamerules.cpp @@ -94,7 +94,7 @@ void CoopClearWeaponList( void ) { g_WeaponList.Clear(); } - +extern int g_iMenu; void BecomeSpectator( CBasePlayer *pPlayer ) { @@ -126,7 +126,7 @@ void SpawnPlayer( CBasePlayer *pPlayer ) extern int gmsgShowMenu; -void ShowMenu( CBasePlayer *pPlayer, const char *title, int count, const char **slot ) +void ShowMenu( CBasePlayer *pPlayer, const char *title, int count, const char **slot, signed char time = -1 ) { char buf[128], *pbuf = buf; short int flags = 1<<9; @@ -138,7 +138,7 @@ void ShowMenu( CBasePlayer *pPlayer, const char *title, int count, const char ** } MESSAGE_BEGIN(MSG_ONE, gmsgShowMenu, NULL, pPlayer->pev); WRITE_SHORT( flags ); // slots - WRITE_CHAR( -1 ); // show time + WRITE_CHAR( time ); // show time WRITE_BYTE( 0 ); // need more WRITE_STRING( buf ); MESSAGE_END(); @@ -156,7 +156,7 @@ void CoopMenu( CBasePlayer *pPlayer ) "Force respawn", "Unblock", "Become spectator", - //"Vote changelevel" + "Vote changelevel" }; ShowMenu( pPlayer, "Coop menu", ARRAYSIZE( menu ), menu ); } @@ -174,7 +174,7 @@ void CoopMenu( CBasePlayer *pPlayer ) } } -int g_iMenu; +void CoopVoteMenu( CBasePlayer *pPlayer ); //********************************************************* @@ -228,6 +228,8 @@ CHalfLifeMultiplay::CHalfLifeMultiplay() } } +void CoopProcessMenu( CBasePlayer *pPlayer, int imenu ); + BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) { #ifndef NO_VOICEGAMEMGR @@ -246,6 +248,7 @@ BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) if( FStrEq( pcmd, "menuselect" ) ) { int imenu = atoi( CMD_ARGV( 1 ) ); + switch( pPlayer->m_state ) { case STATE_SPECTATOR_BEGIN: @@ -259,6 +262,11 @@ BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) pPlayer->m_state = STATE_SPECTATOR; } case STATE_SPAWNED: + if( g_iMenu ) + { + CoopProcessMenu( pPlayer, imenu ); + return TRUE; + } if( imenu == 1 ) { SpawnPlayer( pPlayer ); @@ -272,6 +280,10 @@ BOOL CHalfLifeMultiplay::ClientCommand( CBasePlayer *pPlayer, const char *pcmd ) pPlayer->RemoveAllItems( TRUE ); BecomeSpectator( pPlayer ); } + if( imenu == 4 ) + { + CoopVoteMenu( pPlayer ); + } default: break; } diff --git a/dlls/triggers.cpp b/dlls/triggers.cpp index 5bd8b956..19574cb4 100644 --- a/dlls/triggers.cpp +++ b/dlls/triggers.cpp @@ -1513,6 +1513,146 @@ void CoopClearData( void ) SavedCoords l_SavedCoords = {}; g_SavedCoords = l_SavedCoords; } +int g_iMenu; +void ShowMenu( CBasePlayer *pPlayer, const char *title, int count, const char **slot, signed char time = -1 ); +// Show to all spawned players: voting, etc.. +class GlobalMenu +{ +public: + + int m_iConfirm; + int m_iVoteCount; + int m_iMaxCount; + float flTime; + const char *maps[5]; + int votes[5]; + CBaseEntity *triggers[5]; + EHANDLE m_pTrigger; + + void Process( CBasePlayer *pPlayer, int imenu ) + { + if( pPlayer->pev->flags & FL_SPECTATOR ) + return; + if( gpGlobals->time - flTime > 30 ) + { + g_iMenu = 0; + return; + } + + switch( g_iMenu ) + { + case 1: // touch blue trigger + m_iVoteCount++; + if( imenu == 1 ) // confirm + { + m_iConfirm++; + } + if( imenu == 2 ) // cancel + { + m_iConfirm--; + } + break; + case 2: // vote by request + if( imenu < m_iConfirm ) + { + votes[imenu]++; + m_iVoteCount++; + if( m_iVoteCount == m_iMaxCount ) + { + for( int i = 0; i < m_iConfirm; i++ ) + if( votes[i] == m_iMaxCount ) + { + if( triggers[i]) + triggers[i]->Use( NULL, NULL, USE_TOGGLE, 0 ); + g_iMenu = 0; + } + + } + + } + } + } + void ShowGlobalMenu( const char *title, int count, const char **menu ) + { + int count2 = 0; + for( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBaseEntity *plr = UTIL_PlayerByIndex( i ); + + if( plr && plr->IsPlayer() ) + { + count2++; + ShowMenu( (CBasePlayer *)plr, title, count, menu, 30 ); + + } + } + m_iMaxCount = count2; + } + + void ConfirmMenu( CBaseEntity *trigger, const char *mapname ) + { + if( g_iMenu && gpGlobals->time - flTime < 30 ) + return; // wait 30s befor new confirm vote + g_iMenu = 1; + flTime = gpGlobals->time; + m_pTrigger = trigger; + const char *menu[] = { + "Confirm", + "Cancel" + }; + ShowGlobalMenu(UTIL_VarArgs("Confirm changing map to %s?", mapname), ARRAYSIZE(menu), menu); + + } + void VoteMenu( CBasePlayer *player ) + { + if( g_iMenu && gpGlobals->time - flTime < 30 ) + return; // wait 30s befor new confirm vote + CBaseEntity *pTrigger = NULL; + int i; + g_iMenu = 2; + while( pTrigger = UTIL_FindEntityByClassname( pTrigger, "trigger_changelevel" ) ) + { + CChangeLevel *ent = (CChangeLevel *)pTrigger; + votes[i] = 0; + triggers[i] = pTrigger; + maps[i++] = ent->m_szMapName; + + + } + votes[i] = 0; + triggers[i] = NULL; + maps[i++] = "Keep this map"; + m_iConfirm = i; + m_iVoteCount = 0; + ShowGlobalMenu(UTIL_VarArgs("%s requested to force change map", ""), i, maps); + + } + + +}; +GlobalMenu g_GlobalMenu; + +void CoopVoteMenu( CBasePlayer *pPlayer ) +{ + int count; + for( int i = 1; i <= gpGlobals->maxClients; i++ ) + { + CBaseEntity *plr = UTIL_PlayerByIndex( i ); + + if( plr && plr->IsPlayer() ) + { + count++; + } + } + if( count < 5 ) + return; + g_GlobalMenu.VoteMenu(pPlayer); +} + +void CoopProcessMenu( CBasePlayer *pPlayer, int imenu ) +{ + return g_GlobalMenu.Process( pPlayer, imenu ); +} static void validateoffset( void ) { @@ -1739,19 +1879,13 @@ void CChangeLevel::ChangeLevelNow( CBaseEntity *pActivator ) if( m_fIsBack ) { - if( count2 - count1 > 1 ) + if( g_iMenu != 1 ) { - UTIL_HudMessageAll( params, UTIL_VarArgs( "%s requested to changelevel backwards, but not enough players\n", - ( pActivator->pev->netname && STRING( pActivator->pev->netname )[0] != 0 ) ? STRING( pActivator->pev->netname ) : "unconnected", - st_szNextMap, st_szNextSpot, i ) ); + g_GlobalMenu.ConfirmMenu( this, m_szMapName ); return; } - /* not done, need to send confirmation menus - else if (g_SavedCoords.changeback < 2) - { - UTIL_ChangebackMenu(( pActivator->pev->netname && STRING( pActivator->pev->netname )[0] != 0 ) ? STRING( pActivator->pev->netname ) : "unconnected"); + if( g_GlobalMenu.m_iConfirm < count2 ) return; - }*/ } if( m_fSpawnSaved )