mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2024-12-02 17:02:17 +00:00
9eeea7adf3
mostly -Wreorder, use const char* instead of char* for "static strings", fix inappropriate usage of NULL (e.g. instead of '\0' or (int)0)
638 lines
18 KiB
C++
638 lines
18 KiB
C++
/*
|
|
===========================================================================
|
|
|
|
Doom 3 BFG Edition GPL Source Code
|
|
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
|
|
|
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
|
|
|
Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
|
|
|
|
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
|
|
|
|
===========================================================================
|
|
*/
|
|
#include "../idlib/precompiled.h"
|
|
#pragma hdrstop
|
|
|
|
#include "Game_local.h"
|
|
#include "../../doomclassic/doom/doomdef.h"
|
|
|
|
idCVar achievements_Verbose( "achievements_Verbose", "1", CVAR_BOOL, "debug spam" );
|
|
idCVar g_demoMode( "g_demoMode", "0", CVAR_INTEGER, "this is a demo" );
|
|
|
|
bool idAchievementManager::cheatingDialogShown = false;
|
|
|
|
const struct achievementInfo_t
|
|
{
|
|
int required;
|
|
bool lifetime; // true means the current count is stored on the player profile. Doesn't matter for single count achievements.
|
|
} achievementInfo [ACHIEVEMENTS_NUM] =
|
|
{
|
|
{ 50, true }, // ACHIEVEMENT_EARN_ALL_50_TROPHIES
|
|
{ 1, true }, // ACHIEVEMENT_COMPLETED_DIFFICULTY_0
|
|
{ 1, true }, // ACHIEVEMENT_COMPLETED_DIFFICULTY_1
|
|
{ 1, true }, // ACHIEVEMENT_COMPLETED_DIFFICULTY_2
|
|
{ 1, true }, // ACHIEVEMENT_COMPLETED_DIFFICULTY_3
|
|
{ 64, false }, // ACHIEVEMENT_PDAS_BASE
|
|
{ 14, false }, // ACHIEVEMENT_WATCH_ALL_VIDEOS
|
|
{ 1, false }, // ACHIEVEMENT_KILL_MONSTER_WITH_1_HEALTH_LEFT
|
|
{ 35, false }, // ACHIEVEMENT_OPEN_ALL_LOCKERS
|
|
{ 20, true }, // ACHIEVEMENT_KILL_20_ENEMY_FISTS_HANDS
|
|
{ 1, true }, // ACHIEVEMENT_KILL_SCI_NEXT_TO_RCR
|
|
{ 1, true }, // ACHIEVEMENT_KILL_TWO_IMPS_ONE_SHOTGUN
|
|
{ 1, true }, // ACHIEVEMENT_SCORE_25000_TURKEY_PUNCHER
|
|
{ 50, true }, // ACHIEVEMENT_DESTROY_BARRELS
|
|
{ 1, true }, // ACHIEVEMENT_GET_BFG_FROM_SECURITY_OFFICE
|
|
{ 1, true }, // ACHIEVEMENT_COMPLETE_LEVEL_WITHOUT_TAKING_DMG
|
|
{ 1, true }, // ACHIEVEMENT_FIND_RAGE_LOGO
|
|
{ 1, true }, // ACHIEVEMENT_SPEED_RUN
|
|
{ 1, true }, // ACHIEVEMENT_DEFEAT_VAGARY_BOSS
|
|
{ 1, true }, // ACHIEVEMENT_DEFEAT_GUARDIAN_BOSS
|
|
{ 1, true }, // ACHIEVEMENT_DEFEAT_SABAOTH_BOSS
|
|
{ 1, true }, // ACHIEVEMENT_DEFEAT_CYBERDEMON_BOSS
|
|
{ 1, true }, // ACHIEVEMENT_SENTRY_BOT_ALIVE_TO_DEST
|
|
{ 20, true }, // ACHIEVEMENT_KILL_20_ENEMY_WITH_CHAINSAW
|
|
{ 1, true }, // ACHIEVEMENT_ID_LOGO_SECRET_ROOM
|
|
{ 1, true }, // ACHIEVEMENT_BLOODY_HANDWORK_OF_BETRUGER
|
|
{ 1, true }, // ACHIEVEMENT_TWO_DEMONS_FIGHT_EACH_OTHER
|
|
{ 20, true }, // ACHIEVEMENT_USE_SOUL_CUBE_TO_DEFEAT_20_ENEMY
|
|
{ 1, true }, // ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_0
|
|
{ 1, true }, // ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_1
|
|
{ 1, true }, // ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_2
|
|
{ 1, true }, // ACHIEVEMENT_ROE_COMPLETED_DIFFICULTY_3
|
|
{ 22, false }, // ACHIEVEMENT_PDAS_ROE
|
|
{ 1, true }, // ACHIEVEMENT_KILL_5_ENEMY_HELL_TIME
|
|
{ 1, true }, // ACHIEVEMENT_DEFEAT_HELLTIME_HUNTER
|
|
{ 1, true }, // ACHIEVEMENT_DEFEAT_BERSERK_HUNTER
|
|
{ 1, true }, // ACHIEVEMENT_DEFEAT_INVULNERABILITY_HUNTER
|
|
{ 1, true }, // ACHIEVEMENT_DEFEAT_MALEDICT_BOSS
|
|
{ 20, true }, // ACHIEVEMENT_GRABBER_KILL_20_ENEMY
|
|
{ 20, true }, // ACHIEVEMENT_ARTIFACT_WITH_BERSERK_PUNCH_20
|
|
{ 1, true }, // ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_0
|
|
{ 1, true }, // ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_1
|
|
{ 1, true }, // ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_2
|
|
{ 1, true }, // ACHIEVEMENT_LE_COMPLETED_DIFFICULTY_3
|
|
{ 10, false }, // ACHIEVEMENT_PDAS_LE
|
|
{ 1, true }, // ACHIEVEMENT_MP_KILL_PLAYER_VIA_TELEPORT
|
|
{ 1, true }, // ACHIEVEMENT_MP_CATCH_ENEMY_IN_ROFC
|
|
{ 5, true }, // ACHIEVEMENT_MP_KILL_5_PLAYERS_USING_INVIS
|
|
{ 1, true }, // ACHIEVEMENT_MP_COMPLETE_MATCH_WITHOUT_DYING
|
|
{ 1, true }, // ACHIEVEMENT_MP_USE_BERSERK_TO_KILL_PLAYER
|
|
{ 1, true }, // ACHIEVEMENT_MP_KILL_2_GUYS_IN_ROOM_WITH_BFG
|
|
};
|
|
|
|
/*
|
|
================================================================================================
|
|
|
|
idAchievementManager
|
|
|
|
================================================================================================
|
|
*/
|
|
|
|
/*
|
|
========================
|
|
idAchievementManager::idAchievementManager
|
|
========================
|
|
*/
|
|
idAchievementManager::idAchievementManager() :
|
|
lastPlayerKilledTime( 0 ),
|
|
lastImpKilledTime( 0 ),
|
|
playerTookDamage( false )
|
|
{
|
|
counts.Zero();
|
|
ResetHellTimeKills();
|
|
}
|
|
|
|
/*
|
|
========================
|
|
idAchievementManager::Init
|
|
========================
|
|
*/
|
|
void idAchievementManager::Init( idPlayer* player )
|
|
{
|
|
owner = player;
|
|
SyncAchievments();
|
|
}
|
|
|
|
/*
|
|
========================
|
|
idAchievementManager::SyncAchievments
|
|
========================
|
|
*/
|
|
void idAchievementManager::SyncAchievments()
|
|
{
|
|
idLocalUser* user = GetLocalUser();
|
|
if( user == NULL || user->GetProfile() == NULL )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Set achievement counts
|
|
for( int i = 0; i < counts.Num(); i++ )
|
|
{
|
|
if( user->GetProfile()->GetAchievement( i ) )
|
|
{
|
|
counts[i] = achievementInfo[i].required;
|
|
}
|
|
else if( achievementInfo[i].lifetime )
|
|
{
|
|
counts[i] = user->GetStatInt( i );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
========================
|
|
idAchievementManager::GetLocalUser
|
|
========================
|
|
*/
|
|
idLocalUser* idAchievementManager::GetLocalUser()
|
|
{
|
|
if( !verify( owner != NULL ) )
|
|
{
|
|
return NULL;
|
|
}
|
|
return session->GetGameLobbyBase().GetLocalUserFromLobbyUser( gameLocal.lobbyUserIDs[ owner->GetEntityNumber() ] );
|
|
}
|
|
|
|
/*
|
|
========================
|
|
idAchievementManager::Save
|
|
========================
|
|
*/
|
|
void idAchievementManager::Save( idSaveGame* savefile ) const
|
|
{
|
|
owner.Save( savefile );
|
|
|
|
for( int i = 0; i < ACHIEVEMENTS_NUM; i++ )
|
|
{
|
|
savefile->WriteInt( counts[i] );
|
|
}
|
|
|
|
savefile->WriteInt( lastImpKilledTime );
|
|
savefile->WriteInt( lastPlayerKilledTime );
|
|
savefile->WriteBool( playerTookDamage );
|
|
savefile->WriteInt( currentHellTimeKills );
|
|
}
|
|
|
|
/*
|
|
========================
|
|
idAchievementManager::Restore
|
|
========================
|
|
*/
|
|
void idAchievementManager::Restore( idRestoreGame* savefile )
|
|
{
|
|
owner.Restore( savefile );
|
|
|
|
for( int i = 0; i < ACHIEVEMENTS_NUM; i++ )
|
|
{
|
|
savefile->ReadInt( counts[i] );
|
|
}
|
|
|
|
savefile->ReadInt( lastImpKilledTime );
|
|
savefile->ReadInt( lastPlayerKilledTime );
|
|
savefile->ReadBool( playerTookDamage );
|
|
savefile->ReadInt( currentHellTimeKills );
|
|
|
|
SyncAchievments();
|
|
}
|
|
|
|
/*
|
|
========================
|
|
idAchievementManager::EventCompletesAchievement
|
|
========================
|
|
*/
|
|
void idAchievementManager::EventCompletesAchievement( const achievement_t eventId )
|
|
{
|
|
if( g_demoMode.GetBool() )
|
|
{
|
|
return;
|
|
}
|
|
|
|
idLocalUser* localUser = GetLocalUser();
|
|
if( localUser == NULL || localUser->GetProfile() == NULL )
|
|
{
|
|
|
|
// Send a Reliable Message to the User that needs to unlock this.
|
|
if( owner != NULL )
|
|
{
|
|
int playerId = owner->entityNumber;
|
|
const int bufferSize = sizeof( playerId ) + sizeof( eventId );
|
|
byte buffer[ bufferSize ];
|
|
idBitMsg msg;
|
|
msg.InitWrite( buffer, bufferSize );
|
|
|
|
msg.WriteByte( playerId );
|
|
msg.WriteByte( eventId );
|
|
|
|
msg.WriteByteAlign();
|
|
idLib::Printf( "Host Sending Achievement\n" );
|
|
session->GetActingGameStateLobbyBase().SendReliableToLobbyUser( gameLocal.lobbyUserIDs[ owner->entityNumber ], GAME_RELIABLE_MESSAGE_ACHIEVEMENT_UNLOCK, msg );
|
|
}
|
|
|
|
return; // Remote user or build game
|
|
}
|
|
|
|
// Check to see if we've already given the achievement.
|
|
// If so, don't do again because we don't want to autosave every time a trigger is hit
|
|
if( localUser->GetProfile()->GetAchievement( eventId ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
#ifdef ID_RETAIL
|
|
if( common->GetConsoleUsed() )
|
|
{
|
|
if( !cheatingDialogShown )
|
|
{
|
|
common->Dialog().AddDialog( GDM_ACHIEVEMENTS_DISABLED_DUE_TO_CHEATING, DIALOG_ACCEPT, NULL, NULL, true );
|
|
cheatingDialogShown = true;
|
|
}
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
counts[eventId]++;
|
|
|
|
if( counts[eventId] >= achievementInfo[eventId].required )
|
|
{
|
|
session->GetAchievementSystem().AchievementUnlock( localUser, eventId );
|
|
}
|
|
else
|
|
{
|
|
if( achievementInfo[eventId].lifetime )
|
|
{
|
|
localUser->SetStatInt( eventId, counts[eventId] );
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
========================
|
|
idAchievementManager::IncrementHellTimeKills
|
|
========================
|
|
*/
|
|
void idAchievementManager::IncrementHellTimeKills()
|
|
{
|
|
currentHellTimeKills++;
|
|
if( currentHellTimeKills >= 5 )
|
|
{
|
|
EventCompletesAchievement( ACHIEVEMENT_KILL_5_ENEMY_HELL_TIME );
|
|
}
|
|
}
|
|
|
|
/*
|
|
========================
|
|
idAchievementManager::SavePersistentData
|
|
========================
|
|
*/
|
|
void idAchievementManager::SavePersistentData( idDict& playerInfo )
|
|
{
|
|
for( int i = 0; i < ACHIEVEMENTS_NUM; ++i )
|
|
{
|
|
playerInfo.SetInt( va( "ach_%d", i ), counts[i] );
|
|
}
|
|
}
|
|
|
|
/*
|
|
========================
|
|
idAchievementManager::RestorePersistentData
|
|
========================
|
|
*/
|
|
void idAchievementManager::RestorePersistentData( const idDict& spawnArgs )
|
|
{
|
|
for( int i = 0; i < ACHIEVEMENTS_NUM; ++i )
|
|
{
|
|
counts[i] = spawnArgs.GetInt( va( "ach_%d", i ), "0" );
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
========================
|
|
idAchievementManager::LocalUser_CompleteAchievement
|
|
========================
|
|
*/
|
|
void idAchievementManager::LocalUser_CompleteAchievement( achievement_t id )
|
|
{
|
|
idLocalUser* localUser = session->GetSignInManager().GetMasterLocalUser();
|
|
|
|
// Check to see if we've already given the achievement.
|
|
// If so, don't do again because we don't want to autosave every time a trigger is hit
|
|
if( localUser == NULL || localUser->GetProfile()->GetAchievement( id ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
#ifdef ID_RETAIL
|
|
if( common->GetConsoleUsed() )
|
|
{
|
|
if( !cheatingDialogShown )
|
|
{
|
|
common->Dialog().AddDialog( GDM_ACHIEVEMENTS_DISABLED_DUE_TO_CHEATING, DIALOG_ACCEPT, NULL, NULL, true );
|
|
cheatingDialogShown = true;
|
|
}
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
session->GetAchievementSystem().AchievementUnlock( localUser, id );
|
|
}
|
|
|
|
/*
|
|
========================
|
|
idAchievementManager::CheckDoomClassicsAchievements
|
|
|
|
Processed when the player finishes a level.
|
|
========================
|
|
*/
|
|
// RB begin
|
|
#if defined(USE_DOOMCLASSIC)
|
|
void idAchievementManager::CheckDoomClassicsAchievements( int killcount, int itemcount, int secretcount, int skill, int mission, int map, int episode, int totalkills, int totalitems, int totalsecret )
|
|
{
|
|
|
|
const skill_t difficulty = ( skill_t )skill;
|
|
const currentGame_t currentGame = common->GetCurrentGame();
|
|
const GameMission_t expansion = ( GameMission_t )mission;
|
|
|
|
|
|
idLocalUser* localUser = session->GetSignInManager().GetMasterLocalUser();
|
|
if( localUser != NULL && localUser->GetProfile() != NULL )
|
|
{
|
|
|
|
// GENERAL ACHIEVEMENT UNLOCKING.
|
|
if( currentGame == DOOM_CLASSIC )
|
|
{
|
|
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_NEOPHYTE_COMPLETE_ANY_LEVEL );
|
|
}
|
|
else if( currentGame == DOOM2_CLASSIC )
|
|
{
|
|
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_JUST_GETTING_STARTED_COMPLETE_ANY_LEVEL );
|
|
}
|
|
|
|
// Complete Any Level on Nightmare.
|
|
if( difficulty == sk_nightmare && currentGame == DOOM_CLASSIC )
|
|
{
|
|
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_NIGHTMARE_COMPLETE_ANY_LEVEL_NIGHTMARE );
|
|
}
|
|
|
|
const bool gotAllKills = killcount >= totalkills;
|
|
const bool gotAllItems = itemcount >= totalitems;
|
|
const bool gotAllSecrets = secretcount >= totalsecret;
|
|
|
|
if( gotAllItems && gotAllKills && gotAllSecrets )
|
|
{
|
|
if( currentGame == DOOM_CLASSIC )
|
|
{
|
|
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_BURNING_OUT_OF_CONTROL_COMPLETE_KILLS_ITEMS_SECRETS );
|
|
}
|
|
else if( currentGame == DOOM2_CLASSIC )
|
|
{
|
|
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_BURNING_OUT_OF_CONTROL_COMPLETE_KILLS_ITEMS_SECRETS );
|
|
}
|
|
}
|
|
|
|
// DOOM EXPANSION ACHIEVEMENTS
|
|
if( expansion == doom )
|
|
{
|
|
|
|
if( map == 8 )
|
|
{
|
|
|
|
// Medium or higher skill level.
|
|
if( difficulty >= sk_medium )
|
|
{
|
|
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM + ( episode - 1 ), 1 );
|
|
}
|
|
|
|
// Hard or higher skill level.
|
|
if( difficulty >= sk_hard )
|
|
{
|
|
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_HARD + ( episode - 1 ), 1 );
|
|
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM + ( episode - 1 ), 1 );
|
|
}
|
|
|
|
if( difficulty == sk_nightmare )
|
|
{
|
|
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_HARD + ( episode - 1 ), 1 );
|
|
localUser->SetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM + ( episode - 1 ), 1 );
|
|
}
|
|
|
|
// Save the Settings.
|
|
localUser->SaveProfileSettings();
|
|
}
|
|
|
|
// Check to see if we've completed all episodes.
|
|
const int episode1completed = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_MEDIUM );
|
|
const int episode2completed = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_2_MEDIUM );
|
|
const int episode3completed = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_3_MEDIUM );
|
|
const int episode4completed = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_4_MEDIUM );
|
|
|
|
const int episode1completed_hard = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_1_HARD );
|
|
const int episode2completed_hard = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_2_HARD );
|
|
const int episode3completed_hard = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_3_HARD );
|
|
const int episode4completed_hard = localUser->GetStatInt( STAT_DOOM_COMPLETED_EPISODE_4_HARD );
|
|
|
|
if( currentGame == DOOM_CLASSIC )
|
|
{
|
|
if( episode1completed )
|
|
{
|
|
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_EPISODE1_COMPLETE_MEDIUM );
|
|
}
|
|
|
|
if( episode2completed )
|
|
{
|
|
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_EPISODE2_COMPLETE_MEDIUM );
|
|
}
|
|
|
|
if( episode3completed )
|
|
{
|
|
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_EPISODE3_COMPLETE_MEDIUM );
|
|
}
|
|
|
|
if( episode4completed )
|
|
{
|
|
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_EPISODE4_COMPLETE_MEDIUM );
|
|
}
|
|
|
|
if( episode1completed_hard && episode2completed_hard && episode3completed_hard && episode4completed_hard )
|
|
{
|
|
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM1_RAMPAGE_COMPLETE_ALL_HARD );
|
|
}
|
|
}
|
|
}
|
|
else if( expansion == doom2 )
|
|
{
|
|
|
|
if( map == 30 )
|
|
{
|
|
|
|
if( currentGame == DOOM2_CLASSIC )
|
|
{
|
|
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_FROM_EARTH_TO_HELL_COMPLETE_HELL_ON_EARTH );
|
|
|
|
if( difficulty >= sk_hard )
|
|
{
|
|
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_SUPERIOR_FIREPOWER_COMPLETE_ALL_HARD );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if( expansion == pack_nerve )
|
|
{
|
|
if( map == 8 )
|
|
{
|
|
|
|
if( currentGame == DOOM2_CLASSIC )
|
|
{
|
|
LocalUser_CompleteAchievement( ACHIEVEMENT_DOOM2_AND_BACK_AGAIN_COMPLETE_NO_REST );
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
#endif // #if defined(USE_DOOMCLASSIC)
|
|
// RB end
|
|
|
|
/*
|
|
=================
|
|
AchievementsReset
|
|
=================
|
|
*/
|
|
CONSOLE_COMMAND( AchievementsReset, "Lock an achievement", NULL )
|
|
{
|
|
idLocalUser* user = session->GetSignInManager().GetMasterLocalUser();
|
|
if( user == NULL )
|
|
{
|
|
idLib::Printf( "Must be signed in\n" );
|
|
return;
|
|
}
|
|
if( args.Argc() == 1 )
|
|
{
|
|
for( int i = 0; i < ACHIEVEMENTS_NUM; i++ )
|
|
{
|
|
user->SetStatInt( i, 0 );
|
|
session->GetAchievementSystem().AchievementLock( user, i );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int i = atoi( args.Argv( 1 ) );
|
|
user->SetStatInt( i, 0 );
|
|
session->GetAchievementSystem().AchievementLock( user, i );
|
|
}
|
|
user->SaveProfileSettings();
|
|
}
|
|
|
|
/*
|
|
=================
|
|
AchievementsUnlock
|
|
=================
|
|
*/
|
|
CONSOLE_COMMAND( AchievementsUnlock, "Unlock an achievement", NULL )
|
|
{
|
|
idLocalUser* user = session->GetSignInManager().GetMasterLocalUser();
|
|
if( user == NULL )
|
|
{
|
|
idLib::Printf( "Must be signed in\n" );
|
|
return;
|
|
}
|
|
if( args.Argc() == 1 )
|
|
{
|
|
for( int i = 0; i < ACHIEVEMENTS_NUM; i++ )
|
|
{
|
|
user->SetStatInt( i, achievementInfo[i].required );
|
|
session->GetAchievementSystem().AchievementUnlock( user, i );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int i = atoi( args.Argv( 1 ) );
|
|
user->SetStatInt( i, achievementInfo[i].required );
|
|
session->GetAchievementSystem().AchievementUnlock( user, i );
|
|
}
|
|
user->SaveProfileSettings();
|
|
}
|
|
|
|
/*
|
|
=================
|
|
AchievementsList
|
|
=================
|
|
*/
|
|
CONSOLE_COMMAND( AchievementsList, "Lists achievements and status", NULL )
|
|
{
|
|
idPlayer* player = gameLocal.GetLocalPlayer();
|
|
idLocalUser* user = ( player == NULL ) ? session->GetSignInManager().GetMasterLocalUser() : session->GetGameLobbyBase().GetLocalUserFromLobbyUser( gameLocal.lobbyUserIDs[ player->GetEntityNumber() ] );
|
|
if( user == NULL )
|
|
{
|
|
idLib::Printf( "Must be signed in\n" );
|
|
return;
|
|
}
|
|
idPlayerProfile* profile = user->GetProfile();
|
|
|
|
idArray<bool, 128> achievementState;
|
|
bool achievementStateValid = session->GetAchievementSystem().GetAchievementState( user, achievementState );
|
|
|
|
for( int i = 0; i < ACHIEVEMENTS_NUM; i++ )
|
|
{
|
|
const char* pInfo = "";
|
|
if( profile == NULL )
|
|
{
|
|
pInfo = S_COLOR_RED "unknown" S_COLOR_DEFAULT;
|
|
}
|
|
else if( !profile->GetAchievement( i ) )
|
|
{
|
|
pInfo = S_COLOR_YELLOW "locked" S_COLOR_DEFAULT;
|
|
}
|
|
else
|
|
{
|
|
pInfo = S_COLOR_GREEN "unlocked" S_COLOR_DEFAULT;
|
|
}
|
|
const char* sInfo = "";
|
|
if( !achievementStateValid )
|
|
{
|
|
sInfo = S_COLOR_RED "unknown" S_COLOR_DEFAULT;
|
|
}
|
|
else if( !achievementState[i] )
|
|
{
|
|
sInfo = S_COLOR_YELLOW "locked" S_COLOR_DEFAULT;
|
|
}
|
|
else
|
|
{
|
|
sInfo = S_COLOR_GREEN "unlocked" S_COLOR_DEFAULT;
|
|
}
|
|
int count = 0;
|
|
if( achievementInfo[i].lifetime )
|
|
{
|
|
count = user->GetStatInt( i );
|
|
}
|
|
else if( player != NULL )
|
|
{
|
|
count = player->GetAchievementManager().GetCount( ( achievement_t ) i );
|
|
}
|
|
else
|
|
{
|
|
count = 0;
|
|
}
|
|
|
|
achievementDescription_t data;
|
|
bool descriptionValid = session->GetAchievementSystem().GetAchievementDescription( user, i, data );
|
|
|
|
idLib::Printf( "%02d: %2d/%2d | %12.12s | %12.12s | %s%s\n", i, count, achievementInfo[i].required, pInfo, sInfo, descriptionValid ? data.hidden ? "(hidden) " : "" : "(unknown) ", descriptionValid ? data.name : "" );
|
|
}
|
|
}
|