etqw-sdk/source/game/rules/VoteManager.cpp

1792 lines
48 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 "VoteManager.h"
#include "../Player.h"
#include "../script/Script_Helper.h"
#include "../script/Script_ScriptObject.h"
#include "../rules/GameRules.h"
#include "../rules/AdminSystem.h"
#include "../guis/UserInterfaceLocal.h"
#include "../guis/UIList.h"
#include "../botai/Bot.h"
/*
================
sdCallVote::AddVoteOption
================
*/
void sdCallVote::AddVoteOption( sdUIList* list, const wchar_t* text ) {
AddVoteOption( list, text, list->GetNumItems() );
}
/*
================
sdCallVote::AddVoteOption
================
*/
void sdCallVote::AddVoteOption( sdUIList* list, const wchar_t* text, int dataKey ) {
int index = sdUIList::InsertItem( list, text, -1, 0 );
list->SetItemDataInt( dataKey, index, 0 );
}
/*
================
sdCallVote::CreateCmdArgs
================
*/
void sdCallVote::CreateCmdArgs( idCmdArgs& args ) const {
args.AppendArg( "callvote" );
args.AppendArg( GetCommandName() );
}
class sdCallVoteAdminCommandFinalizer : public sdVoteFinalizer {
public:
sdCallVoteAdminCommandFinalizer( const char* _command, const char* _suffix ) {
command = _command;
suffix = _suffix;
}
virtual void OnVoteCompleted( bool passed ) const {
if ( !passed ) {
return;
}
idCmdArgs args;
args.AppendArg( "admin" );
args.AppendArg( command );
if ( suffix != NULL ) {
args.AppendArg( suffix );
}
sdAdminSystem::GetInstance().PerformCommand( args, NULL );
}
private:
const char* command;
const char* suffix;
};
/*
================
sdCallVoteAdminCommand::EnumerateOptions
================
*/
void sdCallVoteAdminCommand::EnumerateOptions( sdUIList* list ) const {
}
/*
================
sdCallVoteAdminCommand::Execute
================
*/
void sdCallVoteAdminCommand::Execute( int dataKey ) const {
idCmdArgs args;
CreateCmdArgs( args );
sdVoteManagerLocal::Callvote_f( args );
}
/*
================
sdCallVoteAdminCommand::Execute
================
*/
sdPlayerVote* sdCallVoteAdminCommand::Execute( const idCmdArgs& args, idPlayer* player ) const {
sdPlayerVote* vote = sdVoteManager::GetInstance().AllocVote();
if ( vote != NULL ) {
vote->MakeGlobalVote();
vote->SetText( gameLocal.declToolTipType[ GetVoteTextKey() ] );
vote->SetFinalizer( new sdCallVoteAdminCommandFinalizer( GetAdminCommand(), GetAdminCommandSuffix() ) );
}
return vote;
}
class sdCallVoteShuffleXP : public sdCallVoteAdminCommand {
public:
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/shuffleXP" ); }
virtual const char* GetCommandName( void ) const { return "shufflexp"; }
virtual const char* GetAdminCommand( void ) const { return "shuffleteams"; }
virtual const char* GetAdminCommandSuffix( void ) const { return "xp"; }
virtual const char* GetVoteTextKey( void ) const { return "votes/shuffleXP/text"; }
};
class sdCallVoteShuffleRandom : public sdCallVoteAdminCommand {
public:
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/shuffleRandom" ); }
virtual const char* GetCommandName( void ) const { return "shufflerandom"; }
virtual const char* GetAdminCommand( void ) const { return "shuffleteams"; }
virtual const char* GetAdminCommandSuffix( void ) const { return "random"; }
virtual const char* GetVoteTextKey( void ) const { return "votes/shuffleRandom/text"; }
};
class sdCallVoteSwapTeams : public sdCallVoteAdminCommand {
public:
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/swapTeams" ); }
virtual const char* GetCommandName( void ) const { return "swapteams"; }
virtual const char* GetAdminCommand( void ) const { return "shuffleteams"; }
virtual const char* GetAdminCommandSuffix( void ) const { return "swap"; }
virtual const char* GetVoteTextKey( void ) const { return "votes/swapTeams/text"; }
virtual bool AllowedOnRankedServer( void ) const { return false; }
};
class sdCallVoteRestartMap : public sdCallVoteAdminCommand {
public:
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/restartMap" ); }
virtual const char* GetCommandName( void ) const { return "restartmap"; }
virtual const char* GetAdminCommand( void ) const { return "restartMap"; }
virtual const char* GetVoteTextKey( void ) const { return "votes/restartMap/text"; }
};
class sdCallVoteCVar : public sdCallVote {
public:
struct data_t {
const char* text;
int i;
};
class sdCallVoteCVarFinalizer : public sdVoteFinalizer {
public:
sdCallVoteCVarFinalizer( const char* _cvarName, data_t& _data ) {
cvarName = _cvarName;
data = _data;
}
virtual void OnVoteCompleted( bool passed ) const {
if ( !passed ) {
return;
}
cvarSystem->SetCVarInteger( cvarName, data.i );
}
private:
const char* cvarName;
data_t data;
};
virtual void EnumerateOptions( sdUIList* list ) const {
for ( int i = 0; i < GetCount(); i++ ) {
AddVoteOption( list, common->LocalizeText( GetData()[ i ].text ).c_str() );
}
}
virtual void Execute( int dataKey ) const {
idCmdArgs args;
CreateCmdArgs( args );
args.AppendArg( va( "%d", dataKey ) );
sdVoteManagerLocal::Callvote_f( args );
}
virtual sdPlayerVote* Execute( const idCmdArgs& args, idPlayer* player ) const {
if ( args.Argc() < 3 ) {
return NULL;
}
int value = atoi( args.Argv( 2 ) );
if ( value < 0 || value >= GetCount() ) {
return NULL;
}
data_t& data = GetData()[ value ];
sdPlayerVote* vote = sdVoteManager::GetInstance().AllocVote();
if ( vote != NULL ) {
vote->MakeGlobalVote();
vote->SetText( gameLocal.declToolTipType[ GetVoteTextKey() ] );
vote->AddTextParm( declHolder.declLocStrType[ data.text ] );
vote->SetFinalizer( new sdCallVoteCVarFinalizer( GetCVarName(), data ) );
}
return vote;
}
virtual data_t* GetData( void ) const = 0;
virtual int GetCount( void ) const = 0;
virtual const char* GetCVarName( void ) const = 0;
virtual const char* GetVoteTextKey( void ) const = 0;
};
sdCallVoteCVar::data_t g_sdCallVoteCVarOnOff_Data[] = {
{ "votes/values/on", 1 },
{ "votes/values/off", 0 },
};
class sdCallVoteCVarOnOff : public sdCallVoteCVar {
public:
virtual data_t* GetData( void ) const { return g_sdCallVoteCVarOnOff_Data; }
virtual int GetCount( void ) const { return _arraycount( g_sdCallVoteCVarOnOff_Data ); }
};
class sdCallVoteBalancedTeams : public sdCallVoteCVarOnOff {
public:
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/balancedTeams" ); }
virtual const char* GetCommandName( void ) const { return "balancedteams"; }
virtual const char* GetCVarName( void ) const { return "si_teamForceBalance"; }
virtual const char* GetVoteTextKey( void ) const { return "votes/balancedTeams/text"; }
virtual void PreCache( void ) const { gameLocal.declToolTipType[ GetVoteTextKey() ]; }
virtual bool AllowedOnRankedServer( void ) const { return false; }
};
class sdCallVoteTeamDamage : public sdCallVoteCVarOnOff {
public:
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/teamDamage" ); }
virtual const char* GetCommandName( void ) const { return "teamdamage"; }
virtual const char* GetCVarName( void ) const { return "si_teamDamage"; }
virtual const char* GetVoteTextKey( void ) const { return "votes/teamDamage/text"; }
virtual void PreCache( void ) const { gameLocal.declToolTipType[ GetVoteTextKey() ]; }
virtual bool AllowedOnRankedServer( void ) const { return false; }
};
class sdCallVoteNoXP : public sdCallVoteCVarOnOff {
public:
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/noXP" ); }
virtual const char* GetCommandName( void ) const { return "noxp"; }
virtual const char* GetCVarName( void ) const { return "si_noProficiency"; }
virtual const char* GetVoteTextKey( void ) const { return "votes/noXP/text"; }
virtual void PreCache( void ) const { gameLocal.declToolTipType[ GetVoteTextKey() ]; }
virtual bool AllowedOnRankedServer( void ) const { return false; }
};
sdCallVoteCVar::data_t g_sdCallVoteTimeLimit_Data[] = {
{ "votes/values/5", 5 },
{ "votes/values/10", 10 },
{ "votes/values/15", 15 },
{ "votes/values/20", 20 },
{ "votes/values/25", 25 },
{ "votes/values/30", 30 },
};
class sdCallVoteTimeLimit : public sdCallVoteCVar {
public:
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/timelimit" ); }
virtual const char* GetCommandName( void ) const { return "timelimit"; }
virtual const char* GetCVarName( void ) const { return "si_timeLimit"; }
virtual const char* GetVoteTextKey( void ) const { return "votes/timelimit/text"; }
virtual data_t* GetData( void ) const { return g_sdCallVoteTimeLimit_Data; }
virtual int GetCount( void ) const { return _arraycount( g_sdCallVoteTimeLimit_Data ); }
virtual void PreCache( void ) const { gameLocal.declToolTipType[ GetVoteTextKey() ]; }
virtual bool AllowedOnRankedServer( void ) const { return false; }
};
class sdCallVoteServerMode : public sdCallVote {
public:
class sdCallVoteServerModeFinalizer : public sdVoteFinalizer {
public:
sdCallVoteServerModeFinalizer( const char* _config ) {
config = _config;
}
virtual void OnVoteCompleted( bool passed ) const {
if ( !passed ) {
return;
}
idCmdArgs args;
args.AppendArg( "admin" );
args.AppendArg( "execConfig" );
args.AppendArg( config.c_str() );
sdAdminSystem::GetInstance().PerformCommand( args, NULL );
}
private:
idStr config;
};
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/serverMode" ); }
virtual const char* GetCommandName( void ) const { return "servermode"; }
virtual void PreCache( void ) const { gameLocal.declToolTipType[ "votes/serverMode/text" ]; }
virtual void EnumerateOptions( sdUIList* list ) const {
const idDict& configs = sdUserGroupManager::GetInstance().GetConfigs();
for ( int i = 0; i < configs.GetNumKeyVals(); i++ ) {
AddVoteOption( list, va( L"%hs", configs.GetKeyVal( i )->GetKey().c_str() ) );
}
}
virtual void Execute( int dataKey ) const {
const idDict& configs = sdUserGroupManager::GetInstance().GetConfigs();
if ( dataKey < 0 || dataKey >= configs.GetNumKeyVals() ) {
return;
}
idCmdArgs args;
CreateCmdArgs( args );
args.AppendArg( configs.GetKeyVal( dataKey )->GetKey().c_str() );
sdVoteManagerLocal::Callvote_f( args );
}
virtual sdPlayerVote* Execute( const idCmdArgs& args, idPlayer* player ) const {
if ( args.Argc() < 3 ) {
return NULL;
}
const char* configName = args.Argv( 2 );
const idDict& configs = sdUserGroupManager::GetInstance().GetConfigs();
if ( configs.FindKey( configName ) == NULL ) {
return NULL;
}
sdPlayerVote* vote = sdVoteManager::GetInstance().AllocVote();
if ( vote != NULL ) {
vote->MakeGlobalVote();
vote->SetText( gameLocal.declToolTipType[ "votes/serverMode/text" ] );
vote->AddTextParm( va( L"%hs", configName ) );
vote->SetFinalizer( new sdCallVoteServerModeFinalizer( configName ) );
}
return vote;
}
};
class sdPlayerCallVote : public sdCallVote {
public:
class sdPlayerCallVoteFinalizer : public sdVoteFinalizer {
public:
sdPlayerCallVoteFinalizer( idPlayer* _player, const char* _command, const char* _suffix ) {
player = _player;
command = _command;
suffix = _suffix;
}
virtual void OnVoteCompleted( bool passed ) const {
if ( !passed ) {
return;
}
if ( !player.IsValid() ) {
return;
}
idCmdArgs args;
args.AppendArg( "admin" );
args.AppendArg( command );
args.AppendArg( player->userInfo.cleanName.c_str() );
if ( suffix != NULL ) {
args.AppendArg( suffix );
}
sdAdminSystem::GetInstance().PerformCommand( args, NULL );
}
private:
idEntityPtr< idPlayer > player;
const char* command;
const char* suffix;
};
virtual void EnumerateOptions( sdUIList* list ) const {
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
idPlayer* player = gameLocal.GetClient( i );
if ( player == NULL || gameLocal.IsLocalPlayer( player ) ) {
continue;
}
AddVoteOption( list, va( L"%hs", player->userInfo.name.c_str() ), gameLocal.GetSpawnId( player ) );
}
}
virtual void Execute( int dataKey ) const {
idCmdArgs args;
CreateCmdArgs( args );
args.AppendArg( va( "%d", dataKey ) );
sdVoteManagerLocal::Callvote_f( args );
}
virtual sdPlayerVote* Execute( const idCmdArgs& args, idPlayer* player ) const {
if ( args.Argc() < 3 ) {
return NULL;
}
int spawnId = atoi( args.Argv( 2 ) );
idPlayer* other = gameLocal.EntityForSpawnId( spawnId )->Cast< idPlayer >();
if ( other == NULL || other == player ) {
return NULL;
}
sdPlayerVote* vote = sdVoteManager::GetInstance().AllocVote();
if ( vote != NULL ) {
vote->MakeGlobalVote();
vote->SetText( gameLocal.declToolTipType[ GetVoteTextKey() ] );
vote->AddTextParm( va( L"%hs", other->userInfo.name.c_str() ) );
vote->SetFinalizer( new sdPlayerCallVoteFinalizer( other, GetAdminCommand(), GetAdminCommandSuffix() ) );
}
return vote;
}
virtual const char* GetCommandName( void ) const = 0;
virtual const char* GetAdminCommand( void ) const = 0;
virtual const char* GetAdminCommandSuffix( void ) const { return NULL; }
virtual const char* GetVoteTextKey( void ) const = 0;
};
class sdCallVoteKickPlayer : public sdPlayerCallVote {
public:
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/kickplayer" ); }
virtual const char* GetCommandName( void ) const { return "kickplayer"; }
virtual const char* GetAdminCommand( void ) const { return "kick"; }
virtual const char* GetVoteTextKey( void ) const { return "votes/kickplayer/text"; }
virtual void PreCache( void ) const { gameLocal.declToolTipType[ GetVoteTextKey() ]; }
};
class sdCallVoteMutePlayer : public sdPlayerCallVote {
public:
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/mute" ); }
virtual const char* GetCommandName( void ) const { return "muteplayer"; }
virtual const char* GetAdminCommand( void ) const { return "playerMute"; }
virtual const char* GetAdminCommandSuffix( void ) const { return "on"; }
virtual const char* GetVoteTextKey( void ) const { return "votes/mute/text"; }
virtual void PreCache( void ) const { gameLocal.declToolTipType[ GetVoteTextKey() ]; }
};
class sdCallVoteMuteVoicePlayer : public sdPlayerCallVote {
public:
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/mutevoice" ); }
virtual const char* GetCommandName( void ) const { return "muteplayervoip"; }
virtual const char* GetAdminCommand( void ) const { return "playerVOIPMute"; }
virtual const char* GetAdminCommandSuffix( void ) const { return "on"; }
virtual const char* GetVoteTextKey( void ) const { return "votes/mutevoice/text"; }
virtual void PreCache( void ) const { gameLocal.declToolTipType[ GetVoteTextKey() ]; }
};
class sdCallVoteMapChange : public sdCallVote {
public:
static const idDict* sdCallVoteMapChange::GetMapData( const char* name ) {
const metaDataContext_t* metaData = gameLocal.mapMetaDataList->FindMetaDataContext( name );
if ( metaData == NULL ) {
return NULL;
}
if ( !gameLocal.IsMetaDataValidForPlay( *metaData, true ) ) {
return NULL;
}
return metaData->meta;
}
static const idDict* sdCallVoteMapChange::GetMapData( int index ) {
if( index < 0 || index > gameLocal.mapMetaDataList->GetNumMetaData() ) {
return NULL;
}
const metaDataContext_t& metaData = gameLocal.mapMetaDataList->GetMetaDataContext( index );
if ( !gameLocal.IsMetaDataValidForPlay( metaData, true ) ) {
return NULL;
}
return metaData.meta;
}
static const sdDeclMapInfo* sdCallVoteMapChange::GetMapInfo( const char* name ) {
const idDict* mapData = GetMapData( name );
if ( mapData == NULL ) {
return NULL;
}
const char* mapInfoName = mapData->GetString( "mapinfo" );
if ( mapInfoName[ 0 ] == '\0' ) {
return NULL;
}
return gameLocal.declMapInfoType[ mapInfoName ];
}
static const sdDeclMapInfo* sdCallVoteMapChange::GetMapInfo( int index ) {
const idDict* mapData = GetMapData( index );
if ( mapData == NULL ) {
return NULL;
}
const char* mapInfoName = mapData->GetString( "mapinfo" );
if ( mapInfoName[ 0 ] == '\0' ) {
return NULL;
}
return gameLocal.declMapInfoType[ mapInfoName ];
}
class sdCallVoteMapChangeFinalizer : public sdVoteFinalizer {
public:
sdCallVoteMapChangeFinalizer( const char* _mapName, const char* _mode ) {
mapName = _mapName;
mode = _mode;
}
virtual void OnVoteCompleted( bool passed ) const {
if ( !passed ) {
return;
}
idCmdArgs args;
args.AppendArg( "admin" );
args.AppendArg( mode );
args.AppendArg( mapName.c_str() );
sdAdminSystem::GetInstance().PerformCommand( args, NULL );
}
private:
idStr mapName;
const char* mode;
};
virtual void sdCallVoteMapChange::EnumerateOptions( sdUIList* list ) const {
for ( int i = 0; i < gameLocal.mapMetaDataList->GetNumMetaData(); i++ ) {
const idDict* mapInfo = GetMapData( i );
if ( mapInfo == NULL ) {
continue;
}
const char* materialName = mapInfo->GetString( "server_shot_thumb", "levelshots/thumbs/generic.tga" );
AddVoteOption( list, va( L"%hs\t%hs\t1.7777", mapInfo->GetString( "pretty_name", "" ), materialName ), i );
}
}
virtual void sdCallVoteMapChange::Execute( int dataKey ) const {
idCmdArgs args;
CreateCmdArgs( args );
const char* name = GetMapData( dataKey )->GetString( "metadata_name" );
args.AppendArg( name );
sdVoteManagerLocal::Callvote_f( args );
}
virtual sdPlayerVote* sdCallVoteMapChange::Execute( const idCmdArgs& args, idPlayer* player ) const {
if ( args.Argc() < 3 ) {
return NULL;
}
const char* metaDataName = args.Argv( 2 );
const idDict* mapData = GetMapData( metaDataName );
if ( mapData == NULL ) {
return NULL;
}
const sdDeclMapInfo* mapInfo = GetMapInfo( metaDataName );
if ( mapInfo == NULL ) {
assert( false );
return NULL;
}
sdPlayerVote* vote = sdVoteManager::GetInstance().AllocVote();
if ( vote != NULL ) {
vote->MakeGlobalVote();
vote->SetText( gameLocal.declToolTipType[ GetVoteTextKey() ] );
vote->AddTextParm( va( L"%hs", mapData->GetString( "pretty_name", "" ) ) );
vote->SetFinalizer( new sdCallVoteMapChangeFinalizer( mapData->GetString( "metadata_name" ), GetModeName() ) );
}
return vote;
}
virtual const char* GetVoteTextKey( void ) const = 0;
virtual const char* GetModeName( void ) const = 0;
virtual void PreCache( void ) const { PreCache( this ); }
protected:
static void PreCache( const sdCallVoteMapChange* command ) {
gameLocal.declToolTipType[ command->GetVoteTextKey() ];
}
};
class sdCallVoteObjectiveMap : public sdCallVoteMapChange {
public:
virtual const char* GetCommandName( void ) const { return "setobjectivemap"; }
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/setobjectivemap" ); }
virtual const char* GetVoteTextKey( void ) const { return "votes/setobjectivemap/text"; }
virtual const char* GetModeName( void ) const { return "setObjectiveMap"; }
virtual bool AllowedOnRankedServer( void ) const { return false; }
};
class sdCallVoteStopWatchMap : public sdCallVoteMapChange {
public:
virtual const char* GetCommandName( void ) const { return "setstopwatchmap"; }
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/setstopwatchmap" ); }
virtual const char* GetVoteTextKey( void ) const { return "votes/setstopwatchmap/text"; }
virtual const char* GetModeName( void ) const { return "setStopWatchMap"; }
virtual bool AllowedOnRankedServer( void ) const { return false; }
};
class sdCallVoteCampaignChange : public sdCallVote {
public:
virtual const char* GetCommandName( void ) const { return "setcampaign"; }
virtual void GetText( idWStr& out ) const { out = common->LocalizeText( "votes/setcampaign" ); }
class sdCallVoteCampaignChangeFinalizer : public sdVoteFinalizer {
public:
sdCallVoteCampaignChangeFinalizer( const char* _campaignName ) {
campaignName = _campaignName;
}
virtual void OnVoteCompleted( bool passed ) const {
if ( !passed ) {
return;
}
idCmdArgs args;
args.AppendArg( "admin" );
args.AppendArg( "setCampaign" );
args.AppendArg( campaignName.c_str() );
sdAdminSystem::GetInstance().PerformCommand( args, NULL );
}
private:
idStr campaignName;
};
virtual void EnumerateOptions( sdUIList* list ) const {
for( int i = 0; i < gameLocal.campaignMetaDataList->GetNumMetaData(); i++ ) {
const metaDataContext_t& metaData = gameLocal.campaignMetaDataList->GetMetaDataContext( i );
if ( !gameLocal.IsMetaDataValidForPlay( metaData, true ) ) {
continue;
}
const idDict& dict = *metaData.meta;
const char* materialName = dict.GetString( "server_shot_thumb" );
const char* prettyName = dict.GetString( "pretty_name" );
AddVoteOption( list, va( L"%hs\t%hs\t1.333", prettyName, materialName ), i );
}
}
virtual void Execute( int dataKey ) const {
if( dataKey < 0 || dataKey >= gameLocal.campaignMetaDataList->GetNumMetaData() ) {
gameLocal.Warning( "sdCallVoteCampaignChange: index '%i' out of range", dataKey );
return;
}
const metaDataContext_t& metaData = gameLocal.campaignMetaDataList->GetMetaDataContext( dataKey );
if ( !gameLocal.IsMetaDataValidForPlay( metaData, true ) ) {
return;
}
const idDict& dict = *metaData.meta;
const sdDeclCampaign* campaign = gameLocal.declCampaignType.LocalFind( dict.GetString( "metadata_name" ), false );
if ( campaign == NULL ) {
return;
}
idCmdArgs args;
CreateCmdArgs( args );
args.AppendArg( campaign->GetName() );
sdVoteManagerLocal::Callvote_f( args );
}
virtual sdPlayerVote* Execute( const idCmdArgs& args, idPlayer* player ) const {
if ( args.Argc() < 3 ) {
return NULL;
}
const char* campaignName = args.Argv( 2 );
const metaDataContext_t* metaData = gameLocal.campaignMetaDataList->FindMetaDataContext( campaignName );
if ( metaData == NULL ) {
return NULL;
}
if ( !gameLocal.IsMetaDataValidForPlay( *metaData, true ) ) {
return NULL;
}
const sdDeclCampaign* campaign = gameLocal.declCampaignType[ campaignName ];
if ( campaign == NULL ) {
return NULL;
}
sdPlayerVote* vote = sdVoteManager::GetInstance().AllocVote();
if ( vote != NULL ) {
vote->MakeGlobalVote();
vote->SetText( gameLocal.declToolTipType[ "votes/setcampaign/text" ] );
const idDict* dict = gameLocal.campaignMetaDataList->FindMetaData( campaignName, &gameLocal.defaultMetaData );
vote->AddTextParm( va( L"%hs", dict->GetString( "pretty_name" ) ) );
vote->SetFinalizer( new sdCallVoteCampaignChangeFinalizer( campaignName ) );
}
return vote;
}
virtual void PreCache( void ) const {
gameLocal.declToolTipType[ "votes/setcampaign/text" ];
}
};
/*
================
sdVoteModePrivate::sdVoteModePrivate
================
*/
sdVoteModePrivate::sdVoteModePrivate( idPlayer* other ) {
client = other;
}
/*
================
sdVoteModePrivate::CanVote
================
*/
bool sdVoteModePrivate::CanVote( idPlayer* player ) const {
return client == player;
}
/*
================
sdVoteModeTeam::sdVoteModeTeam
================
*/
sdVoteModeTeam::sdVoteModeTeam( sdTeamInfo* _team ) {
team = _team;
}
/*
================
sdVoteModeTeam::CanVote
================
*/
bool sdVoteModeTeam::CanVote( idPlayer* player ) const {
return player->GetTeam() == team;
}
/*
================
sdVoteModeGlobal::CanVote
================
*/
bool sdVoteModeGlobal::CanVote( idPlayer* player ) const {
return true;
}
/*
================
sdVoteFinalizer_Script::sdVoteFinalizer_Script
================
*/
sdVoteFinalizer_Script::sdVoteFinalizer_Script( idScriptObject* object, const char* functionName ) : scriptObjectHandle( 0 ), function( NULL ) {
if ( !object ) {
gameLocal.Warning( "sdVoteFinalizer_Script::sdVoteFinalizer_Script No Scriptobject" );
return;
}
scriptObjectHandle = object->GetHandle();
function = object->GetFunction( functionName );
if ( !function ) {
gameLocal.Warning( "sdVoteFinalizer_Script::sdVoteFinalizer_Script Invalid Function '%s'", functionName );
return;
}
}
/*
================
sdVoteFinalizer_Script::OnVoteCompleted
================
*/
void sdVoteFinalizer_Script::OnVoteCompleted( bool passed ) const {
idScriptObject* object = gameLocal.program->GetScriptObject( scriptObjectHandle );
if ( !object || !function ) {
return;
}
sdScriptHelper h1;
h1.Push( passed ? 1.f : 0.f );
object->CallNonBlockingScriptEvent( function, h1 );
}
/*
================
sdPlayerVote::sdPlayerVote
================
*/
sdPlayerVote::sdPlayerVote( void ) : index( -1 ), mode( NULL ), endTime( 0 ), finalizer( NULL ),
yesCount( 0 ), noCount( 0 ), totalCount( 0 ), text( NULL ), voteId( VI_NONE ), displayFinishedMessage( true ) {
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
votes[ i ] = VS_CANNOT_VOTE;
}
activeNode.SetOwner( this );
}
/*
================
sdPlayerVote::~sdPlayerVote
================
*/
sdPlayerVote::~sdPlayerVote( void ) {
ClearMode();
ClearFinalizer();
}
/*
================
sdPlayerVote::AddTextParm
================
*/
void sdPlayerVote::AddTextParm( const sdDeclLocStr* text ) {
textParm_t& parm = textParms.Alloc();
parm.locStr = text;
}
/*
================
sdPlayerVote::AddTextParm
================
*/
void sdPlayerVote::AddTextParm( const wchar_t* text ) {
textParm_t& parm = textParms.Alloc();
parm.text = text;
parm.locStr = NULL;
}
/*
================
sdPlayerVote::MakeTeamVote
================
*/
void sdPlayerVote::MakeTeamVote( sdTeamInfo* team ) {
ClearMode();
mode = new sdVoteModeTeam( team );
SetVoteFlags();
}
/*
================
sdPlayerVote::MakePrivateVote
================
*/
void sdPlayerVote::MakePrivateVote( idPlayer* client ) {
ClearMode();
mode = new sdVoteModePrivate( client );
SetVoteFlags();
}
/*
================
sdPlayerVote::MakeGlobalVote
================
*/
void sdPlayerVote::MakeGlobalVote( void ) {
ClearMode();
mode = new sdVoteModeGlobal();
SetVoteFlags();
}
/*
================
sdPlayerVote::ClearMode
================
*/
void sdPlayerVote::ClearMode( void ) {
delete mode;
mode = NULL;
}
/*
================
sdPlayerVote::ClearFinalizer
================
*/
void sdPlayerVote::ClearFinalizer( void ) {
delete finalizer;
finalizer = NULL;
}
/*
================
sdPlayerVote::SetVoteFlags
================
*/
void sdPlayerVote::SetVoteFlags( void ) {
if ( gameLocal.isClient ) {
if ( voteCaller.IsValid() && gameLocal.IsLocalPlayer( voteCaller ) ) {
votes[ gameLocal.localClientNum ] = VS_YES;
} else {
votes[ gameLocal.localClientNum ] = VS_NOT_VOTED;
}
return;
}
assert( mode );
totalCount = 0;
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
idPlayer* player = gameLocal.GetClient( i );
if ( !player || player->GetType()->IsType( idBot::Type ) || !mode->CanVote( player ) ) {
votes[ i ] = VS_CANNOT_VOTE;
} else {
totalCount++;
votes[ i ] = VS_NOT_VOTED;
}
}
}
/*
================
sdPlayerVote::Start
================
*/
void sdPlayerVote::Start( idPlayer* player ) {
int length = text ? text->GetLength() : SEC2MS( 30.f );
endTime = gameLocal.ToGuiTime( gameLocal.time + length );
sdVoteManager::GetInstance().MakeActive( activeNode );
voteCaller = player;
if ( text ) {
finalText.Clear();
if ( player != NULL ) {
const sdDeclLocStr* locStr = declHolder.declLocStrType[ "votes/playercalled" ];
if ( locStr != NULL ) {
idWStrList parms( 1 ); parms.Append( va( L"%hs", player->GetUserInfo().name.c_str() ) );
finalText = common->LocalizeText( locStr, parms );
}
}
sdToolTipParms parms;
for ( int i = 0; i < textParms.Num(); i++ ) {
if ( textParms[ i ].locStr != NULL ) {
parms.Add( textParms[ i ].locStr->GetText() );
} else {
parms.Add( textParms[ i ].text.c_str() );
}
}
idWStr guiText;
text->GetMessage( &parms, guiText );
finalText.Append( guiText );
}
if ( gameLocal.isServer ) {
sdReliableServerMessage msg( GAME_RELIABLE_SMESSAGE_VOTE );
msg.WriteBits( sdVoteManagerLocal::VM_CREATE, idMath::BitsForInteger( sdVoteManagerLocal::VM_NUM ) );
msg.WriteBits( index, idMath::BitsForInteger( sdVoteManagerLocal::MAX_VOTES ) );
if ( player != NULL ) {
msg.WriteBits( 1, 1 );
msg.WriteByte( player->entityNumber );
} else {
msg.WriteBits( 0, 1 );
}
msg.WriteBits( text ? text->Index() + 1 : 0, idMath::BitsForInteger( gameLocal.declToolTipType.Num() + 1 ) );
msg.WriteLong( textParms.Num() );
for ( int i = 0; i < textParms.Num(); i++ ) {
if ( textParms[ i ].locStr != NULL ) {
msg.WriteBool( false );
msg.WriteLong( textParms[ i ].locStr->Index() );
} else {
msg.WriteBool( true );
msg.WriteString( textParms[ i ].text.c_str() );
}
}
msg.WriteLong( endTime );
SendMessage( msg );
}
}
/*
================
sdPlayerVote::Vote
================
*/
void sdPlayerVote::Vote( bool result ) {
if ( result ) {
yesCount++;
} else {
noCount++;
}
}
/*
================
sdPlayerVote::Vote
================
*/
void sdPlayerVote::Vote( idPlayer* client, bool result ) {
int clientIndex = client->entityNumber;
if ( votes[ clientIndex ] != VS_NOT_VOTED ) {
// already voted or not eligible
// TODO: send message
return;
}
if ( result ) {
votes[ clientIndex ] = VS_YES;
yesCount++;
} else {
votes[ clientIndex ] = VS_NO;
noCount++;
}
if ( gameLocal.isServer ) {
sdReliableServerMessage msg( GAME_RELIABLE_SMESSAGE_VOTE );
msg.WriteBits( sdVoteManagerLocal::VM_VOTE, idMath::BitsForInteger( sdVoteManagerLocal::VM_NUM ) );
msg.WriteBits( index, idMath::BitsForInteger( sdVoteManagerLocal::MAX_VOTES ) );
msg.WriteBool( result );
SendMessage( msg );
}
// check if there are enough people left for it to be able to fail/pass
int votesLeft = totalCount - ( noCount + yesCount );
float minYesPcnt = ( yesCount ) / ( float )totalCount;
float maxYesPcnt = ( yesCount + votesLeft ) / ( float )totalCount;
float passPcnt = GetPassPercentage();
if ( minYesPcnt >= passPcnt || maxYesPcnt < passPcnt ) {
endTime = 0; // this will make us be marked as complete on next check
}
}
/*
================
sdPlayerVote::ClientVote
================
*/
void sdPlayerVote::ClientVote( bool result ) {
assert( gameLocal.isClient );
votes[ gameLocal.localClientNum ] = result ? VS_YES : VS_NO;
sdReliableClientMessage msg( GAME_RELIABLE_CMESSAGE_VOTE );
msg.WriteBits( GetIndex(), idMath::BitsForInteger( sdVoteManagerLocal::MAX_VOTES ) );
msg.WriteLong( GetEndTime() );
msg.WriteBool( result );
msg.Send();
}
/*
================
sdPlayerVote::SendMessage
================
*/
void sdPlayerVote::SendMessage( sdReliableServerMessage& msg ) {
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
if ( votes[ i ] == VS_CANNOT_VOTE ) {
continue;
}
msg.Send( sdReliableMessageClientInfo( i ) );
}
}
/*
================
sdPlayerVote::Tag
================
*/
void sdPlayerVote::Tag( voteId_t id, idEntity* object ) {
voteId = id;
voteObject = object;
}
/*
================
sdPlayerVote::Match
================
*/
bool sdPlayerVote::Match( voteId_t id, idEntity* object ) {
return voteId == id && voteObject == object;
}
idCVar g_votePassPercentage( "g_votePassPercentage", "51", CVAR_GAME | CVAR_FLOAT | CVAR_ARCHIVE | CVAR_RANKLOCKED, "Percentage of yes votes required for a vote to pass", 0.f, 100.f );
idCVar g_minAutoVotePlayers( "g_minAutoVotePlayers", "0", CVAR_GAME | CVAR_INTEGER | CVAR_ARCHIVE, "If this number of players has voted, then the vote will be considered valid even if the required % of yes/no votes has not been met" );
/*
================
sdPlayerVote::GetPassPercentage
================
*/
float sdPlayerVote::GetPassPercentage( void ) const {
return g_votePassPercentage.GetFloat() / 100.f;
}
/*
================
sdPlayerVote::Complete
================
*/
void sdPlayerVote::Complete( void ) {
bool passed;
if ( g_minAutoVotePlayers.GetInteger() > 0 && ( yesCount + noCount ) >= g_minAutoVotePlayers.GetInteger() ) {
passed = yesCount > noCount;
} else {
float frac = ( yesCount / ( float )totalCount );
passed = frac >= GetPassPercentage();
}
if ( displayFinishedMessage ) {
const sdDeclLocStr* finishedMessage = NULL;
if ( passed ) {
finishedMessage = declHolder.declLocStrType[ "votes/finished/success" ];
} else {
finishedMessage = declHolder.declLocStrType[ "votes/finished/failed" ];
}
if ( finishedMessage == NULL ) {
gameLocal.Warning( "sdPlayerVote::Complete Missing Vote Complete Mission" );
} else {
for ( int i = 0; i < MAX_CLIENTS; i++ ) {
if ( votes[ i ] == VS_CANNOT_VOTE ) {
continue;
}
idPlayer* player = gameLocal.GetClient( i );
if ( !player ) {
continue;
}
player->SendLocalisedMessage( finishedMessage, idWStrList() );
}
}
}
if ( finalizer == NULL ) {
gameLocal.Warning( "sdPlayerVote::Complete Vote completed with no Finalizer" );
return;
}
finalizer->OnVoteCompleted( passed );
}
/*
================
sdPlayerVote::GetPlayerCanVote
================
*/
bool sdPlayerVote::GetPlayerCanVote( idPlayer* player ) const {
return votes[ player->entityNumber ] == VS_NOT_VOTED;
}
/*
================
sdVoteManagerLocal::sdVoteManagerLocal
================
*/
sdVoteManagerLocal::sdVoteManagerLocal( void ) {
memset( votes, 0, sizeof( votes ) );
}
/*
================
sdVoteManagerLocal::~sdVoteManagerLocal
================
*/
sdVoteManagerLocal::~sdVoteManagerLocal( void ) {
globalCallVotes.DeleteContents( true );
}
/*
================
sdVoteManagerLocal::AllocVote
================
*/
sdPlayerVote* sdVoteManagerLocal::AllocVote( int index ) {
if ( index == -1 ) {
if ( gameLocal.isClient ) {
gameLocal.Error( "sdVoteManagerLocal::AllocVote Tried to Create a Vote on a Network Client" );
return NULL;
}
for ( int i = 0; i < MAX_VOTES; i++ ) {
if ( votes[ i ] != NULL ) {
continue;
}
index = i;
break;
}
}
if ( index == -1 ) {
gameLocal.Error( "sdVoteManagerLocal::AllocVote Max Votes Hit" );
return NULL;
}
votes[ index ] = new sdPlayerVote();
votes[ index ]->Init( index );
return votes[ index ];
}
/*
================
sdVoteManagerLocal::Think
================
*/
void sdVoteManagerLocal::Think( void ) {
sdPlayerVote* next = activeVotes.Next();
for ( sdPlayerVote* vote = next; vote; vote = next ) {
next = vote->GetNextActiveVote();
int endTime = vote->GetEndTime();
if ( gameLocal.ToGuiTime( gameLocal.time ) < endTime ) {
continue;
}
int index = vote->GetIndex();
vote->Complete();
FreeVote( index );
}
}
/*
================
sdVoteManagerLocal::FreeVote
================
*/
void sdVoteManagerLocal::FreeVote( int index ) {
if ( index < 0 || index > MAX_VOTES ) {
assert( false );
return;
}
sdPlayerVote* vote = votes[ index ];
if( vote == NULL ) {
return;
}
if ( gameLocal.isServer ) {
sdReliableServerMessage msg( GAME_RELIABLE_SMESSAGE_VOTE );
msg.WriteBits( VM_FREE, idMath::BitsForInteger( VM_NUM ) );
msg.WriteBits( index, idMath::BitsForInteger( sdVoteManagerLocal::MAX_VOTES ) );
vote->SendMessage( msg );
}
delete votes[ index ];
votes[ index ] = NULL;
}
/*
================
sdVoteManagerLocal::AllocVote
================
*/
void sdVoteManagerLocal::FreeVotes( void ) {
for ( int i = 0; i < MAX_VOTES; i++ ) {
FreeVote( i );
}
}
/*
================
sdVoteManagerLocal::Init
================
*/
void sdVoteManagerLocal::Init( void ) {
globalCallVotes.Alloc() = new sdCallVoteObjectiveMap();
globalCallVotes.Alloc() = new sdCallVoteStopWatchMap();
globalCallVotes.Alloc() = new sdCallVoteCampaignChange();
globalCallVotes.Alloc() = new sdCallVoteShuffleXP();
globalCallVotes.Alloc() = new sdCallVoteShuffleRandom();
globalCallVotes.Alloc() = new sdCallVoteSwapTeams();
globalCallVotes.Alloc() = new sdCallVoteBalancedTeams();
globalCallVotes.Alloc() = new sdCallVoteTeamDamage();
globalCallVotes.Alloc() = new sdCallVoteNoXP();
globalCallVotes.Alloc() = new sdCallVoteTimeLimit();
globalCallVotes.Alloc() = new sdCallVoteServerMode();
globalCallVotes.Alloc() = new sdCallVoteKickPlayer();
globalCallVotes.Alloc() = new sdCallVoteMutePlayer();
globalCallVotes.Alloc() = new sdCallVoteMuteVoicePlayer();
for( int i = 0; i < globalCallVotes.Num(); i++ ) {
globalCallVotes[ i ]->PreCache();
}
}
/*
================
sdVoteManagerLocal::MakeActive
================
*/
void sdVoteManagerLocal::MakeActive( idLinkList< sdPlayerVote >& node ) {
node.AddToEnd( activeVotes );
}
idCVar g_voteKeepVote( "g_voteKeepVote", "1", CVAR_GAME | CVAR_BOOL | CVAR_ARCHIVE, "Keep vote on the HUD after having voted" );
/*
================
sdVoteManagerLocal::GetActiveVote
================
*/
sdPlayerVote* sdVoteManagerLocal::GetActiveVote( idPlayer* p ) {
if ( p == NULL ) {
return NULL;
}
// get first vote player hasn't voted on
for ( sdPlayerVote* vote = activeVotes.Next(); vote != NULL; vote = vote->GetNextActiveVote() ) {
if ( !vote->GetPlayerCanVote( p ) ) {
continue;
}
return vote;
}
// get first vote player is part of
if ( g_voteKeepVote.GetBool() ) {
for ( sdPlayerVote* vote = activeVotes.Next(); vote != NULL; vote = vote->GetNextActiveVote() ) {
if ( vote->GetVoteState( p ) != sdPlayerVote::VS_CANNOT_VOTE ) {
return vote;
}
}
}
return NULL;
}
/*
================
sdVoteManagerLocal::ClientReadNetworkMessage
================
*/
void sdVoteManagerLocal::ClientReadNetworkMessage( const idBitMsg& msg ) {
idPlayer* player = NULL;
voteMessage_t message = ( voteMessage_t )msg.ReadBits( idMath::BitsForInteger( VM_NUM ) );
switch ( message ) {
case VM_CREATE: {
int index = msg.ReadBits( idMath::BitsForInteger( MAX_VOTES ) );
FreeVote( index );
if ( msg.ReadBits( 1 ) != 0 ) {
int client = msg.ReadByte();
if ( client >= 0 || client < MAX_CLIENTS ) {
player = gameLocal.GetClient( client );
}
}
sdPlayerVote* vote = AllocVote( index );
int toolTipIndex = msg.ReadBits( idMath::BitsForInteger( gameLocal.declToolTipType.Num() ) );
const sdDeclToolTip* toolTip = toolTipIndex ? gameLocal.declToolTipType[ toolTipIndex - 1 ] : NULL;
vote->SetText( toolTip );
int textCount = msg.ReadLong();
for ( int i = 0; i < textCount; i++ ) {
if ( !msg.ReadBool() ) {
vote->AddTextParm( declHolder.declLocStrType.SafeIndex( msg.ReadLong() ) );
} else {
wchar_t buffer[ 128 ];
msg.ReadString( buffer, sizeof( buffer ) / sizeof( wchar_t ) );
vote->AddTextParm( buffer );
}
}
vote->Start( player );
vote->SetEndTime( msg.ReadLong() );
vote->SetVoteFlags();
break;
}
case VM_FREE: {
int index = msg.ReadBits( idMath::BitsForInteger( MAX_VOTES ) );
FreeVote( index );
break;
}
case VM_VOTE: {
int index = msg.ReadBits( idMath::BitsForInteger( MAX_VOTES ) );
sdPlayerVote* v = votes[ index ];
if ( v ) {
v->Vote( msg.ReadBool() );
}
break;
}
}
}
/*
================
sdVoteManagerLocal::ServerReadNetworkMessage
================
*/
void sdVoteManagerLocal::ServerReadNetworkMessage( idPlayer* client, const idBitMsg& msg ) {
int index = msg.ReadBits( idMath::BitsForInteger( MAX_VOTES ) );
int endTime = msg.ReadLong();
bool result = msg.ReadBool();
sdPlayerVote* v = votes[ index ];
if ( !v ) {
return;
}
if ( v->GetEndTime() != endTime ) {
return; // try to make sure we are talking about the same vote
}
v->Vote( client, result );
}
/*
============
sdVoteManagerLocal::PerformCommand
============
*/
void sdVoteManagerLocal::PerformCommand( const idCmdArgs& args, idPlayer* player ) {
const char* cmd = args.Argv( 1 );
sdCallVote* vote = NULL;
for ( int i = 0; i < globalCallVotes.Num(); i++ ) {
if ( idStr::Icmp( globalCallVotes[ i ]->GetCommandName(), cmd ) != 0 ) {
continue;
}
vote = globalCallVotes[ i ];
break;
}
if ( vote == NULL && gameLocal.rules != NULL ) {
const idList< sdCallVote* >& ruleVotes = gameLocal.rules->GetCallVotes();
for ( int i = 0; i < ruleVotes.Num(); i++ ) {
if ( idStr::Icmp( ruleVotes[ i ]->GetCommandName(), cmd ) != 0 ) {
continue;
}
vote = ruleVotes[ i ];
break;
}
}
if ( vote != NULL ) {
if ( !CanUseVote( vote, player ) ) {
return;
}
sdPlayerVote* playerVote = vote->Execute( args, player );
if ( playerVote == NULL ) {
return;
}
player->SetNextCallVoteTime( gameLocal.ToGuiTime( gameLocal.time + MINS2MS( g_voteWait.GetFloat() ) ) );
playerVote->Start( player );
if ( player != NULL ) {
playerVote->Vote( player, true );
}
}
}
/*
============
sdVoteManagerLocal::CancelVote
============
*/
void sdVoteManagerLocal::CancelVote( voteId_t id, idEntity* object ) {
while ( sdPlayerVote* vote = FindVote( id, object ) ) {
FreeVote( vote->GetIndex() );
}
}
/*
============
sdVoteManagerLocal::CancelVote
============
*/
void sdVoteManagerLocal::CancelVote( sdPlayerVote* vote ) {
FreeVote( vote->GetIndex() );
}
/*
============
sdVoteManagerLocal::CancelFireTeamVotesForPlayer
============
*/
void sdVoteManagerLocal::CancelFireTeamVotesForPlayer( idPlayer *player ) {
CancelVote( VI_FIRETEAM_CREATE, player );
CancelVote( VI_FIRETEAM_JOIN, player );
CancelVote( VI_FIRETEAM_REQUEST, player );
CancelVote( VI_FIRETEAM_PROPOSE, player );
CancelVote( VI_FIRETEAM_INVITE, player );
}
/*
============
sdVoteManagerLocal::FindVote
============
*/
sdPlayerVote* sdVoteManagerLocal::FindVote( voteId_t id ) {
for ( sdPlayerVote* vote = activeVotes.Next(); vote; vote = vote->GetNextActiveVote() ) {
if ( vote->GetVoteId() != id ) {
continue;
}
return vote;
}
return NULL;
}
/*
============
sdVoteManagerLocal::FindVote
============
*/
sdPlayerVote* sdVoteManagerLocal::FindVote( voteId_t id, idEntity* object ) {
for ( sdPlayerVote* vote = activeVotes.Next(); vote; vote = vote->GetNextActiveVote() ) {
if ( !vote->Match( id, object ) ) {
continue;
}
return vote;
}
return NULL;
}
/*
============
sdVoteManagerLocal::CreateCallVoteList
============
*/
void sdVoteManagerLocal::CreateCallVoteList( sdUIList* list ) {
sdUIList::ClearItems( list );
sdVoteManagerLocal& manager = sdVoteManager::GetInstance();
manager.EnumerateCallVotes( list );
}
/*
============
sdVoteManagerLocal::CreateCallVoteOptionList
============
*/
void sdVoteManagerLocal::CreateCallVoteOptionList( sdUIList* list ) {
sdUIList::ClearItems( list );
int index;
list->GetUI()->PopScriptVar( index );
sdCallVote* vote = sdVoteManager::GetInstance().CallVoteForIndex( index );
if ( vote == NULL ) {
return;
}
vote->EnumerateOptions( list );
}
/*
============
sdVoteManagerLocal::EnumerateCallVotes
============
*/
void sdVoteManagerLocal::EnumerateCallVotes( sdUIList* list ) {
idPlayer* localPlayer = gameLocal.GetLocalPlayer();
if ( localPlayer == NULL ) {
return;
}
int voteIndex = 0;
for ( int i = 0; i < globalCallVotes.Num(); i++, voteIndex++ ) {
if( !globalCallVotes[ i ]->AllowedOnRankedServer() && networkSystem->IsRankedServer() ) {
continue;
}
PushVoteItem( list, globalCallVotes[ i ], voteIndex );
}
if ( gameLocal.rules != NULL ) {
const idList< sdCallVote* >& ruleVotes = gameLocal.rules->GetCallVotes();
for ( int i = 0; i < ruleVotes.Num(); i++, voteIndex++ ) {
if( !globalCallVotes[ i ]->AllowedOnRankedServer() && networkSystem->IsRankedServer() ) {
continue;
}
PushVoteItem( list, ruleVotes[ i ], voteIndex );
}
}
}
/*
============
sdVoteManagerLocal::ExecVote
============
*/
void sdVoteManagerLocal::ExecVote( sdUserInterfaceLocal* ui ) {
int voteIndex;
ui->PopScriptVar( voteIndex );
int voteKey;
ui->PopScriptVar( voteKey );
sdCallVote* vote = CallVoteForIndex( voteIndex );
if ( vote == NULL ) {
return;
}
vote->Execute( voteKey );
}
/*
============
sdVoteManagerLocal::CanUseVote
============
*/
bool sdVoteManagerLocal::CanUseVote( sdCallVote* vote, idPlayer* player ) {
if ( gameLocal.serverInfoData.votingDisabled ) {
return false;
}
if ( !vote->AllowedOnRankedServer() ) {
if ( networkSystem->IsRankedServer() ) {
return false;
}
}
if( player == NULL ) {
return false;
}
const sdUserGroup& group = sdUserGroupManager::GetInstance().GetGroup( player->GetUserGroup() );
int voteLevel = sdUserGroupManager::GetInstance().GetVoteLevel( vote->GetCommandName() );
return gameLocal.ToGuiTime( gameLocal.time ) > player->GetNextCallVoteTime() && group.CanCallVote( voteLevel );
}
/*
============
sdVoteManagerLocal::NumActiveVotes
============
*/
int sdVoteManagerLocal::NumActiveVotes( voteId_t id, idEntity* player ) const {
assert( gameLocal.isServer );
int count = 0;
sdPlayerVote* next = activeVotes.Next();
for ( sdPlayerVote* vote = next; vote; vote = next ) {
next = vote->GetNextActiveVote();
if ( vote->GetVoteCaller() == player && vote->GetVoteId() == id ) {
count++;
}
}
return count;
}
/*
============
sdVoteManagerLocal::PushVoteItem
============
*/
void sdVoteManagerLocal::PushVoteItem( sdUIList* list, sdCallVote* vote, int voteIndex ) {
bool canUse = CanUseVote( vote, gameLocal.GetLocalPlayer() );
if( !canUse ) {
return;
}
idWStr temp;
vote->GetText( temp );
int index = sdUIList::InsertItem( list, temp.c_str(), -1, 0 );
list->SetItemDataInt( voteIndex, index, 0 );
}
/*
============
sdVoteManagerLocal::CallVoteForIndex
============
*/
sdCallVote* sdVoteManagerLocal::CallVoteForIndex( int index ) {
if ( index < 0 ) {
return NULL;
}
if ( index < globalCallVotes.Num() ) {
return globalCallVotes[ index ];
}
index -= globalCallVotes.Num();
if ( gameLocal.rules != NULL ) {
const idList< sdCallVote* >& ruleVotes = gameLocal.rules->GetCallVotes();
if ( index < ruleVotes.Num() ) {
return ruleVotes[ index ];
}
index -= ruleVotes.Num();
}
return NULL;
}
/*
==================
sdVoteManagerLocal::Callvote_f
==================
*/
void sdVoteManagerLocal::Callvote_f( const idCmdArgs &args ) {
if ( gameLocal.isClient ) {
sdReliableClientMessage msg( GAME_RELIABLE_CMESSAGE_CALLVOTE );
msg.WriteLong( args.Argc() - 1 );
for ( int i = 1; i < args.Argc(); i++ ) {
msg.WriteString( args.Argv( i ) );
}
msg.Send();
return;
}
sdVoteManager::GetInstance().PerformCommand( args, gameLocal.GetLocalPlayer() );
}
/*
==================
sdVoteManagerLocal::ListVotes
==================
*/
void sdVoteManagerLocal::ListVotes( void ) {
int index = 0;
while ( true ) {
sdCallVote* vote = CallVoteForIndex( index++ );
if ( vote == NULL ) {
break;
}
const char* cmdName = vote->GetCommandName();
int voteLevel = sdUserGroupManager::GetInstance().GetVoteLevel( cmdName );
gameLocal.Printf( "\"%s\"\t\"%d\"\n", cmdName, voteLevel );
}
}