etqw-sdk/source/game/Game_ui.cpp

2442 lines
67 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#include "precompiled.h"
#pragma hdrstop
#if defined( _DEBUG ) && !defined( ID_REDIRECT_NEWDELETE )
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "../framework/Licensee.h"
#include "roles/Inventory.h"
#include "roles/FireTeams.h"
#include "roles/ObjectiveManager.h"
#include "roles/Tasks.h"
#include "structures/TeamManager.h"
#include "rules/GameRules.h"
#include "Player.h"
#include "../framework/BuildVersion.h"
#include "../framework/KeyInput.h"
#include "guis/UserInterfaceLocal.h"
#include "guis/UserInterfaceManagerLocal.h"
#include "guis/UIList.h"
#include "guis/UIRadialMenu.h"
#include "CommandMapInfo.h"
#include "demos/DemoManager.h"
#include "rules/UserGroup.h"
#include "rules/AdminSystem.h"
#include "rules/VoteManager.h"
#include "Atmosphere.h"
#include "misc/Door.h"
#include "vehicles/Transport.h"
#include "vehicles/VehicleWeapon.h"
#include "ScriptEntity.h"
#include "Waypoints/LocationMarker.h"
#include "proficiency/StatsTracker.h"
#include "../framework/async/Demo.h"
#include "../sys/sys_local.h"
#ifndef _XENON
#include "../sdnet/SDNet.h"
#endif
#define ON_UIVALID( handle, thename ) sdUserInterfaceLocal* thename = GetUserInterface( handle ); if ( thename )
#define ON_UIINVALID( handle, thename ) sdUserInterfaceLocal* thename = GetUserInterface( handle ); if ( !thename )
idList< qhandle_t > idGameLocal::taskListHandles;
/*
================
idGameLocal::HandleGuiEvent
================
*/
bool idGameLocal::HandleGuiEvent( const sdSysEvent* event ) {
if ( networkSystem->IsDedicated() ) {
return false;
}
ON_UIVALID( uiMainMenuHandle, ui ) {
if ( ui->IsActive() ) {
return ui->PostEvent( event );
}
}
sdHudModule* module = localPlayerProperties.GetActiveHudModule();
if ( module && module->HandleGuiEvent( event ) ) {
return true;
}
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
if ( localPlayer ) {
if( isServer && event->GetKey() == K_F1 && event->IsKeyDown() && isPaused && localPlayer->IsSinglePlayerToolTipPlaying() ) {
cmdSystem->BufferCommandText( CMD_EXEC_APPEND, "unPauseGame\n" );
return true;
}
if ( localPlayer->HandleGuiEvent( event ) ) {
return true;
}
}
if ( rules ) {
if ( rules->HandleGuiEvent( event ) ) {
return true;
}
}
return false;
}
/*
================
idGameLocal::TranslateGuiBind
================
*/
bool idGameLocal::TranslateGuiBind( const idKey& key, sdKeyCommand** cmd ) {
ON_UIVALID( uiMainMenuHandle, ui ) {
if ( ui->IsActive() ) {
if ( ui->Translate( key, cmd ) ) {
return true;
}
}
}
sdHudModule* module = gameLocal.localPlayerProperties.GetActiveHudModule();
if ( module != NULL ) {
sdUserInterfaceLocal* ui = module->GetGui();
if ( ui != NULL ) {
if ( ui->Translate( key, cmd ) ) {
return true;
}
}
}
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
if ( localPlayer ) {
if ( localPlayer->TranslateGuiBind( key, cmd ) ) {
return true;
}
}
if ( rules != NULL ) {
if ( rules->TranslateGuiBind( key, cmd ) ) {
return true;
}
}
return false;
}
/*
============
idGameLocal::ShowMainMenu
============
*/
void idGameLocal::ShowMainMenu() {
ON_UIVALID( uiMainMenuHandle, ui ) {
ui->Activate();
}
}
/*
============
idGameLocal::HideMainMenu
============
*/
void idGameLocal::HideMainMenu() {
// ao: never called
ON_UIVALID( uiMainMenuHandle, ui ) {
ui->Deactivate( true );
}
}
/*
============
idGameLocal::IsMainMenuActive
============
*/
bool idGameLocal::IsMainMenuActive() {
ON_UIVALID( uiMainMenuHandle, ui ) {
return ui->IsActive();
}
return false;
}
/*
============
idGameLocal::DrawMainMenu
============
*/
void idGameLocal::DrawMainMenu() {
ON_UIINVALID( uiMainMenuHandle, ui ) {
return;
}
if ( gamestate == GAMESTATE_NOMAP ) {
sdGlobalStatsTracker::GetInstance().UpdateStatsRequests();
}
ui->Draw();
}
/*
============
idGameLocal::DrawSystemUI
============
*/
void idGameLocal::DrawSystemUI() {
ON_UIINVALID( uiSystemUIHandle, ui ) {
return;
}
ui->Draw();
}
/*
============
idGameLocal::DrawLoadScreen
============
*/
void idGameLocal::DrawLoadScreen() {
ON_UIINVALID( uiLevelLoadHandle, ui ) {
return;
}
ui->Activate();
ui->Update();
ui->Draw();
}
/*
============
idGameLocal::DrawPureWaitScreen
============
*/
void idGameLocal::DrawPureWaitScreen() {
ON_UIINVALID( pureWaitHandle, ui ) {
return;
}
ui->Activate();
ui->Update();
ui->Draw();
}
/*
============
idGameLocal::CreateKeyBindingList
============
*/
void idGameLocal::CreateKeyBindingList( sdUIList* list ) {
assert( list );
using namespace sdProperties;
idStr category;
if( sdProperty* property = list->GetScope().GetProperties().GetProperty( "bindCategory", PT_STRING )) {
category = *property->value.stringValue;
}
sdUIList::ClearItems( list );
const sdDeclKeyBinding* bind = gameLocal.declKeyBindingType.LocalFind( category, false );
if( bind == NULL ) {
return;
}
idWStr text;
for( int i = 0; i < bind->GetKeys().GetNumKeyVals(); i++ ) {
const idKeyValue* kv = bind->GetKeys().GetKeyVal( i );
int item = sdUIList::InsertItem( list, va( L"<loc = '%hs'>", kv->GetKey().c_str() ), -1, 0 );
int numKeys = 0;
keyInputManager->KeysFromBinding( gameLocal.GetDefaultBindContext(), kv->GetValue(), numKeys, NULL );
idKey** keys = NULL;
if( numKeys > 0 ) {
keys = static_cast< idKey** >( _alloca( numKeys * sizeof( idKey* ) ) );
keyInputManager->KeysFromBinding( gameLocal.GetDefaultBindContext(), kv->GetValue(), numKeys, keys );
}
if( numKeys > 0 ) {
assert( keys != NULL );
keys[ 0 ]->GetLocalizedText( text );
sdUIList::CleanUserInput( text );
sdUIList::SetItemText( list, text.c_str(), item, 1 );
} else {
sdUIList::SetItemText( list, L"<loc = 'guis/mainmenu/bindings/unbound'>", item, 1 );
}
if( numKeys > 1 ) {
assert( keys != NULL );
keys[ 1 ]->GetLocalizedText( text );
sdUIList::CleanUserInput( text );
sdUIList::SetItemText( list, text.c_str(), item, 2 );
} else {
sdUIList::SetItemText( list, L"<loc = 'guis/mainmenu/bindings/unbound'>", item, 2 );
}
sdUIList::SetItemText( list, va( L"%hs", kv->GetValue().c_str() ), item, 3 );
}
}
/*
============
idGameLocal::CreateCrosshairList
============
*/
void idGameLocal::CreateCrosshairList( sdUIList* list ) {
assert( list != NULL );
sdUIList::ClearItems( list );
int num = gameLocal.declStringMapType.Num();
for( int i = 0; i < num; i++ ) {
const sdDeclStringMap* decl = gameLocal.declStringMapType.LocalFindByIndex( i, false );
if( idStr::Icmpn( decl->GetName(), "crosshairs", 10 ) != 0 ) {
continue;
}
// ensure we're parsed
gameLocal.declStringMapType.LocalFindByIndex( i, true );
const idDict& dict = decl->GetDict();
for( int j = 0; j < dict.GetNumKeyVals(); j++ ) {
const idKeyValue* kv = dict.GetKeyVal( j );
sdUIList::InsertItem( list, va( L"<material = 'literal: %hs'>\t%hs\t%hs", kv->GetValue().c_str(), decl->GetName(), kv->GetKey().c_str() ), -1, 0 );
}
}
}
/*
============
idGameLocal::CreateDemoList
============
*/
void idGameLocal::CreateDemoList( sdUIList* list ) {
sdUIList::ClearItems( list );
idFileList* files = fileSystem->ListFiles( "demos", ".ndm" );
if( files == NULL ) {
return;
}
idStr file;
idWStr date;
idStr fullPath;
sysTime_t time;
if( files->GetNumFiles() > 0 ) {
list->BeginBatch();
list->SetItemGranularity( files->GetNumFiles() );
for( int i = 0; i < files->GetNumFiles(); i++ ) {
file = files->GetFile( i );
if( networkSystem->CanPlayDemo( file.c_str() ) ) {
unsigned int timeStamp;
fullPath = files->GetBasePath();
fullPath += "/" + file;
fileSystem->ReadFile( fullPath, NULL, &timeStamp );
sys->SecondsToTime( timeStamp, time );
sdNetProperties::FormatTimeStamp( time, date );
file.StripFileExtension();
int index = sdUIList::InsertItem( list, va( L"%hs\t%ls\t%hs", file.c_str(), date.c_str(), fullPath.c_str() ), -1, 0 );
list->SetItemDataInt( timeStamp, index, 1, true );
}
}
list->EndBatch();
}
fileSystem->FreeFileList( files );
}
/*
============
idGameLocal::CreateVehiclePlayerList
============
*/
void idGameLocal::CreateVehiclePlayerList( sdUIList* list ) {
idPlayer* localPlayer = gameLocal.GetLocalViewPlayer();
if ( localPlayer == NULL ) {
if( g_debugPlayerList.GetInteger() ) {
sdUIList::ClearItems( list );
idWStr formatString;
for( int i = 0; i < g_debugPlayerList.GetInteger(); i++ ) {
formatString = va( L"<material = \"soldier\" >\tPlayer%i", i );
sdUIList::InsertItem( list, formatString.c_str(), -1, 0 );
}
}
return;
}
sdUIList::ClearItems( list );
idEntity* proxy = localPlayer->GetProxyEntity();
if( proxy == NULL ) {
return;
}
if ( sdUsableInterface* iface = proxy->GetUsableInterface() ) {
const wchar_t* formatString;
int selIndex = -1;
idWStr cleanPlayerName;
for( int i = 0; i < iface->GetNumPositions(); i++ ) {
const idPlayer* player = iface->GetPlayerAtPosition( i );
if( player == NULL ) {
if( g_debugPlayerList.GetInteger() ) {
formatString = va( L"<material = \"soldier\" >\tPlayer%i", i );
sdUIList::InsertItem( list, formatString, -1, 0 );
}
continue;
}
if( const sdDeclPlayerClass* pc = player->GetInventory().GetClass() ) {
cleanPlayerName = va( L"%hs", player->userInfo.name.c_str() );
sdUIList::CleanUserInput( cleanPlayerName );
formatString = va( L"<material = \"%hs\" >\t%ls", ( pc == NULL ) ? "" : pc->GetName(), cleanPlayerName.c_str() );
int index = sdUIList::InsertItem( list, formatString, -1, 0 );
if( player == localPlayer ) {
selIndex = index;
}
}
}
list->SelectItem( selIndex );
}
}
/*
============
idGameLocal::CreateScoreboardList
============
*/
void idGameLocal::CreateScoreboardList( sdUIList* list ) {
if( gameLocal.rules ) {
idStr teamName;
if( sdUserInterfaceLocal* ui = list->GetUI() ) {
ui->PopScriptVar( teamName );
}
gameLocal.rules->UpdateScoreboard( list, teamName );
} else {
if( sdUserInterfaceLocal* ui = list->GetUI() ) {
idStr name;
ui->PopScriptVar( name );
ui->PushScriptVar( 0.0f );
ui->PushScriptVar( 0.0f );
ui->PushScriptVar( 0.0f );
}
}
}
/*
============
idGameLocal::CreatePlayerAdminList
============
*/
void idGameLocal::CreatePlayerAdminList( sdUIList* list ) {
sdAdminSystem::GetInstance().CreatePlayerAdminList( list );
}
/*
============
idGameLocal::CreateUserGroupList
============
*/
void idGameLocal::CreateUserGroupList( sdUIList* list ) {
sdUserGroupManager::GetInstance().CreateUserGroupList( list );
}
/*
============
idGameLocal::CreateUserGroupList
============
*/
void idGameLocal::CreateServerConfigList( sdUIList* list ) {
sdUserGroupManager::GetInstance().CreateServerConfigList( list );
}
/*
============
idGameLocal::CreateFireTeamListEntry
============
*/
void idGameLocal::CreateFireTeamListEntry( sdUIList* list, int index, idPlayer* player ) {
static const idVec4 noDraw( 0.0f, 0.0f, 0.0f, 0.0f );
sdUIList::InsertItem( list, L"", index, 0 );
const sdDeclPlayerClass* cls = player->GetInventory().GetClass();
if ( cls != NULL ) {
// class
sdUIList::SetItemIcon( list, cls->GetName(), index, 0 );
}
// rank/voip
bool sendingVoice = ( sys->Milliseconds() - networkSystem->GetLastVoiceReceivedTime( player->entityNumber ) ) < SEC2MS( 0.5f );
if ( sendingVoice ) {
sdUIList::SetItemIcon( list, "voip", index, 1 );
sdUIList::SetItemForeColor( list, colorWhite, index, 1 );
} else if ( const sdDeclRank* rank = player->GetProficiencyTable().GetRank() ) {
sdUIList::SetItemIcon( list, rank->GetMaterial(), index, 1 );
sdUIList::SetItemForeColor( list, colorWhite, index, 1 );
} else {
sdUIList::SetItemForeColor( list, noDraw, index, 1 );
}
// name
idWStr cleanPlayerName = va( L"%hs", player->userInfo.cleanName.c_str() );
sdUIList::CleanUserInput( cleanPlayerName );
sdUIList::SetItemText( list, cleanPlayerName.c_str(), index, 2 );
if( player->IsInLimbo() ) {
sdUIList::SetItemForeColor( list, colorBlack, index, 2 );
} else {
float healthFrac = player->GetHealth() / ( float )player->GetMaxHealth();
healthFrac = idMath::ClampFloat( 0.0f, 1.0f, healthFrac );
idVec4 healthColor( 1.0f - healthFrac, healthFrac, 0.0f, 1.0f );
sdUIList::SetItemForeColor( list, healthColor, index, 2 );
}
}
/*
============
idGameLocal::CreateFireTeamList
============
*/
void idGameLocal::CreateFireTeamList( sdUIList* list ) {
sdUIList::ClearItems( list );
int listType;
if( sdUserInterfaceLocal* ui = list->GetUI() ) {
ui->PopScriptVar( listType );
}
if ( gameLocal.rules == NULL ) {
return;
}
if ( gameLocal.GetLocalPlayer() == NULL ) {
return;
}
if ( listType == FIRETEAMLIST_MYFIRETEAM ) {
CreateFireTeamList_MyFireTeam( list );
} else if ( listType == FIRETEAMLIST_MAIN ) {
CreateFireTeamList_Main( list );
} else if ( listType == FIRETEAMLIST_JOIN ) {
CreateFireTeamList_Join( list );
} else if ( listType == FIRETEAMLIST_INVITE ) {
CreateFireTeamList_Invite( list );
} else if ( listType == FIRETEAMLIST_KICK ) {
CreateFireTeamList_Kick( list );
} else if ( listType == FIRETEAMLIST_PROMOTE ) {
CreateFireTeamList_Promote( list );
} else if ( listType == FIRETEAMLIST_MANAGE ) {
CreateFireTeamList_Manage( list );
} else {
assert( 0 );
}
}
/*
============
idGameLocal::CreateFireTeamList_MyFireTeam
============
*/
void idGameLocal::CreateFireTeamList_MyFireTeam( sdUIList* list ) {
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
sdFireTeam* fireTeam = gameLocal.rules->GetPlayerFireTeam( localPlayer->entityNumber );
if ( fireTeam != NULL ) {
int index = 0;
for ( int i = 0; i < fireTeam->GetNumMembers(); i++, index++ ) {
idPlayer* player = fireTeam->GetMember( i );
CreateFireTeamListEntry( list, index, player );
}
if ( g_debugPlayerList.GetInteger() ) {
int i = 0;
int num = 8;
while ( list->GetNumItems() < num ) {
idWStr formatString = va( L"<material = \"soldier\" >\t<material = \"guis/assets/icons/rank01\" >\tPlayer%i\t<fore = 1,1,1,1>100.00XP\t100%%", i );
sdUIList::InsertItem( list, formatString.c_str(), -1, 0 );
i++;
}
}
} else {
sdTeamInfo* localTeam = localPlayer->GetGameTeam();
if ( localTeam == NULL ) {
return;
}
idStaticList< idPlayer*, MAX_CLIENTS > playerList;
// Mission teams
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
idPlayer* player = gameLocal.GetClient( i );
if ( player == NULL ) {
continue;
}
if ( player->GetGameTeam() != localTeam ) {
continue;
}
if ( gameLocal.rules->GetPlayerFireTeam( i ) != NULL ) {
continue;
}
if( player->GetActiveTaskHandle() != localPlayer->GetActiveTaskHandle() ) {
continue;
}
playerList.Append( player );
}
for ( int i = 0; i < playerList.Num() && i < MAX_MISSION_TEAM_PLAYERS; i++ ) {
idPlayer* player = playerList[ i ];
CreateFireTeamListEntry( list, i, player );
}
}
}
/*
============
idGameLocal::CreateFireTeamList_Main
============
*/
void idGameLocal::CreateFireTeamList_Main( sdUIList* list ) {
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
bool canJoin = false;
bool canCreate = false;
for ( int i = 0; i < sdTeamInfo::MAX_FIRETEAMS; i++ ) {
sdFireTeam& fireTeam = localPlayer->GetTeam()->GetFireTeam( i );
if ( fireTeam.GetNumMembers() > 0 ) {
if ( !fireTeam.IsPrivate() ) {
if ( fireTeam.MaxMembers() - fireTeam.GetNumMembers() > 0 ) {
canJoin = true;
}
}
} else {
canCreate = true;
}
}
if ( canJoin ) {
sdUIList::InsertItem( list, va( L" 1. %ls\tcanjoin", common->LocalizeText( "guis/hud/fireteam/menu/join" ).c_str() ), 0, 0 );
} else {
sdUIList::InsertItem( list, va( L" 1. ^1%ls\tcannot", common->LocalizeText( "guis/hud/fireteam/menu/join" ).c_str() ), 0, 0 );
}
if ( canCreate ) {
sdUIList::InsertItem( list, va( L" 2. %ls\tcancreate", common->LocalizeText( "guis/hud/fireteam/menu/create" ).c_str() ), 1, 0 );
} else {
sdUIList::InsertItem( list, va( L" 2. ^1%ls\tcannot", common->LocalizeText( "guis/hud/fireteam/menu/create" ).c_str() ), 1, 0 );
}
}
/*
============
idGameLocal::CreateFireTeamList_Join
============
*/
void idGameLocal::CreateFireTeamList_Join( sdUIList* list ) {
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
int num = 0;
for ( int i = 0; i < sdTeamInfo::MAX_FIRETEAMS; i++ ) {
sdFireTeam& fireTeam = localPlayer->GetTeam()->GetFireTeam( i );
if ( !fireTeam.IsPrivate() ) {
if ( fireTeam.GetNumMembers() > 0 && fireTeam.MaxMembers() - fireTeam.GetNumMembers() > 0 ) {
sdUIList::InsertItem( list, va( L" %i. %hs\t%i", num+1, fireTeam.GetName(), i ), i, 0 );
num++;
}
}
}
}
/*
============
idGameLocal::CreateFireTeamList_Invite
============
*/
void idGameLocal::CreateFireTeamList_Invite( sdUIList* list ) {
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
sdFireTeam* fireTeam = gameLocal.rules->GetPlayerFireTeam( localPlayer->entityNumber );
if ( fireTeam == NULL ) {
return;
}
int page;
if( sdUserInterfaceLocal* ui = list->GetUI() ) {
ui->PopScriptVar( page );
}
assert( page >= 0 && page <= 1 );
int numAdded = 0;
int numFound = 0;
if ( fireTeam->MaxMembers() - fireTeam->GetNumMembers() >= 1 ) {
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
idPlayer *p = gameLocal.GetClient( i );
if ( p != NULL && p->GetTeam() == localPlayer->GetTeam() ) {
if ( gameLocal.rules->GetPlayerFireTeam( i ) == NULL ) {
numFound++;
if ( numFound > FIRETEAMLIST_PAGE_NUM_PLAYERS * page && numAdded < FIRETEAMLIST_PAGE_NUM_PLAYERS ) {
sdUIList::InsertItem( list, va( L" %i. %hs\t%hs", numAdded+1, p->userInfo.cleanName.c_str(), p->userInfo.cleanName.c_str() ), numAdded, 0 );
numAdded++;
}
}
}
}
}
if ( numFound != numAdded ) {
if ( page == 1 ) {
sdUIList::InsertItem( list, va( L" %i. %ls\tprevpage", numAdded+1, common->LocalizeText( "guis/hud/fireteam/menu/prevpage" ).c_str() ), numAdded, 0 );
} else {
sdUIList::InsertItem( list, va( L" %i. %ls\tnextpage", numAdded+1, common->LocalizeText( "guis/hud/fireteam/menu/nextpage" ).c_str() ), numAdded, 0 );
}
numAdded++;
}
}
/*
============
idGameLocal::CreateFireTeamList_Kick
============
*/
void idGameLocal::CreateFireTeamList_Kick( sdUIList* list ) {
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
sdFireTeam* fireTeam = gameLocal.rules->GetPlayerFireTeam( localPlayer->entityNumber );
if ( fireTeam == NULL ) {
return;
}
int numAdded = 0;
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
idPlayer* p = gameLocal.GetClient( i );
if ( p != NULL && p != localPlayer && fireTeam->IsMember( p ) ) {
sdUIList::InsertItem( list, va( L" %i. %hs\t%hs", numAdded+1, p->userInfo.cleanName.c_str(), p->userInfo.cleanName.c_str() ), numAdded, 0 );
numAdded++;
}
}
}
/*
============
idGameLocal::CreateFireTeamList_Promote
============
*/
void idGameLocal::CreateFireTeamList_Promote( sdUIList* list ) {
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
sdFireTeam* fireTeam = gameLocal.rules->GetPlayerFireTeam( localPlayer->entityNumber );
if ( fireTeam == NULL ) {
return;
}
int numAdded = 0;
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
idPlayer* p = gameLocal.GetClient( i );
if ( p != NULL && p != localPlayer && fireTeam->IsMember( p ) ) {
if ( !p->userInfo.isBot ) {
sdUIList::InsertItem( list, va( L" %i. %hs\t%hs", numAdded+1, p->userInfo.cleanName.c_str(), p->userInfo.cleanName.c_str() ), numAdded, 0 );
numAdded++;
}
}
}
}
/*
============
idGameLocal::CreateFireTeamList_Manage
============
*/
void idGameLocal::CreateFireTeamList_Manage( sdUIList* list ) {
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
sdFireTeam* fireTeam = gameLocal.rules->GetPlayerFireTeam( localPlayer->entityNumber );
if ( fireTeam == NULL ) {
return;
}
int index = 0;
if ( fireTeam->IsCommander( localPlayer ) ) {
bool canInvite = false;
if ( fireTeam->MaxMembers() - fireTeam->GetNumMembers() > 0 ) {
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
idPlayer *p = gameLocal.GetClient( i );
if ( p != NULL && p->GetTeam() == localPlayer->GetTeam() ) {
if ( gameLocal.rules->GetPlayerFireTeam( i ) == NULL ) {
canInvite = true;
break;
}
}
}
}
if ( canInvite ) {
sdUIList::InsertItem( list, va( L" %i. %ls\tcaninvite", index+1, common->LocalizeText( "guis/hud/fireteam/menu/invite" ).c_str() ), index, 0 );
} else {
sdUIList::InsertItem( list, va( L" %i. ^1%ls\tcannot", index+1, common->LocalizeText( "guis/hud/fireteam/menu/invite" ).c_str() ), index, 0 );
}
index++;
if ( fireTeam->GetNumMembers() > 1 ) {
sdUIList::InsertItem( list, va( L" %i. %ls\tcankick", index+1, common->LocalizeText( "guis/hud/fireteam/menu/kick" ).c_str() ), index, 0 );
} else {
sdUIList::InsertItem( list, va( L" %i. ^1%ls\tcannot", index+1, common->LocalizeText( "guis/hud/fireteam/menu/kick" ).c_str() ), index, 0 );
}
index++;
sdUIList::InsertItem( list, va( L" %i. %ls\tdisband", index+1, common->LocalizeText( "guis/hud/fireteam/menu/disband" ).c_str() ), index, 0 );
index++;
sdUIList::InsertItem( list, va( L" %i. %ls\tleave", index+1, common->LocalizeText( "guis/hud/fireteam/menu/leave" ).c_str() ), index, 0 );
index++;
int numPromote = 0;
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
idPlayer* p = gameLocal.GetClient( i );
if ( p != NULL && p != localPlayer && fireTeam->IsMember( p ) ) {
if ( !p->userInfo.isBot ) {
numPromote++;
}
}
}
if ( numPromote > 0 ) {
sdUIList::InsertItem( list, va( L" %i. %ls\tcanpromote", index+1, common->LocalizeText( "guis/hud/fireteam/menu/promote" ).c_str() ), index, 0 );
} else {
sdUIList::InsertItem( list, va( L" %i. ^1%ls\tcannot", index+1, common->LocalizeText( "guis/hud/fireteam/menu/promote" ).c_str() ), index, 0 );
}
index++;
if ( fireTeam->IsPrivate() ) {
sdUIList::InsertItem( list, va( L" %i. %ls\tpublic", index+1, common->LocalizeText( "guis/hud/fireteam/menu/makepublic" ).c_str() ), index, 0 );
} else {
sdUIList::InsertItem( list, va( L" %i. %ls\tprivate", index+1, common->LocalizeText( "guis/hud/fireteam/menu/makeprivate" ).c_str() ), index, 0 );
}
index++;
sdUIList::InsertItem( list, va( L" %i. %ls\trename", index+1, common->LocalizeText( "guis/hud/fireteam/menu/rename" ).c_str() ), index, 0 );
index++;
} else {
bool canPropose = false;
if ( fireTeam->MaxMembers() - fireTeam->GetNumMembers() >= 1 ) {
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
idPlayer *p = gameLocal.GetClient( i );
if ( p != NULL && p->GetTeam() == localPlayer->GetTeam() ) {
if ( gameLocal.rules->GetPlayerFireTeam( i ) == NULL ) {
canPropose = true;
}
}
}
}
if ( canPropose ) {
sdUIList::InsertItem( list, va( L" %i. %ls\tcanpropose", index+1, common->LocalizeText( "guis/hud/fireteam/menu/propose" ).c_str() ), index, 0 );
} else {
sdUIList::InsertItem( list, va( L" %i. ^1%ls\tcannot", index+1, common->LocalizeText( "guis/hud/fireteam/menu/propose" ).c_str() ), index, 0 );
}
index++;
sdUIList::InsertItem( list, va( L" %i. %ls\tleave", index+1, common->LocalizeText( "guis/hud/fireteam/menu/leave" ).c_str() ), index, 0 );
index++;
}
}
/*
============
idGameLocal::GeneratePlayerListForTask
============
*/
void idGameLocal::GeneratePlayerListForTask( idStr& playerList, const sdPlayerTask* task ) {
sdStringBuilder_Heap builder;
playerList.Clear();
sdTaskManagerLocal& manager = sdTaskManager::GetInstance();
for( int playerIndex = 0; playerIndex < gameLocal.numClients; playerIndex++ ) {
idPlayer* player = gameLocal.GetClient( playerIndex );
if ( player == NULL ) {
continue;
}
if ( player->GetActiveTaskHandle() != task->GetHandle() ) {
continue;
}
builder += " " + player->userInfo.name;
}
builder.ToString( playerList );
}
/*
============
idGameLocal::InsertTask
============
*/
int idGameLocal::InsertTask( sdUIList* list, const sdPlayerTask* task, bool highlightActive ) {
const char* iconMat = "guis/nodraw";
if ( task->GetInfo()->GetNumWayPoints() > 0 ) {
const idMaterial* mat = task->GetInfo()->GetWaypointIcon( 0 );
if( mat != NULL ) {
iconMat = mat->GetName();
}
}
idWStr xpString = task->GetInfo()->GetXPString();
sdUIList::CleanUserInput( xpString );
int index = sdUIList::InsertItem( list, va( L"<material = \"::%hs\">\t%ls\t<align = right>%ls",
iconMat, task->GetTitle(), xpString.c_str() ), -1, 0 );
return index;
}
/*
============
idGameLocal::CreateActiveTaskList
============
*/
void idGameLocal::CreateActiveTaskList( sdUIList* list ) {
sdTaskManagerLocal& manager = sdTaskManager::GetInstance();
sdUIList::ClearItems( list );
bool showAll;
list->GetUI()->PopScriptVar( showAll );
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
idPlayer* localPlayerView = gameLocal.GetLocalViewPlayer();
if ( localPlayerView == NULL ) {
return;
}
if ( g_debugPlayerList.GetInteger() ) {
sdUIList::InsertItem( list, L"Task 1", 0, 1 );
idWStrList parms( 1 );
keyInputManager->KeysFromBinding( gameLocal.GetDefaultBindContext(), "_taskmenu", true, parms.Alloc() );
sdUIList::InsertItem( list, va( L"<fore = 0 1 0 1>\t%ls", common->LocalizeText( "guis/hud/tasks_are_available", parms ).c_str() ), -1, 1 );
return;
}
sdTeamInfo* team = localPlayerView->GetGameTeam();
if ( team == NULL ) {
return;
}
bool canSelect = true;
sdPlayerTask* activeTask = NULL;
sdFireTeam* fireTeam = gameLocal.rules->GetPlayerFireTeam( localPlayerView->entityNumber );
if ( fireTeam != NULL ) {
activeTask = fireTeam->GetCommander()->GetActiveTask();
canSelect = fireTeam->GetCommander() == localPlayer;
} else {
activeTask = localPlayerView->GetActiveTask();
}
const sdPlayerTask::nodeType_t& objectiveTasks = sdTaskManager::GetInstance().GetObjectiveTasks( team );
sdPlayerTask* objectiveTask = objectiveTasks.Next();
if ( ( showAll || activeTask == NULL ) && objectiveTask != NULL ) {
int index = InsertTask( list, objectiveTask, false );
if( activeTask == NULL ) {
list->SelectItem( index );
}
}
gameLocal.localPlayerProperties.SetHasTask( !showAll && canSelect && ( activeTask != NULL || ( activeTask == NULL && objectiveTask != NULL ) ) );
if( showAll && canSelect && localPlayerView == localPlayer ) {
playerTaskList_t miniList;
manager.BuildTaskList( localPlayer, miniList );
int num = Min( sdPlayerTask::MAX_CHOOSABLE_TASKS, miniList.Num() );
for( int i = 0; i < num; i++ ) {
int index = InsertTask( list, miniList[ i ], false );
if( activeTask == miniList[ i ] ){
list->SelectItem( index );
}
}
/*
int index = sdUIList::InsertItem( list, common->LocalizeText( "guis/game/scoreboard/nomission" ).c_str(), -1, 1 );
if( activeTask == NULL ) {
list->SelectItem( index );
}
*/
idWStrList args( 1 );
keyInputManager->KeysFromBinding( gameLocal.GetDefaultBindContext(), "_taskmenu", true, args.Alloc() );
const idWStr localized = common->LocalizeText( "guis/hud/tasks_are_available", args );
sdUIList::InsertItem( list, localized.c_str(), -1, 1 );
return;
}
if ( activeTask != NULL ) {
int index = InsertTask( list, activeTask, false );
list->SelectItem( index );
}
if ( localPlayerView != localPlayer ) {
return;
}
playerTaskList_t miniList;
manager.BuildTaskList( localPlayer, miniList );
int numAvailableTasks = miniList.Num();
if( objectiveTask != NULL ) {
numAvailableTasks++;
}
if ( numAvailableTasks > 1 && canSelect ) {
idWStrList args( 1 );
keyInputManager->KeysFromBinding( gameLocal.GetDefaultBindContext(), "_taskmenu", true, args.Alloc() );
const idWStr localized = common->LocalizeText( "guis/hud/tasks_are_available", args );
sdUIList::InsertItem( list, localized.c_str(), -1, 1 );
}
if ( list->GetNumItems() == 0 ) {
const idWStr localized = common->LocalizeText( "guis/hud/no_tasks" );
sdUIList::InsertItem( list, localized.c_str(), -1, 1 );
}
}
/*
============
idGameLocal::GetTaskListHandle
============
*/
qhandle_t idGameLocal::GetTaskListHandle( int index ) {
if ( index < 0 || index >= taskListHandles.Num() ) {
return -1;
}
return taskListHandles[ index ];
}
/*
============
idGameLocal::TestGUI_f
============
*/
void idGameLocal::TestGUI_f( const idCmdArgs& args ) {
if( args.Argc() < 2 || idStr::Length( args.Argv( 1 )) == 0 ) {
gameLocal.uiMainMenuHandle = gameLocal.LoadUserInterface( "mainmenu", false, true );
} else {
gameLocal.uiMainMenuHandle = gameLocal.LoadUserInterface( args.Argv( 1 ), false, true );
// jrad - something of a hack:
// ensure that we're pushing the proper times through to the gui
sdUserInterfaceLocal* ui =gameLocal.GetUserInterface( gameLocal.uiMainMenuHandle );
if( ui != NULL ) {
ui->SetGUIFlag( sdUserInterfaceLocal::GUI_FRONTEND );
}
}
gameLocal.ShowMainMenu();
}
/*
================
idGameLocal::LoadUserInterface
================
*/
guiHandle_t idGameLocal::LoadUserInterface( const char* name, bool requireUnique, bool permanent, const char* theme, sdHudModule* module ) {
return uiManager->AllocUI( name, requireUnique, permanent, theme, module );
}
/*
================
idGameLocal::FreeUserInterface
================
*/
void idGameLocal::FreeUserInterface( guiHandle_t handle ) {
uiManager->FreeUserInterface( handle );
}
/*
================
idGameLocal::GetUserInterface
================
*/
sdUserInterfaceLocal* idGameLocal::GetUserInterface( const guiHandle_t handle ) {
return static_cast< sdUserInterfaceLocal* >( uiManager->GetUserInterface( handle ) );
}
/*
============
idGameLocal::GetUserInterfaceWindow
============
*/
sdUIWindow* idGameLocal::GetUserInterfaceWindow( const guiHandle_t handle, const char* windowName ) {
if( handle.IsValid() ) {
sdUserInterfaceLocal* ui = GetUserInterface( handle );
if( ui ) {
return ui->GetWindow( windowName )->Cast< sdUIWindow >();
}
}
return NULL;
}
/*
============
idGameLocal::GetUserInterfaceProperty
============
*/
sdProperties::sdProperty* idGameLocal::GetUserInterfaceProperty( guiHandle_t handle, const char* propertyName, sdProperties::ePropertyType expectedType ) {
if( sdUserInterfaceLocal* ui = GetUserInterface( handle ) ) {
return ui->GetState().GetProperty( propertyName, expectedType );
}
return NULL;
}
/*
============
idGameLocal::GetUserInterfaceProperty_r
============
*/
sdProperties::sdProperty* idGameLocal::GetUserInterfaceProperty_r( guiHandle_t handle, const char* propertyName, sdProperties::ePropertyType expectedType ) {
sdProperties::sdProperty* property = GetUserInterfaceProperty( handle, propertyName, expectedType );
if( property ) {
return property;
}
if( sdUserInterfaceLocal* ui = GetUserInterface( handle ) ) {
idLexer parser( propertyName, idStr::Length( propertyName ), "GetUserInterfaceProperty_r", sdDeclGUI::LEXER_FLAGS | LEXFL_NOERRORS );
sdUserInterfaceScope* scope = GetUserInterfaceScope( ui->GetState(), &parser );
if( scope ) {
idToken token;
if( parser.ReadToken( &token )) {
return scope->GetProperty( token, expectedType );
}
}
}
return NULL;
}
/*
================
idGameLocal::GetUserInterfaceScope
================
*/
sdUserInterfaceScope* idGameLocal::GetGlobalUserInterfaceScope( sdUserInterfaceScope& scope, const char* name ) {
for( int i = 0; i < uiScopes.Num(); i++ ) {
guiScope_t& scope = uiScopes[ i ];
if( idStr::Icmp( name, scope.name ) == 0 ) {
return scope.scope;
}
}
return NULL;
}
/*
================
idGameLocal::GetUserInterfaceScope
================
*/
sdUserInterfaceScope* idGameLocal::GetUserInterfaceScope( sdUserInterfaceScope& scope, idLexer* src ) {
idToken dot;
idToken token;
if ( !src->ReadToken( &token ) ) {
return &scope;
}
if ( token.type != TT_NAME ) {
src->UnreadToken( &token );
return &scope;
}
sdUserInterfaceScope* altScope = &scope;
sdUserInterfaceScope* globalScope = GetGlobalUserInterfaceScope( scope, token );
if ( globalScope ) {
if ( !src->ReadToken( &dot ) || dot != "." ) {
src->UnreadToken( &dot );
src->UnreadToken( &token );
return &scope;
}
src->ReadToken( &token );
altScope = globalScope;
}
while( true ) {
sdUserInterfaceScope* temp;
if ( !token.Cmp( "self" ) ) {
temp = altScope;
} else {
temp = altScope->GetSubScope( token );
}
if ( !temp || !src->ReadToken( &dot ) ) {
src->UnreadToken( &token );
return altScope;
}
if ( dot != "." ) {
src->UnreadToken( &dot );
src->UnreadToken( &token );
return altScope;
}
src->ReadToken( &token );
altScope = temp;
if ( token.type != TT_NAME ) {
return altScope;
}
}
}
/*
================
sdUIScopeParser::sdUIScopeParser
================
*/
sdUIScopeParser::sdUIScopeParser( const char* text ) {
idStr::Copynz( entryText, text, sizeof( entryText ) );
int len = idStr::Length( entryText );
( *entries.Alloc() ) = entryText;
int index = 0;
while ( ( index = idStr::FindChar( entryText, '.', index, len - 1 ) ) != idStr::INVALID_POSITION ) {
entryText[ index ] = '\0';
index++;
const char** entry = entries.Alloc();
if ( entry == NULL ) {
gameLocal.Error( "sdUIScopeParser: Max Entries Hit" );
}
*entry = &entryText[ index ];
}
entryIndex = 0;
}
/*
================
idGameLocal::GetUserInterfaceScope
================
*/
sdUserInterfaceScope* idGameLocal::GetUserInterfaceScope( sdUserInterfaceScope& scope, sdUIScopeParser& src ) {
sdUserInterfaceScope* altScope = &scope;
const char* token = src.GetNextEntry();
if ( src.IsLastEntry() ) {
src.Revert();
return altScope;
}
sdUserInterfaceScope* globalScope = GetGlobalUserInterfaceScope( scope, token );
if ( globalScope != NULL ) {
altScope = globalScope;
token = src.GetNextEntry();
}
while ( true ) {
if ( src.IsLastEntry() ) {
src.Revert();
return altScope;
}
sdUserInterfaceScope* temp = altScope->GetSubScope( token );
if ( temp == NULL ) {
gameLocal.Warning( "idGameLocal::GetUserInterfaceScope Failed To Find Scope: '%s'", token );
return altScope;
}
altScope = temp;
token = src.GetNextEntry();
}
}
/*
============
idGameLocal::GuiFrameEvents
============
*/
void idGameLocal::GuiFrameEvents( bool outOfSequence ) {
uiManager->Update( outOfSequence );
}
/*
============
idGameLocal::CreateInventoryList
============
*/
void idGameLocal::CreateInventoryList( sdUIList* list ) {
sdUserInterfaceLocal* ui = list->GetUI();
assert( ui );
idStr classname;
int bank;
int package;
ui->PopScriptVar( classname );
ui->PopScriptVar( bank );
ui->PopScriptVar( package );
idPlayer* player = gameLocal.GetLocalPlayer();
idList< itemBankPair_t > items;
ui->EnumerateItemsForBank( items, classname, bank, package );
for( int i = 0; i < items.Num(); i++ ) {
const wchar_t* formatString = va( L"<material = '::%hs'>\t<align = top><loc = '%hs'>", items[ i ].first->GetData().GetString( "mtr_weaponmenu", "default" ), items[ i ].first->GetItemName()->GetName() );
int index = sdUIList::InsertItem( list, formatString, -1, 0 );
list->SetItemDataInt( items[ i ].second, index, 0 );
}
}
typedef sdPair< int, const vidmode_t* > modePair_t;
struct sortVidMode_t {
int operator()( const modePair_t& a, const modePair_t& b ) {
if( a.second->width == b.second->width ) {
return a.second->height - b.second->height;
}
return a.second->width - b.second->width;
return 0;
}
};
/*
============
idGameLocal::CreateVideoModeList
============
*/
void idGameLocal::CreateVideoModeList( sdUIList* list ) {
sdUIList::ClearItems( list );
bool fullScreen;
list->GetUI()->PopScriptVar( fullScreen );
int aspect;
list->GetUI()->PopScriptVar( aspect );
int currentMode = cvarSystem->GetCVarInteger( "r_mode" );
int startMode = 3;
int selIndex = -1;
static const char* ratios[ 4 ] = {
"(4:3)",
"(16:9)",
"(16:10)",
"(5:4)"
};
idList< modePair_t > modes;
for( int i = startMode; i < common->GetNumVideoModes(); i++ ) {
const vidmode_t& mode = common->GetVideoMode( i );
// don't show modes that the monitor says it doesn't support
if ( fullScreen && !mode.available ) {
continue;
}
if ( aspect != -1 && aspect != mode.aspectRatio ) {
continue;
}
modes.Append( modePair_t( i, &mode ) );
}
sdQuickSort( modes.Begin(), modes.End(), sortVidMode_t() );
int nextBestModeWidth = -1;
int nextBestMode = -1;
const int currentWidth = currentMode == -1 ? cvarSystem->GetCVarInteger( "r_customWidth" ) : common->GetVideoMode( currentMode ).width;
for( int i = 0; i < modes.Num(); i++ ) {
const vidmode_t& mode = *modes[ i ].second;
int index = sdUIList::InsertItem( list, va( L"%ix%i %hs\t%i", mode.width, mode.height, ratios[ mode.aspectRatio ], modes[ i ].first ), -1, 0 );
if( modes[ i ].first == currentMode ) {
selIndex = index;
}
if( modes[ i ].second->width < currentWidth && modes[ i ].second->width > nextBestModeWidth ) {
nextBestMode = index;
nextBestModeWidth = modes[ i ].second->width;
}
}
if( selIndex != -1 ) {
list->SelectItem( selIndex );
} else if( nextBestMode != -1 ) {
list->SelectItem( nextBestMode );
}
}
/*
============
idGameLocal::CreateCampaignList
============
*/
void idGameLocal::CreateCampaignList( sdUIList* list ) {
sdUIList::ClearItems( list );
for( int i = 0; i < gameLocal.campaignMetaDataList->GetNumMetaData(); i++ ) {
const metaDataContext_t& metaDataContext = gameLocal.campaignMetaDataList->GetMetaDataContext( i );
if ( !gameLocal.IsMetaDataValidForPlay( metaDataContext, true ) ) {
continue;
}
const idDict& dict = *metaDataContext.meta;
const char* materialName = dict.GetString( "server_shot_thumb" );
const char* prettyName = dict.GetString( "pretty_name" );
const char* defName = dict.GetString( "metadata_name" );
int index = sdUIList::InsertItem( list, va( L"%hs\t%hs\t%hs", prettyName, defName, materialName ), -1, 0 );
}
}
/*
============
idGameLocal::CreateMapList
============
*/
void idGameLocal::CreateMapList( sdUIList* list ) {
sdUIList::ClearItems( list );
sdAddonMetaDataList* metaData = fileSystem->ListAddonMetaData( "mapMetaData" );
for( int i = 0; i < metaData->GetNumMetaData(); i++ ) {
const metaDataContext_t& metaDataContext = metaData->GetMetaDataContext( i );
if ( !gameLocal.IsMetaDataValidForPlay( metaDataContext, true ) ) {
continue;
}
const idDict& data = *metaDataContext.meta;
const char* materialName = data.GetString( "server_shot_thumb", "levelshots/thumbs/generic.tga" );
const char* defName = data.GetString( "metadata_name" );
const char* prettyName = data.GetString( "pretty_name" );
int index = sdUIList::InsertItem( list, va( L"%hs\t%hs\t%hs", prettyName, defName, materialName ), -1, 0 );
}
fileSystem->FreeAddonMetaDataList( metaData );
}
/*
============
idGameLocal::PacifierUpdate
============
*/
void idGameLocal::PacifierUpdate() {
gameLocal.localPlayerProperties.PacifierUpdate();
deviceContext->BeginEmitFullScreen();
if ( sdUserInterfaceLocal* ui = GetUserInterface( uiLevelLoadHandle ) ) {
ui->SetCurrentTime( sys->Milliseconds() );
ui->Update();
ui->Draw();
}
deviceContext->End();
}
/*
============
idGameLocal::ShowLevelLoadScreen
============
*/
void idGameLocal::ShowLevelLoadScreen( const char* mapName ) {
if ( networkSystem->IsDedicated() ) {
return;
}
/*
if ( !reloadingSameMap ) {
bytesNeededForMapLoad = GetBytesNeededForMapLoad( mapName );
} else {
bytesNeededForMapLoad = 30 * 1024 * 1024;
}
*/
idStr stripped = mapName;
stripped.StripFileExtension();
mapMetaData = mapMetaDataList->FindMetaData( stripped, &defaultMetaData );
mapInfo = declMapInfoType.LocalFind( mapMetaData->GetString( "mapinfo", "default" ) );
using namespace sdProperties;
if ( sdUserInterfaceScope* scope = globalProperties.GetSubScope( "mapinfo" ) ) {
if ( sdProperty* property = scope->GetProperty( "numObjectives", PT_FLOAT ) ) {
*property->value.floatValue = mapInfo->GetData().GetFloat( "numObjectives", "0" );
}
}
sdUserInterfaceLocal* ui;
ui = GetUserInterface( pureWaitHandle );
if ( ui != NULL ) {
ui->Deactivate( false );
}
uiLevelLoadHandle = LoadUserInterface( "loadscreen", false, true );
UpdateCampaignStats( true );
ui = GetUserInterface( uiLevelLoadHandle );
if ( ui != NULL ) {
ui->SetCurrentTime( sys->Milliseconds() );
ui->Activate();
PacifierUpdate();
}
}
/*
============
idGameLocal::UpdateLevelLoadScreen
============
*/
void idGameLocal::UpdateLevelLoadScreen( const wchar_t* status ) {
if ( networkSystem->IsDedicated() ) {
return;
}
using namespace sdProperties;
sdUserInterfaceScope* scope = globalProperties.GetSubScope( "mapinfo" );
if( scope ) {
if( sdProperty* property = scope->GetProperty( "mapStatus", PT_WSTRING )) {
*property->value.wstringValue = status;
}
}
common->PacifierUpdate();
}
/*
============
idGameLocal::HideLevelLoadScreen
============
*/
void idGameLocal::HideLevelLoadScreen() {
if ( networkSystem->IsDedicated() ) {
return;
}
if ( sdUserInterfaceLocal* ui = GetUserInterface( uiLevelLoadHandle ) ) {
ui->Deactivate();
}
}
/*
============
idGameLocal::GetUIManager
============
*/
sdUserInterfaceManager* idGameLocal::GetUIManager() {
return uiManager;
}
/*
============
idGameLocal::SetGUIFloat
============
*/
void idGameLocal::SetGUIFloat( int handle, const char* name, float value ) {
if ( networkSystem->IsDedicated() ) {
gameLocal.Warning( "Tried to run a GUI command on the server" );
}
sdUserInterfaceScope* scope;
if ( handle == GUI_GLOBALS_HANDLE ) {
scope = &gameLocal.globalProperties;
} else {
sdUserInterfaceLocal* ui = gameLocal.GetUserInterface( handle );
if ( !ui ) {
gameLocal.Warning( "idGameLocal::SetGUIFloat: could not find GUI" );
return;
}
scope = &ui->GetState();
}
sdUIScopeParser parser( name );
scope = gameLocal.GetUserInterfaceScope( *scope, parser );
sdProperties::sdProperty* prop = NULL;
const char* token = parser.GetNextEntry();
if ( token == NULL ) {
assert( false );
} else {
prop = scope->GetProperty( token, sdProperties::PT_FLOAT );
}
if ( prop != NULL ) {
*( prop->value.floatValue ) = value;
} else {
gameLocal.Warning( "idGameLocal::SetGUIFloat: could not find float property '%s'", name );
}
}
/*
============
idGameLocal::GetGUIFloat
============
*/
float idGameLocal::GetGUIFloat( int handle, const char* name ) {
if( networkSystem->IsDedicated() ) {
gameLocal.Warning( "Tried to run a GUI command on the server" );
}
sdUserInterfaceScope* scope;
if ( handle == GUI_GLOBALS_HANDLE ) {
scope = &gameLocal.globalProperties;
} else {
sdUserInterfaceLocal* ui = gameLocal.GetUserInterface( handle );
if( !ui ) {
gameLocal.Warning( "idGameLocal::GetGUIFloat: could not find GUI" );
return 0.0f;
}
scope = &ui->GetState();
}
sdUIScopeParser parser( name );
scope = gameLocal.GetUserInterfaceScope( *scope, parser );
sdProperties::sdProperty* prop = NULL;
const char* token = parser.GetNextEntry();
if ( token == NULL ) {
assert( false );
} else {
prop = scope->GetProperty( token, sdProperties::PT_FLOAT );
}
if ( prop == NULL ) {
gameLocal.Warning( "idGameLocal::GetGUIFloat: could not find float property '%s'", name );
return 0.f;
}
return prop->value.floatValue->GetValue();
}
/*
============
idGameLocal::SetGUIInt
============
*/
void idGameLocal::SetGUIInt( int handle, const char* name, int value ) {
if ( networkSystem->IsDedicated() ) {
gameLocal.Warning( "Tried to run a GUI command on the server" );
}
sdUserInterfaceScope* scope;
if ( handle == GUI_GLOBALS_HANDLE ) {
scope = &gameLocal.globalProperties;
} else {
sdUserInterfaceLocal* ui = gameLocal.GetUserInterface( handle );
if ( !ui ) {
gameLocal.Warning( "idGameLocal::SetGUIInt: could not find GUI" );
return;
}
scope = &ui->GetState();
}
sdUIScopeParser parser( name );
scope = gameLocal.GetUserInterfaceScope( *scope, parser );
sdProperties::sdProperty* prop = NULL;
const char* token = parser.GetNextEntry();
if ( token == NULL ) {
assert( false );
} else {
prop = scope->GetProperty( token, sdProperties::PT_INT );
}
if ( prop != NULL ) {
*( prop->value.intValue ) = value;
} else {
gameLocal.Warning( "idGameLocal::SetGUIInt: could not find int property '%s'", name );
}
}
/*
============
idGameLocal::SetGUIVec2
============
*/
void idGameLocal::SetGUIVec2( int handle, const char* name, const idVec2& value ) {
if ( networkSystem->IsDedicated() ) {
gameLocal.Warning( "Tried to run a GUI command on the server" );
}
sdUserInterfaceScope* scope;
if ( handle == GUI_GLOBALS_HANDLE ) {
scope = &gameLocal.globalProperties;
} else {
sdUserInterfaceLocal* ui = gameLocal.GetUserInterface( handle );
if( !ui ) {
gameLocal.Warning( "idGameLocal::SetGUIVec2: could not find GUI" );
return;
}
scope = &ui->GetState();
}
sdUIScopeParser parser( name );
scope = gameLocal.GetUserInterfaceScope( *scope, parser );
sdProperties::sdProperty* prop = NULL;
const char* token = parser.GetNextEntry();
if ( token == NULL ) {
assert( false );
} else {
prop = scope->GetProperty( token, sdProperties::PT_VEC2 );
}
if ( prop != NULL ) {
*( prop->value.vec2Value ) = value;
} else {
gameLocal.Warning( "idGameLocal::SetGUIVec2: could not find vec2 property '%s'", name );
}
}
/*
============
idGameLocal::SetGUIVec3
============
*/
void idGameLocal::SetGUIVec3( int handle, const char* name, const idVec3& value ) {
if ( networkSystem->IsDedicated() ) {
gameLocal.Warning( "Tried to run a GUI command on the server" );
}
sdUserInterfaceScope* scope;
if ( handle == GUI_GLOBALS_HANDLE ) {
scope = &gameLocal.globalProperties;
} else {
sdUserInterfaceLocal* ui = gameLocal.GetUserInterface( handle );
if( !ui ) {
gameLocal.Warning( "idGameLocal::SetGUIVec3: could not find GUI" );
return;
}
scope = &ui->GetState();
}
sdUIScopeParser parser( name );
scope = gameLocal.GetUserInterfaceScope( *scope, parser );
sdProperties::sdProperty* prop = NULL;
const char* token = parser.GetNextEntry();
if ( token == NULL ) {
assert( false );
} else {
prop = scope->GetProperty( token, sdProperties::PT_VEC3 );
}
if ( prop != NULL ) {
*( prop->value.vec3Value ) = value;
} else {
gameLocal.Warning( "idGameLocal::SetGUIVec3: could not find vec3 property '%s'", name );
}
}
/*
============
idGameLocal::SetGUIVec4
============
*/
void idGameLocal::SetGUIVec4( int handle, const char* name, const idVec4& value ) {
if ( networkSystem->IsDedicated() ) {
gameLocal.Warning( "Tried to run a GUI command on the server" );
}
sdUserInterfaceScope* scope;
if ( handle == GUI_GLOBALS_HANDLE ) {
scope = &gameLocal.globalProperties;
} else {
sdUserInterfaceLocal* ui = gameLocal.GetUserInterface( handle );
if( !ui ) {
gameLocal.Warning( "idGameLocal::SetGUIVec4: could not find GUI" );
return;
}
scope = &ui->GetState();
}
sdUIScopeParser parser( name );
scope = gameLocal.GetUserInterfaceScope( *scope, parser );
sdProperties::sdProperty* prop = NULL;
const char* token = parser.GetNextEntry();
if ( token == NULL ) {
assert( false );
} else {
prop = scope->GetProperty( token, sdProperties::PT_VEC4 );
}
if ( prop != NULL ) {
*( prop->value.vec4Value ) = value;
} else {
gameLocal.Warning( "idGameLocal::SetGUIVec4: could not find vec4 property '%s'", name );
}
}
/*
============
idGameLocal::SetGUIString
============
*/
void idGameLocal::SetGUIString( int handle, const char* name, const char* value ) {
if ( networkSystem->IsDedicated() ) {
gameLocal.Warning( "Tried to run a GUI command on the server" );
}
sdUserInterfaceScope* scope;
if ( handle == GUI_GLOBALS_HANDLE ) {
scope = &gameLocal.globalProperties;
} else {
sdUserInterfaceLocal* ui = gameLocal.GetUserInterface( handle );
if( !ui ) {
gameLocal.Warning( "idGameLocal::SetGUIString: could not find GUI" );
return;
}
scope = &ui->GetState();
}
sdUIScopeParser parser( name );
scope = gameLocal.GetUserInterfaceScope( *scope, parser );
sdProperties::sdProperty* prop = NULL;
const char* token = parser.GetNextEntry();
if ( token == NULL ) {
assert( false );
} else {
prop = scope->GetProperty( token, sdProperties::PT_STRING );
}
if ( prop != NULL ) {
*( prop->value.stringValue ) = value;
} else {
gameLocal.Warning( "idGameLocal::SetGUIString: could not find string property '%s'", name );
}
}
/*
============
idGameLocal::SetGUIWString
============
*/
void idGameLocal::SetGUIWString( int handle, const char* name, const wchar_t* value ) {
if( networkSystem->IsDedicated() ) {
gameLocal.Warning( "Tried to run a GUI command on the server" );
}
sdUserInterfaceScope* scope;
if ( handle == GUI_GLOBALS_HANDLE ) {
scope = &gameLocal.globalProperties;
} else {
sdUserInterfaceLocal* ui = gameLocal.GetUserInterface( handle );
if( !ui ) {
gameLocal.Warning( "idGameLocal::SetGUIWString: could not find GUI" );
return;
}
scope = &ui->GetState();
}
sdUIScopeParser parser( name );
scope = gameLocal.GetUserInterfaceScope( *scope, parser );
sdProperties::sdProperty* prop = NULL;
const char* token = parser.GetNextEntry();
if ( token == NULL ) {
assert( false );
} else {
prop = scope->GetProperty( token, sdProperties::PT_WSTRING );
}
if ( prop != NULL ) {
*( prop->value.wstringValue ) = value;
} else {
gameLocal.Warning( "idGameLocal::SetGUIWString: could not find string property '%s'", name );
}
}
/*
============
idGameLocal::SetGUITheme
============
*/
void idGameLocal::SetGUITheme( guiHandle_t handle, const char* theme ) {
if( !handle ) {
gameLocal.Error( "SetGUITheme: Invalid GUI handle." );
return;
}
sdUserInterfaceLocal* ui = static_cast< sdUserInterfaceLocal* >( uiManager->GetUserInterface( handle ) );
if( !ui ) {
gameLocal.Warning( "idGameLocal::SetGUITheme : Could not find GUI." );
return;
}
ui->SetTheme( theme );
}
/*
============
idGameLocal::GUIPostNamedEvent
============
*/
void idGameLocal::GUIPostNamedEvent( int handle, const char* window, const char* name ) {
if( networkSystem->IsDedicated() ) {
gameLocal.Warning( "Tried to run a GUI command on the server" );
}
sdUserInterfaceLocal* ui = gameLocal.GetUserInterface( handle );
if( !ui ) {
gameLocal.Warning( "idGameLocal::GUIPostNamedEvent: could not find GUI" );
return;
}
sdUIObject* object = NULL;
if( idStr::Length( window )) {
object = ui->GetWindow( window );
}
if( !object && idStr::Length( window )) {
gameLocal.Warning( "idGameLocal::GUIPostNamedEvent: could not find window '%s'", window );
return;
} else if( object ) {
object->PostNamedEvent( name, false );
} else {
ui->PostNamedEvent( name );
}
}
/*
============
idGameLocal::UpdateCampaignStats
============
*/
void idGameLocal::UpdateCampaignStats( bool allowMedia ) {
if( networkSystem->IsDedicated() ) {
return;
}
sdGameRules* rulesInstance = gameLocal.GetRulesInstance( serverInfo.GetString( "si_rules" ) );
if( rulesInstance != NULL ) {
rulesInstance->UpdateClientFromServerInfo( serverInfo, allowMedia );
}
}
/*
============
idGameLocal::CreateWeaponSwitchList
============
*/
void idGameLocal::CreateWeaponSwitchList( sdUIList* list ) {
sdUIList::ClearItems( list );
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
if( localPlayer == NULL ) {
return;
}
using namespace sdProperties;
const sdInventory& inv = localPlayer->GetInventory();
const int currentWeapon = inv.GetCurrentWeapon();
const int switchingWeapon = inv.GetSwitchingWeapon();
if( currentWeapon == -1 || switchingWeapon == -1 ) {
return;
}
const sdDeclInvItem* item = inv.GetItem( currentWeapon );
const sdDeclInvItem* switchItem = inv.GetItem( switchingWeapon );
typedef sdPair< const sdDeclInvItem*, int > invElement_t;
idStaticList< invElement_t, 10 > items;
for( int i = 0; i < inv.GetNumItems(); i++ ) {
if ( !inv.CanAutoEquip( i, false ) ) {
continue;
}
const sdDeclInvItem* item = inv.GetItem( i );
if ( inv.GetSlotForWeapon( i ) != -1 ) {
int j = 0;
const sdDeclInvSlot* slot = gameLocal.declInvSlotType.LocalFindByIndex( item->GetSlot() );
while( j < items.Num() ) {
if( item->GetSlot() < items[ j ].first->GetSlot() ) {
break;
}
const sdDeclInvSlot* otherSlot = gameLocal.declInvSlotType.LocalFindByIndex( items[ j ].first->GetSlot() );
if( slot->GetBank() < otherSlot->GetBank() ) {
break;
}
j++;
}
items.Insert( invElement_t( item, i ), j );
}
}
int offset = 0;
for( int i = 0; i < items.Num(); i++ ) {
int bankNumber = i;
const sdDeclInvItem* invItem = inv.GetItem( items[ i ].second );
const bool available = inv.CheckWeaponHasAmmo( invItem ) || invItem->GetData().GetBool( "select_when_empty", "0" );
const char* material = invItem->GetData().GetString( "mtr_weaponmenu", "_default" );
const int title = invItem->GetItemName()->Index();
float weaponAmmo = -1.0f;
const idList< itemClip_t >& itemClips = invItem->GetClips();
if ( itemClips.Num() && itemClips[ 0 ].ammoPerShot > 0 ) {
float ammo;
float totalAmmo;
if( invItem->GetData().GetBool( "show_all_ammo", "0" )) {
ammo = inv.GetAmmo( itemClips[ 0 ].ammoType ) / itemClips[ 0 ].ammoPerShot;
totalAmmo = inv.GetMaxAmmo( itemClips[ 0 ].ammoType ) / itemClips[ 0 ].ammoPerShot;
} else {
ammo = inv.GetClip( items[ i ].second, 0 );
totalAmmo = inv.GetClipSize( items[ i ].second, 0 );
}
weaponAmmo = idMath::ClampFloat( 0.0f, 1.0f, ammo / totalAmmo );
}
int index = sdUIList::InsertItem( list, va( L"%i\t<material = '::%hs'>\t%f\t%i\t%i", invItem->GetSlot(), material, weaponAmmo, title, available ), -1, 0 );
if( invItem == switchItem ) {
list->SelectItem( index );
localPlayer->SetWeaponSelectionItemIndex( bankNumber );
}
}
}
/*
============
idGameLocal::CreateColorList
============
*/
void idGameLocal::CreateColorList( sdUIList* list ) {
idVec4 customColor;
list->GetUI()->PopScriptVar( customColor );
idStr currentColorStr;
list->GetUI()->PopScriptVar( currentColorStr );
idVec4 currentColor = colorWhite;
if( !currentColorStr.IsEmpty() ) {
currentColor = sdTypeFromString< idVec4 >( currentColorStr.c_str() );
}
// if refreshing, only add new custom colors
bool refreshOnly;
list->GetUI()->PopScriptVar( refreshOnly );
if( refreshOnly == false ) {
sdUIList::ClearItems( list );
}
idWStr str;
idWStr colorSymbol;
idStr color;
bool customMatchesDefault = false;
int toSelect = -1;
static const float COLOR_EPSILON = 0.001f;
// check against previous custom colors
if( refreshOnly == false || list->GetNumItems() == 0 ) {
// skip default color
for( int i = 1; i < COLOR_BITS + 1; i++ ) {
const idVec4& c = idStr::ColorForIndex( i );
if( c.ToVec3().Compare( customColor.ToVec3(), COLOR_EPSILON ) ) {
customMatchesDefault = true;
}
colorSymbol = va( L"%hs", idStr::StrForColorIndex( i ) );
sdUIList::CleanUserInput( colorSymbol );
color = c.ToString( 2 );
str = va( L"<fore = %hs><material = '::guis/assets/white'>\t%ls\t%hs", color.c_str(), colorSymbol.c_str(), color.c_str() );
int index = sdUIList::InsertItem( list, str.c_str(), -1, 0 );
if( currentColor.ToVec3().Compare( c.ToVec3(), COLOR_EPSILON ) ) {
toSelect = index;
}
}
} else {
for( int i = 0; i < list->GetNumItems(); i++ ) {
idVec4 c = sdTypeFromString< idVec4 >( va( "%ls", list->GetItemText( i, 2, true ) ) );
if( c.ToVec3().Compare( customColor.ToVec3(), COLOR_EPSILON ) ) {
customMatchesDefault = true;
}
if( currentColor.ToVec3().Compare( c.ToVec3(), COLOR_EPSILON ) ) {
toSelect = i;
}
}
}
if( !customMatchesDefault ) {
str = va( L"<fore = %hs><material = '::guis/assets/white'>\t%\t%hs", customColor.ToString( 2 ), customColor.ToString( 2 ) );
int index = sdUIList::InsertItem( list, str.c_str(), -1, 0 );
if( currentColor.ToVec3().Compare( customColor.ToVec3(), COLOR_EPSILON ) ) {
toSelect = index;
}
}
list->SelectItem( toSelect );
}
/*
============
idGameLocal::CreateSpawnLocationList
============
*/
void idGameLocal::CreateSpawnLocationList( sdUIList* list ) {
sdUIList::ClearItems( list );
idStr team;
list->GetUI()->PopScriptVar( team );
const sdTeamInfo* info = sdTeamManager::GetInstance().GetTeamSafe( team.c_str() );
if( info == NULL ) {
return;
}
int currentSpawn = -1;
int defaultSpawn = -1;
int numLocs = info->GetNumSpawnLocations();
int* spawnCounts = static_cast< int* >( _alloca( numLocs * sizeof( int ) ) );
memset( &spawnCounts[ 0 ], 0, numLocs * sizeof( int ) );
const idPlayer* localPlayer = gameLocal.GetLocalPlayer();
for( int i = 0; i < MAX_CLIENTS; i++ ) {
idPlayer* player = gameLocal.GetClient( i );
if( player == NULL || player->GetGameTeam() != info ) {
continue;
}
const idEntity* playerSpawnLoc = player->GetSpawnPoint();
for( int si = 0; si < numLocs; si++ ) {
const idEntity* spawn = info->GetSpawnLocation( si );
if( playerSpawnLoc == NULL && spawn == info->GetDefaultSpawn() ) {
defaultSpawn = si;
if( playerSpawnLoc == NULL ) {
spawnCounts[ defaultSpawn ]++;
break;
}
}
if( spawn == playerSpawnLoc ) {
spawnCounts[ si ]++;
if( player == localPlayer ) {
currentSpawn = si;
}
break;
}
}
}
idWStr loc;
for( int i = 0; i < numLocs; i++ ) {
const idEntity* spawn = info->GetSpawnLocation( i );
sdLocationMarker::GetLocationText( spawn->GetPhysics()->GetOrigin(), loc );
int index = sdUIList::InsertItem( list, va( L"%ls\t%i\t%hs", loc.c_str(), spawnCounts[ i ], spawn->GetName() ), -1, 0 );
if( i == currentSpawn ) {
list->SelectItem( index );
}
}
int index = sdUIList::InsertItem( list, L"<loc = 'guis/mainmenu/defaultspawn'>\t\t", -1, 0 );
if( currentSpawn == -1 ) {
list->SelectItem( index );
}
}
/*
============
idGameLocal::CreateMSAAList
============
*/
void idGameLocal::CreateMSAAList( sdUIList* list ) {
int num = renderSystem->GetNumMSAAModes();
for (int i=0; i<num; i++) {
int val;
const char *msaaName = renderSystem->GetMSAAMode( i, val );
int index = sdUIList::InsertItem( list, va( L"%hs", msaaName ), -1, 0 );
list->SetItemDataInt( val, index, 0, true );
}
}
/*
============
idGameLocal::CreateSoundPlaybackList
============
*/
void idGameLocal::CreateSoundPlaybackList( sdUIList* list ) {
sdUIList::ClearItems( list );
const idWStrList* devices = soundSystem->ListSoundPlaybackDevices();
for( int i = 0; devices != NULL && i < devices->Num(); i++ ) {
const idWStr& str = (*devices)[ i ];
int hash = soundSystem->GetAudioDeviceHash( str.c_str() );
sdUIList::InsertItem( list, va( L"%ls\t%d", str.c_str(), hash ), -1, 0 );
}
soundSystem->FreeDeviceList( devices );
}
/*
============
idGameLocal::CreateSoundCaptureList
============
*/
void idGameLocal::CreateSoundCaptureList( sdUIList* list ) {
sdUIList::ClearItems( list );
const idWStrList* devices = soundSystem->ListSoundCaptureDevices();
for( int i = 0; devices != NULL && i < devices->Num(); i++ ) {
const idWStr& str = (*devices)[ i ];
int hash = soundSystem->GetAudioDeviceHash( str.c_str() );
sdUIList::InsertItem( list, va( L"%ls\t%d", str.c_str(), hash ), -1, 0 );
}
soundSystem->FreeDeviceList( devices );
}
/*
============
idGameLocal::CreateModList
============
*/
void idGameLocal::CreateModList( sdUIList* list ) {
sdUIList::ClearItems( list );
idModList* mods = fileSystem->ListMods();
if( mods != NULL ) {
for( int i = 0; i < mods->GetNumMods(); i++ ) {
sdUIList::InsertItem( list, va( L"%hs\t%hs", mods->GetDescription( i ), mods->GetMod( i ) ), -1, 0 );
}
fileSystem->FreeModList( mods );
}
}
static void AddLifeStatsItems( sdUIList* list, const char* material, const idList< const sdStatsTracker::lifeStatsData_t* >& data ) {
for( int i = 0; i < data.Num(); i++ ) {
const sdStatsTracker::lifeStatsData_t* item = data[ i ];
const lifeStat_t& stat = gameLocal.lifeStats[ item->index ];
switch( item->newValue.GetType() ) {
case sdNetStatKeyValue::SVT_INT:
case sdNetStatKeyValue::SVT_INT_MAX:
if( stat.isTimeBased ) {
idStr::hmsFormat_t format;
format.showZeroMinutes = true;
sdUIList::InsertItem( list, va( L"<material = '%hs'>\t<loc = '%hs'>\t%hs (%hs)", material, stat.text->GetName(), idStr::MS2HMS( item->newValue.GetInt() * 1000, format ), idStr::MS2HMS( item->oldValue.GetInt() * 1000, format ) ), -1, 0 );
} else {
sdUIList::InsertItem( list, va( L"<material = '%hs'>\t<loc = '%hs'>\t%i (%i)", material, stat.text->GetName(), item->newValue.GetInt(), item->oldValue.GetInt() ), -1, 0 );
}
break;
case sdNetStatKeyValue::SVT_FLOAT:
case sdNetStatKeyValue::SVT_FLOAT_MAX:
sdUIList::InsertItem( list, va( L"<material = '%hs'>\t<loc = '%hs'>\t%i (%i)", material, stat.text->GetName(), idMath::Ftoi( idMath::Ceil( item->newValue.GetFloat() ) ), idMath::Ftoi( idMath::Ceil( item->oldValue.GetFloat() ) ) ), -1, 0 );
break;
}
}
}
/*
============
idGameLocal::CreateLifeStatsList
============
*/
void idGameLocal::CreateLifeStatsList( sdUIList* list ) {
sdUIList::ClearItems( list );
idList< const sdStatsTracker::lifeStatsData_t* > improved;
idList< const sdStatsTracker::lifeStatsData_t* > unchanged;
idList< const sdStatsTracker::lifeStatsData_t* > worse;
sdGlobalStatsTracker::GetInstance().GetTopLifeStats( improved, unchanged, worse );
AddLifeStatsItems( list, "improved", improved );
AddLifeStatsItems( list, "unchanged", unchanged );
AddLifeStatsItems( list, "nodraw", worse );
}
class sdSortCategories {
public:
sdSortCategories( const sdProficiencyTable& table ) : table( table ) {}
int operator()( const sdDeclPlayerClass::proficiencyCategory_t* lhs, const sdDeclPlayerClass::proficiencyCategory_t* rhs ) {
float lhsPercent = table.GetPercent( lhs->index );
float rhsPercent = table.GetPercent( rhs->index );
return ( idMath::Ftoi( rhsPercent * 100 ) ) - ( idMath::Ftoi( lhsPercent * 100 ) );
}
const sdProficiencyTable& table;
};
/*
============
idGameLocal::CreatePredictedUpgradesList
============
*/
void idGameLocal::CreatePredictedUpgradesList( sdUIList* list ) {
sdUIList::ClearItems( list );
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
if( localPlayer == NULL ) {
return;
}
const sdTeamInfo* ti = localPlayer->GetGameTeam();
idList< const sdDeclPlayerClass::proficiencyCategory_t* > bestCategories;
const sdProficiencyTable& table = localPlayer->GetProficiencyTable();
for( int i = 0; i < gameLocal.declPlayerClassType.Num(); i++ ) {
const sdDeclPlayerClass* pc = gameLocal.declPlayerClassType.LocalFindByIndex( i );
if( pc->GetTeam() != ti && ti != NULL ) {
continue;
}
for ( int j = 0; j < pc->GetNumProficiencies(); j++ ) {
const sdDeclPlayerClass::proficiencyCategory_t& category = pc->GetProficiency( j );
float percent = table.GetPercent( category.index );
if( percent >= 1.0f ) {
continue;
}
int k;
for( k = 0; k < bestCategories.Num(); k++ ) {
if( bestCategories[ k ]->index == category.index ) {
break;
}
}
if( k >= bestCategories.Num() ) {
bestCategories.Append( &category );
}
}
}
sdQuickSort( bestCategories.Begin(), bestCategories.End(), sdSortCategories( table ) );
int numAdded = 0;
for( int i = 0; i < bestCategories.Num() && numAdded < 2; i++ ) {
int currentLevel = table.GetLevel( bestCategories[ i ]->index );
if( currentLevel < bestCategories[ i ]->upgrades.Num() ) {
const sdDeclProficiencyType* type = gameLocal.declProficiencyTypeType.LocalFindByIndex( bestCategories[ i ]->index );
const sdDeclPlayerClass::proficiencyUpgrade_t& upgrade = bestCategories[ i ]->upgrades[ currentLevel ];
int index = sdUIList::InsertItem( list, va( L"<material = '%hs'>\t<loc = '%hs'>\t<flags customdraw>%hs",
upgrade.materialInfo.c_str(),
upgrade.title->GetName(),
type->GetName() ),
-1, 0 );
float percent = table.GetPercent( bestCategories[ i ]->index );
// push some extra data along for the GUI
list->SetItemDataInt( percent * 100 , index, 0, true );
list->SetItemDataInt( currentLevel, index, 1, true );
numAdded++;
}
}
}
/*
============
idGameLocal::CreateUpgradesReviewList
============
*/
void idGameLocal::CreateUpgradesReviewList( sdUIList* list ) {
sdUIList::ClearItems( list );
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
if( localPlayer == NULL ) {
return;
}
const sdTeamInfo* ti = localPlayer->GetGameTeam();
const sdProficiencyTable& table = localPlayer->GetProficiencyTable();
idList< const sdDeclPlayerClass::proficiencyCategory_t* > bestCategories;
for( int i = 0; i < gameLocal.declPlayerClassType.Num(); i++ ) {
const sdDeclPlayerClass* pc = gameLocal.declPlayerClassType.LocalFindByIndex( i );
if( pc->GetTeam() != ti && ti != NULL ) {
continue;
}
for ( int j = 0; j < pc->GetNumProficiencies(); j++ ) {
const sdDeclPlayerClass::proficiencyCategory_t& category = pc->GetProficiency( j );
int k;
for( k = 0; k < bestCategories.Num(); k++ ) {
if( bestCategories[ k ]->index == category.index ) {
break;
}
}
if( k < bestCategories.Num() ) {
continue;
}
bestCategories.Append( &category );
int currentLevel = table.GetLevel(category.index );
for ( int level = 0; level < currentLevel && level < category.upgrades.Num(); level++ ) {
const sdDeclPlayerClass::proficiencyUpgrade_t& upgrade = category.upgrades[ level ];
int index = sdUIList::InsertItem( list, va( L"<material = '%hs'>\t<loc = '%hs'>",
upgrade.materialInfo.c_str(),
upgrade.title->GetName()),
-1, 0 );
}
}
}
}
/*
===============
idGameLocal::UpdateHudStats
===============
*/
void idGameLocal::UpdateHudStats( idPlayer* player ) {
localPlayerProperties.Update( player );
limboProperties.Update();
sdAdminSystem::GetInstance().UpdateProperties();
}
#undef ON_UIVALID
#undef ON_UIINVALID