2010-07-22 01:46:14 -05:00
# include "cbase.h"
# ifdef CLIENT_DLL
# define CASW_Equip_Req C_ASW_Equip_Req
# include "c_asw_player.h"
# include "c_asw_marine.h"
# include "c_asw_game_resource.h"
# include "c_asw_marine_resource.h"
# include "asw_input.h"
# include "c_asw_weapon.h"
# include "c_asw_game_resource.h"
# include "clientmode_asw.h"
# include "c_asw_objective.h"
# include "c_asw_debrief_stats.h"
# include "asw_hud_objective.h"
# include "asw_equip_req.h"
# include "achievementmgr.h"
# include "asw_achievements.h"
# include "asw_medal_store.h"
# include "asw_equipment_list.h"
# include "asw_marine_profile.h"
# include "clientmode_asw.h"
# ifndef _X360
# include "steam/isteamuserstats.h"
# include "steam/isteamfriends.h"
# include "steam/isteamutils.h"
# include "steam/steam_api.h"
# include "c_asw_steamstats.h"
# endif
# define CASW_Marine C_ASW_Marine
# define CASW_Marine_Resource C_ASW_Marine_Resource
# define CASW_Weapon C_ASW_Weapon
# define CASW_Debrief_Stats C_ASW_Debrief_Stats
# define CASW_Objective C_ASW_Objective
# else
# include "player.h"
# include "asw_player.h"
# include "asw_marine.h"
# include "asw_marine_resource.h"
# include "asw_weapon.h"
# include "asw_objective.h"
# include "asw_debrief_stats.h"
# include "asw_achievements.h"
# ifndef _X360
# include "steam/isteamgameserverstats.h"
# include "gameinterface.h"
# endif
# endif
# include "asw_gamerules.h"
# include "asw_shareddefs.h"
# include "asw_weapon_parse.h"
# include "asw_medals_shared.h"
// memdbgon must be the last include file in a .cpp file!!!
# include "tier0/memdbgon.h"
extern ConVar asw_skill ;
ConVar asw_show_xp_details ( " asw_show_xp_details " , " 0 " , FCVAR_REPLICATED , " Output XP rewards to the console " ) ;
// Experience levels. NOTE: Level shown in the UI is one higher than used in code
int g_iLevelExperience [ ASW_NUM_EXPERIENCE_LEVELS ] =
{
1000 , // XP under this = 1evel 1 in UI
2050 ,
3150 ,
4300 ,
5500 , // XP under this = 1evel 5 in UI
6750 ,
8050 ,
9400 ,
10800 ,
12250 , // XP under this = 1evel 10 in UI
13750 ,
15300 ,
16900 ,
18550 ,
20250 , // XP under this = 1evel 15 in UI
22000 ,
23800 ,
25650 ,
27550 ,
29500 , // XP under this = 1evel 20 in UI
31500 ,
33550 ,
35650 ,
37800 ,
40000 , // XP under this = 1evel 25 in UI
42250 , // XP under this = level 26 in UI, XP equal to this = level 27 in the UI
} ;
int g_iXPAward [ ASW_NUM_XP_TYPES ] =
{
1000 , // ASW_XP_MISSION,
100 , // ASW_XP_KILLS,
100 , // ASW_XP_TIME,
100 , // ASW_XP_FRIENDLY_FIRE,
100 , // ASW_XP_DAMAGE_TAKEN,
50 , // ASW_XP_HEALING,
50 , // ASW_XP_HACKING
} ;
2010-10-11 17:51:21 -05:00
// scalar applied to XP required to level, based on your current promotion
float g_flPromotionXPScale [ ASW_PROMOTION_CAP + 1 ] =
{
1.0f ,
1.0f ,
1.0f ,
1.0f ,
2.0f ,
4.0f ,
6.0f ,
} ;
2010-07-22 01:46:14 -05:00
# define ASW_MISSION_XP_AWARD_ON_FAILURE 750 // XP award divided up between objectives
// NOTE: If you change this, update the labels in CExperienceReport::OnThink too
2010-10-11 17:51:21 -05:00
float g_flXPDifficultyScale [ 5 ] =
2010-07-22 01:46:14 -05:00
{
0.5f , // easy
1.0f , // normal
1.2f , // hard
1.4f , // insane
2010-10-11 17:51:21 -05:00
1.5f , // imba
2010-07-22 01:46:14 -05:00
} ;
// Weapon unlocks
struct ASW_Weapon_Unlock
{
ASW_Weapon_Unlock ( const char * szWeaponClass , int iLevel )
{
m_pszWeaponClass = szWeaponClass ;
m_iLevel = iLevel ;
}
const char * m_pszWeaponClass ;
int m_iLevel ; // player level needed to unlock
} ;
// Keep Equipment.res in the same order as this
ASW_Weapon_Unlock g_WeaponUnlocks [ ] =
{
ASW_Weapon_Unlock ( " asw_weapon_normal_armor " , 1 ) , //
ASW_Weapon_Unlock ( " asw_weapon_shotgun " , 2 ) ,
ASW_Weapon_Unlock ( " asw_weapon_buff_grenade " , 3 ) , //
ASW_Weapon_Unlock ( " asw_weapon_tesla_gun " , 4 ) ,
ASW_Weapon_Unlock ( " asw_weapon_hornet_barrage " , 5 ) , //
ASW_Weapon_Unlock ( " asw_weapon_railgun " , 6 ) ,
ASW_Weapon_Unlock ( " asw_weapon_freeze_grenades " , 7 ) , //
ASW_Weapon_Unlock ( " asw_weapon_heal_gun " , 8 ) ,
ASW_Weapon_Unlock ( " asw_weapon_stim " , 9 ) , //
ASW_Weapon_Unlock ( " asw_weapon_pdw " , 10 ) ,
ASW_Weapon_Unlock ( " asw_weapon_tesla_trap " , 11 ) , //
ASW_Weapon_Unlock ( " asw_weapon_flamer " , 12 ) ,
ASW_Weapon_Unlock ( " asw_weapon_electrified_armor " , 13 ) , //
ASW_Weapon_Unlock ( " asw_weapon_sentry_freeze " , 14 ) ,
ASW_Weapon_Unlock ( " asw_weapon_mines " , 15 ) , //
ASW_Weapon_Unlock ( " asw_weapon_minigun " , 16 ) ,
ASW_Weapon_Unlock ( " asw_weapon_flashlight " , 17 ) , //
ASW_Weapon_Unlock ( " asw_weapon_sniper_rifle " , 18 ) ,
ASW_Weapon_Unlock ( " asw_weapon_fist " , 19 ) , //
ASW_Weapon_Unlock ( " asw_weapon_sentry_flamer " , 20 ) ,
ASW_Weapon_Unlock ( " asw_weapon_grenades " , 21 ) , //
ASW_Weapon_Unlock ( " asw_weapon_chainsaw " , 22 ) ,
ASW_Weapon_Unlock ( " asw_weapon_night_vision " , 23 ) , //
ASW_Weapon_Unlock ( " asw_weapon_sentry_cannon " , 24 ) ,
ASW_Weapon_Unlock ( " asw_weapon_smart_bomb " , 25 ) , //
2010-10-11 17:51:21 -05:00
ASW_Weapon_Unlock ( " asw_weapon_grenade_launcher " , 26 ) , // ASW_NUM_EXPERIENCE_LEVELS
2010-07-22 01:46:14 -05:00
} ;
// given an Experience total, this tells you the player's level
2010-10-11 17:51:21 -05:00
int LevelFromXP ( int iExperience , int iPromotion )
2010-07-22 01:46:14 -05:00
{
2010-10-11 17:51:21 -05:00
iExperience = MIN ( iExperience , ASW_XP_CAP * g_flPromotionXPScale [ iPromotion ] ) ;
2010-07-22 01:46:14 -05:00
for ( int i = 0 ; i < NELEMS ( g_iLevelExperience ) ; i + + )
{
2010-10-11 17:51:21 -05:00
int iRequiredXP = ( int ) ( g_flPromotionXPScale [ iPromotion ] * g_iLevelExperience [ i ] ) ;
if ( iExperience < iRequiredXP )
2010-07-22 01:46:14 -05:00
{
return i ;
}
}
return NELEMS ( g_iLevelExperience ) ;
}
void CASW_Player : : CalculateEarnedXP ( )
{
for ( int i = 0 ; i < ASW_NUM_XP_TYPES ; i + + )
{
m_iEarnedXP [ i ] = 0 ;
m_iStatNumXP [ i ] = 0 ;
}
// no XP if you don't have a marine resource
if ( ! ASWGameResource ( ) | | ! ASWGameResource ( ) - > GetFirstMarineResourceForPlayer ( this ) )
return ;
// no earning XP in singleplayer
if ( gpGlobals - > maxClients < = 1 )
return ;
if ( ASWGameRules ( ) & & ASWGameRules ( ) - > m_bCheated . Get ( ) )
return ;
# ifdef CLIENT_DLL
if ( engine - > IsPlayingDemo ( ) )
return ;
2011-04-15 17:50:57 -05:00
//if ( GetClientModeASW() && !GetClientModeASW()->IsOfficialMap() )
//return;
2010-07-22 01:46:14 -05:00
# endif
int iNumObjectives = 0 ;
float flNumObjectivesComplete = 0 ;
float flPartialScale = 1.0f ; // this is used to scale XP rewards that should be small if you've only completed part of the mission
if ( ASWGameRules ( ) - > GetMissionSuccess ( ) )
{
// XP for completing the mission
m_iEarnedXP [ ASW_XP_MISSION ] = g_iXPAward [ ASW_XP_MISSION ] ;
m_iStatNumXP [ ASW_XP_MISSION ] = 100 ;
}
else
{
// if failed the mission, award XP per completed objective
for ( int i = 0 ; i < ASW_MAX_OBJECTIVES ; i + + )
{
CASW_Objective * pObjective = ASWGameResource ( ) - > GetObjective ( i ) ;
if ( pObjective )
{
iNumObjectives + + ;
flNumObjectivesComplete + = pObjective - > GetObjectiveProgress ( ) ;
}
}
if ( iNumObjectives > 0 )
{
flPartialScale = ( flNumObjectivesComplete / ( float ) iNumObjectives ) ;
m_iEarnedXP [ ASW_XP_MISSION ] + = g_iXPAward [ ASW_XP_MISSION ] * flPartialScale ;
m_iStatNumXP [ ASW_XP_MISSION ] = flPartialScale * 100.0f ;
}
else
{
flPartialScale = 0.0f ;
}
}
// query debrief stats to see how much XP we should award based on performance
CASW_Debrief_Stats * pDebrief = GetDebriefStats ( ) ;
if ( pDebrief )
{
CASW_Marine_Resource * pMR = ASWGameResource ( ) - > GetFirstMarineResourceForPlayer ( this ) ;
if ( pMR )
{
int iMarineIndex = ASWGameResource ( ) - > GetMarineResourceIndex ( pMR ) ;
if ( iMarineIndex ! = - 1 )
{
// XP per kill, capped
m_iEarnedXP [ ASW_XP_KILLS ] = clamp ( pDebrief - > GetKills ( iMarineIndex ) , 0 , g_iXPAward [ ASW_XP_KILLS ] ) ;
m_iStatNumXP [ ASW_XP_KILLS ] = pDebrief - > GetKills ( iMarineIndex ) ;
if ( ASWGameRules ( ) - > GetMissionSuccess ( ) )
{
// FF
m_iEarnedXP [ ASW_XP_FRIENDLY_FIRE ] = clamp ( g_iXPAward [ ASW_XP_FRIENDLY_FIRE ] - pDebrief - > GetFriendlyFire ( iMarineIndex ) , 0 , g_iXPAward [ ASW_XP_FRIENDLY_FIRE ] ) ;
m_iStatNumXP [ ASW_XP_FRIENDLY_FIRE ] = pDebrief - > GetFriendlyFire ( iMarineIndex ) ;
}
if ( ASWGameRules ( ) - > GetMissionSuccess ( ) )
{
// damage taken
m_iEarnedXP [ ASW_XP_DAMAGE_TAKEN ] = clamp ( g_iXPAward [ ASW_XP_DAMAGE_TAKEN ] - pDebrief - > GetDamageTaken ( iMarineIndex ) , 0 , g_iXPAward [ ASW_XP_DAMAGE_TAKEN ] ) ;
m_iStatNumXP [ ASW_XP_DAMAGE_TAKEN ] = pDebrief - > GetDamageTaken ( iMarineIndex ) ;
}
// healing
m_iEarnedXP [ ASW_XP_HEALING ] = clamp ( pDebrief - > GetHealthHealed ( iMarineIndex ) / 10 , 0 , g_iXPAward [ ASW_XP_HEALING ] ) ;
m_iStatNumXP [ ASW_XP_HEALING ] = pDebrief - > GetHealthHealed ( iMarineIndex ) ;
// hacking
if ( pDebrief - > GetFastHacks ( iMarineIndex ) > = 2 )
{
m_iEarnedXP [ ASW_XP_HACKING ] = g_iXPAward [ ASW_XP_HACKING ] ;
}
else if ( pDebrief - > GetFastHacks ( iMarineIndex ) > = 1 )
{
m_iEarnedXP [ ASW_XP_HACKING ] = g_iXPAward [ ASW_XP_HACKING ] / 2 ;
}
else
{
m_iEarnedXP [ ASW_XP_HACKING ] = 0 ;
}
m_iStatNumXP [ ASW_XP_HACKING ] = pDebrief - > GetFastHacks ( iMarineIndex ) ;
}
if ( ASWGameRules ( ) - > GetMissionSuccess ( ) )
{
// time
int speedrun_time = pDebrief - > GetSpeedrunTime ( ) ;
int nTimeTaken = pDebrief - > GetTimeTaken ( ) ;
// award full XP if you get less than the speedrun_time
const float flMaxTime = 5.0f * 60.0f ; // max of 5 minutes over
if ( nTimeTaken < = speedrun_time )
{
m_iEarnedXP [ ASW_XP_TIME ] = g_iXPAward [ ASW_XP_TIME ] ;
m_iStatNumXP [ ASW_XP_TIME ] = nTimeTaken ;
}
else
{
float flReduction = 1.0f - clamp ( static_cast < float > ( nTimeTaken - speedrun_time ) / flMaxTime , 0.0f , 1.0f ) ;
m_iEarnedXP [ ASW_XP_TIME ] = g_iXPAward [ ASW_XP_TIME ] * flReduction ;
m_iStatNumXP [ ASW_XP_TIME ] = nTimeTaken ;
}
}
// medals XP
# ifdef GAME_DLL
const char * szMedalString = pMR - > m_MedalsAwarded . Get ( ) ;
# else
const char * szMedalString = pMR - > m_MedalsAwarded ;
# endif
const char * p = szMedalString ;
char token [ 128 ] ;
p = nexttoken ( token , p , ' ' ) ;
while ( Q_strlen ( token ) > 0 )
{
int iMedalIndex = atoi ( token ) ;
m_iEarnedXP [ ASW_XP_MEDALS ] + = GetXPForMedal ( iMedalIndex ) ;
if ( p )
p = nexttoken ( token , p , ' ' ) ;
else
token [ 0 ] = ' \0 ' ;
}
// achievement XP
# ifdef GAME_DLL
CUtlVector < int > * pAchievementsEarned = & pMR - > m_aAchievementsEarned ;
# else
CUtlVector < int > * pAchievementsEarned = & m_aNonLocalPlayerAchievementsEarned ;
if ( IsLocalPlayer ( ) )
{
pAchievementsEarned = & GetClientModeASW ( ) - > m_aAchievementsEarned ;
}
# endif
for ( int i = 0 ; i < pAchievementsEarned - > Count ( ) ; i + + )
{
m_iEarnedXP [ ASW_XP_MEDALS ] + = GetXPForMedal ( - ( * pAchievementsEarned ) [ i ] ) ;
}
}
}
for ( int i = 0 ; i < ASW_XP_TOTAL ; i + + )
{
m_iEarnedXP [ ASW_XP_TOTAL ] + = m_iEarnedXP [ i ] ;
}
// apply difficulty bonus
if ( ASWGameRules ( ) )
{
m_iEarnedXP [ ASW_XP_TOTAL ] * = g_flXPDifficultyScale [ ASWGameRules ( ) - > GetSkillLevel ( ) - 1 ] ;
}
if ( asw_show_xp_details . GetBool ( ) )
{
Msg ( " [%s] Awarding XP to player %s: \n " , IsServerDll ( ) ? " Server " : " Client " , GetPlayerName ( ) ) ;
Msg ( " EarnedXP[ ASW_XP_MISSION ] = %d \n " , m_iEarnedXP [ ASW_XP_MISSION ] ) ;
Msg ( " EarnedXP[ ASW_XP_KILLS ] = %d \n " , m_iEarnedXP [ ASW_XP_KILLS ] ) ;
Msg ( " EarnedXP[ ASW_XP_TIME ] = %d \n " , m_iEarnedXP [ ASW_XP_TIME ] ) ;
Msg ( " EarnedXP[ ASW_XP_FRIENDLY_FIRE ] = %d \n " , m_iEarnedXP [ ASW_XP_FRIENDLY_FIRE ] ) ;
Msg ( " EarnedXP[ ASW_XP_DAMAGE_TAKEN ] = %d \n " , m_iEarnedXP [ ASW_XP_DAMAGE_TAKEN ] ) ;
Msg ( " EarnedXP[ ASW_XP_HEALING ] = %d \n " , m_iEarnedXP [ ASW_XP_HEALING ] ) ;
Msg ( " EarnedXP[ ASW_XP_HACKING ] = %d \n " , m_iEarnedXP [ ASW_XP_HACKING ] ) ;
Msg ( " EarnedXP[ ASW_XP_MEDALS ] = %d \n " , m_iEarnedXP [ ASW_XP_MEDALS ] ) ;
Msg ( " EarnedXP[ ASW_XP_TOTAL ] = %d (Difficulty scale = %f) \n " , m_iEarnedXP [ ASW_XP_TOTAL ] , ASWGameRules ( ) ? ( ASWGameRules ( ) - > GetSkillLevel ( ) - 1 ) : 1.0f ) ;
}
}
int CASW_Player : : GetLevel ( )
{
2010-10-11 17:51:21 -05:00
return LevelFromXP ( GetExperience ( ) , GetPromotion ( ) ) ;
2010-07-22 01:46:14 -05:00
}
int CASW_Player : : GetLevelBeforeDebrief ( )
{
2010-10-11 17:51:21 -05:00
return LevelFromXP ( GetExperienceBeforeDebrief ( ) , GetPromotion ( ) ) ;
2010-07-22 01:46:14 -05:00
}
void CASW_Player : : RequestExperience ( )
{
# ifdef CLIENT_DLL
// pull XP/level out of the medal store. Steam stats will overwrite these numbers if stat get is successful and USE_XP_FROM_STEAM is defined
if ( IsLocalPlayer ( ) & & GetMedalStore ( ) )
{
m_iExperience = GetMedalStore ( ) - > GetExperience ( ) ;
m_iPromotion = GetMedalStore ( ) - > GetPromotion ( ) ;
}
# endif
# if !defined(NO_STEAM)
# ifdef CLIENT_DLL
# if !defined(USE_XP_FROM_STEAM)
// if we're not pulling XP from Steam stats, then we don't request it for other players
// (instead we wait for the server to network their XP)
if ( ! IsLocalPlayer ( ) )
return ;
# endif
Assert ( steamapicontext - > SteamUserStats ( ) ) ;
if ( steamapicontext - > SteamUserStats ( ) )
{
if ( IsLocalPlayer ( this ) )
{
steamapicontext - > SteamUserStats ( ) - > RequestCurrentStats ( ) ;
}
else
{
player_info_t pi ;
if ( engine - > GetPlayerInfo ( entindex ( ) , & pi ) & & pi . friendsID )
{
CSteamID steamID ( pi . friendsID , 1 , steamapicontext - > SteamUtils ( ) - > GetConnectedUniverse ( ) , k_EAccountTypeIndividual ) ;
Msg ( " Requesting Steam stats for %s (%s) \n " , pi . name ? pi . name : " NULL " , pi . friendsName ? pi . friendsName : " NULL " ) ;
steamapicontext - > SteamUserStats ( ) - > RequestUserStats ( steamID ) ;
}
}
m_bPendingSteamStats = true ;
m_flPendingSteamStatsStart = gpGlobals - > curtime ;
}
# else
Assert ( Steam3Server ( ) . SteamGameServerStats ( ) ) ;
if ( Steam3Server ( ) . SteamGameServerStats ( ) )
{
CSteamID steamID ;
if ( GetSteamID ( & steamID ) )
{
SteamAPICall_t hSteamAPICall = Steam3Server ( ) . SteamGameServerStats ( ) - > RequestUserStats ( steamID ) ;
if ( hSteamAPICall ! = 0 )
{
m_CallbackGSStatsReceived . Set ( hSteamAPICall , this , & CASW_Player : : Steam_OnGSStatsReceived ) ;
}
}
m_bPendingSteamStats = true ;
m_flPendingSteamStatsStart = gpGlobals - > curtime ;
}
# endif
# endif
}
void CASW_Player : : AwardExperience ( )
{
# ifdef CLIENT_DLL
if ( ! GetClientModeASW ( ) | | GetClientModeASW ( ) - > HasAwardedExperience ( this ) | | ! ASWGameRules ( ) | | ! ASWGameResource ( ) )
return ;
# else
if ( m_bHasAwardedXP | | ! ASWGameRules ( ) | | ! ASWGameResource ( ) )
return ;
# endif
if ( IsX360 ( ) )
return ;
m_iExperience = GetExperience ( ) ; // make sure m_iExperience has the correct number (no change if local player, otherwise using networked value)
m_iExperienceBeforeDebrief = m_iExperience ;
CalculateEarnedXP ( ) ;
Msg ( " %s: AwardExperience: Pre XP is %d \n " , IsServerDll ( ) ? " S " : " C " , m_iExperience ) ;
m_iExperience + = m_iEarnedXP [ ASW_XP_TOTAL ] ;
2010-10-11 17:51:21 -05:00
m_iExperience = MIN ( m_iExperience , ASW_XP_CAP * g_flPromotionXPScale [ GetPromotion ( ) ] ) ;
2010-07-22 01:46:14 -05:00
# ifdef CLIENT_DLL
if ( IsLocalPlayer ( ) )
{
# if !defined(NO_STEAM)
// only upload if Steam is running
if ( steamapicontext - > SteamUserStats ( ) )
{
if ( GetLocalASWPlayer ( ) = = this )
g_ASW_Steamstats . PrepStatsForSend ( this ) ;
steamapicontext - > SteamUserStats ( ) - > SetStat ( " experience " , m_iExperience ) ;
g_ASW_AchievementMgr . UploadUserData ( GetSplitScreenPlayerSlot ( ) ) ;
if ( GetMedalStore ( ) )
{
GetMedalStore ( ) - > SetExperience ( m_iExperience ) ;
GetMedalStore ( ) - > SetPromotion ( m_iPromotion ) ;
GetMedalStore ( ) - > SaveMedalStore ( ) ;
}
}
# endif // NO_STEAM
GetClientModeASW ( ) - > SetAwardedExperience ( this ) ;
}
# else
m_bHasAwardedXP = true ;
# endif
Msg ( " %s: Awarded %d XP for player %s (total is now %d) \n " , IsServerDll ( ) ? " S " : " C " , m_iEarnedXP [ ASW_XP_TOTAL ] , GetPlayerName ( ) , m_iExperience ) ;
}
# ifdef CLIENT_DLL
# ifdef _DEBUG
ConVar asw_unlock_all_weapons ( " asw_unlock_all_weapons " , " 0 " , FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY , " If enabled, all weapons will be available in the briefing " ) ;
# endif
int CASW_Player : : GetWeaponLevelRequirement ( const char * szWeaponClass )
{
for ( int i = 0 ; i < NELEMS ( g_WeaponUnlocks ) ; i + + )
{
if ( ! Q_stricmp ( szWeaponClass , g_WeaponUnlocks [ i ] . m_pszWeaponClass ) )
{
return g_WeaponUnlocks [ i ] . m_iLevel ;
}
}
return - 1 ;
}
bool CASW_Player : : IsWeaponUnlocked ( const char * szWeaponClass )
{
# ifdef _DEBUG
if ( asw_unlock_all_weapons . GetBool ( ) )
return true ;
# endif
if ( C_ASW_Equip_Req : : ForceWeaponUnlocked ( szWeaponClass ) )
return true ;
int iPlayerLevel = GetLevel ( ) ;
int iWeaponReq = GetWeaponLevelRequirement ( szWeaponClass ) ;
if ( iWeaponReq = = - 1 )
{
// if it's not in the list of unlocked weapons, assume it's unlocked by default
return true ;
}
return iWeaponReq < = iPlayerLevel ;
}
const char * CASW_Player : : GetNextWeaponClassUnlocked ( )
{
int iPlayerLevel = GetLevel ( ) ;
for ( int i = 0 ; i < NELEMS ( g_WeaponUnlocks ) ; i + + )
{
//Msg( "GetNextWeaponClassUnlocked: player level = %d weapon %s level = %d\n", iPlayerLevel, g_WeaponUnlocks[ i ].m_pszWeaponClass, g_WeaponUnlocks[ i ].m_iLevel );
if ( g_WeaponUnlocks [ i ] . m_iLevel > iPlayerLevel )
{
return g_WeaponUnlocks [ i ] . m_pszWeaponClass ;
}
}
return " " ;
}
const char * CASW_Player : : GetWeaponUnlockedAtLevel ( int nLevel )
{
for ( int i = 0 ; i < NELEMS ( g_WeaponUnlocks ) ; i + + )
{
if ( g_WeaponUnlocks [ i ] . m_iLevel = = nLevel )
{
return g_WeaponUnlocks [ i ] . m_pszWeaponClass ;
}
}
return " " ;
}
# if !defined(NO_STEAM)
//-----------------------------------------------------------------------------
// Purpose: called when stat download is complete
//-----------------------------------------------------------------------------
void CASW_Player : : Steam_OnUserStatsReceived ( UserStatsReceived_t * pUserStatsReceived )
{
Assert ( steamapicontext - > SteamUserStats ( ) ) ;
if ( ! steamapicontext - > SteamUserStats ( ) )
return ;
if ( pUserStatsReceived - > m_eResult ! = k_EResultOK )
{
//Msg( "CASW_Player: failed to download stats from Steam, EResult %d\n", pUserStatsReceived->m_eResult );
//Msg( " m_nGameID = %I64u\n", pUserStatsReceived->m_nGameID );
//Msg( " SteamID = %I64u\n", pUserStatsReceived->m_steamIDUser.ConvertToUint64() );
m_bPendingSteamStats = false ;
return ;
}
CSteamID steamID ;
if ( IsLocalPlayer ( ) )
{
steamID = steamapicontext - > SteamUser ( ) - > GetSteamID ( ) ;
}
else
{
player_info_t pi ;
if ( ! engine - > GetPlayerInfo ( entindex ( ) , & pi ) )
return ;
if ( ! pi . friendsID )
return ;
CSteamID steamIDForPlayer ( pi . friendsID , 1 , steamapicontext - > SteamUtils ( ) - > GetConnectedUniverse ( ) , k_EAccountTypeIndividual ) ;
steamID = steamIDForPlayer ;
Msg ( " Steam_OnUserStatsReceived for non local player %s (%s) \n " , pi . name ? pi . name : " NULL " , pi . friendsName ? pi . friendsName : " NULL " ) ;
}
if ( steamID ! = pUserStatsReceived - > m_steamIDUser )
return ;
# ifdef USE_XP_FROM_STEAM
if ( steamapicontext - > SteamUserStats ( ) - > GetUserStat ( steamID , " experience " , & m_iExperience ) )
{
m_bPendingSteamStats = false ;
}
else
{
Msg ( " Error retrieving experience stat for player %s. \n " , GetPlayerName ( ) ) ;
}
if ( ! steamapicontext - > SteamUserStats ( ) - > GetUserStat ( steamID , " promotion " , & m_iPromotion ) )
{
Msg ( " Error retrieving promotion stat for player %s. \n " , GetPlayerName ( ) ) ;
}
# else
if ( IsLocalPlayer ( this ) )
{
if ( GetMedalStore ( ) )
{
if ( ! GetMedalStore ( ) - > m_bFoundNewClientDat ) // if we failed to find the new client dat, then take steam numbers
{
if ( steamapicontext - > SteamUserStats ( ) - > GetUserStat ( steamID , " experience " , & m_iExperience ) )
{
m_bPendingSteamStats = false ;
}
else
{
Msg ( " Error retrieving experience stat for player %s. \n " , GetPlayerName ( ) ) ;
}
if ( ! steamapicontext - > SteamUserStats ( ) - > GetUserStat ( steamID , " promotion " , & m_iPromotion ) )
{
Msg ( " Error retrieving promotion stat for player %s. \n " , GetPlayerName ( ) ) ;
}
KeyValues * kv = new KeyValues ( " XPUpdate " ) ;
kv - > SetInt ( " xp " , m_iExperience ) ;
kv - > SetInt ( " pro " , m_iPromotion ) ;
engine - > ServerCmdKeyValues ( kv ) ; // kv gets deleted in here
}
}
}
m_bPendingSteamStats = false ;
# endif
// Fetch the rest of the steam stats here
if ( GetLocalASWPlayer ( ) = = this )
g_ASW_Steamstats . FetchStats ( steamID , this ) ;
2010-10-11 17:51:21 -05:00
if ( IsLocalPlayer ( ) & & GetLevel ( ) > = ASW_NUM_EXPERIENCE_LEVELS )
2010-07-22 01:46:14 -05:00
{
CAchievementMgr * pAchievementMgr = dynamic_cast < CAchievementMgr * > ( engine - > GetAchievementMgr ( ) ) ;
if ( ! pAchievementMgr )
return ;
pAchievementMgr - > OnAchievementEvent ( ACHIEVEMENT_ASW_UNLOCK_ALL_WEAPONS , STEAM_PLAYER_SLOT ) ;
}
}
void CASW_Player : : Steam_OnUserStatsStored ( UserStatsStored_t * pUserStatsStored )
{
if ( ! IsLocalPlayer ( this ) )
return ;
CSteamID steamID = steamapicontext - > SteamUser ( ) - > GetSteamID ( ) ;
if ( k_EResultOK ! = pUserStatsStored - > m_eResult )
{
DevMsg ( " CASW_Player: failed to upload stats to Steam, EResult %d \n " , pUserStatsStored - > m_eResult ) ;
# ifdef USE_XP_FROM_STEAM
steamapicontext - > SteamUserStats ( ) - > GetStat ( " experience " , & m_iExperience ) ;
steamapicontext - > SteamUserStats ( ) - > GetStat ( " promotion " , & m_iPromotion ) ;
# endif
// Set stats to whatever is stored on steam
if ( GetLocalASWPlayer ( ) = = this )
g_ASW_Steamstats . FetchStats ( steamID , this ) ;
}
}
# endif
void asw_debug_xp_f ( )
{
C_ASW_Player * pPlayer = C_ASW_Player : : GetLocalASWPlayer ( ) ;
if ( pPlayer )
{
Msg ( " Local player Level = %d \n " , pPlayer - > GetLevel ( ) ) ;
Msg ( " Local player XP = %d \n " , pPlayer - > GetExperience ( ) ) ;
Msg ( " Local player earned XP = %d \n " , pPlayer - > GetEarnedXP ( ASW_XP_TOTAL ) ) ;
Msg ( " Local player promotion level = %d \n " , pPlayer - > GetPromotion ( ) ) ;
}
}
ConCommand asw_debug_xp ( " asw_debug_xp " , asw_debug_xp_f , " Lists XP details for local player " , FCVAR_NONE ) ;
void CASW_Player : : AcceptPromotion ( )
{
2010-10-11 17:51:21 -05:00
if ( GetExperience ( ) < ASW_XP_CAP * g_flPromotionXPScale [ GetPromotion ( ) ] )
2010-07-22 01:46:14 -05:00
return ;
if ( GetPromotion ( ) > = ASW_PROMOTION_CAP )
return ;
m_iExperience = 0 ;
m_iPromotion + + ;
# if !defined(NO_STEAM)
// only upload if Steam is running
if ( steamapicontext - > SteamUserStats ( ) )
{
steamapicontext - > SteamUserStats ( ) - > SetStat ( " experience " , m_iExperience ) ;
steamapicontext - > SteamUserStats ( ) - > SetStat ( " promotion " , m_iPromotion ) ;
steamapicontext - > SteamUserStats ( ) - > SetStat ( " level " , 1 ) ;
steamapicontext - > SteamUserStats ( ) - > SetStat ( " level.xprequired " , 0 ) ;
g_ASW_AchievementMgr . UploadUserData ( GetSplitScreenPlayerSlot ( ) ) ;
if ( GetMedalStore ( ) )
{
GetMedalStore ( ) - > ClearNewWeapons ( ) ;
GetMedalStore ( ) - > SetExperience ( m_iExperience ) ;
GetMedalStore ( ) - > SetPromotion ( m_iPromotion ) ;
GetMedalStore ( ) - > SaveMedalStore ( ) ;
}
KeyValues * kv = new KeyValues ( " XPUpdate " ) ;
kv - > SetInt ( " xp " , m_iExperience ) ;
kv - > SetInt ( " pro " , m_iPromotion ) ;
engine - > ServerCmdKeyValues ( kv ) ; // kv gets deleted in here
}
# endif // NO_STEAM
CLocalPlayerFilter filter ;
C_BaseEntity : : EmitSound ( filter , - 1 /*SOUND_FROM_LOCAL_PLAYER*/ , " ASW_XP.LevelUp " ) ;
engine - > ClientCmd ( VarArgs ( " cl_promoted %d " , m_iPromotion ) ) ;
// reset the player's selected equipment
if ( ! ASWGameResource ( ) | | ! ASWEquipmentList ( ) )
return ;
C_ASW_Marine_Resource * pMR = ASWGameResource ( ) - > GetFirstMarineResourceForPlayer ( this ) ;
if ( ! pMR )
return ;
CASW_Marine_Profile * pProfile = pMR - > GetProfile ( ) ;
if ( ! pProfile )
return ;
for ( int i = 0 ; i < ASW_NUM_INVENTORY_SLOTS ; i + + )
{
const char * szWeaponClass = pProfile - > m_DefaultWeaponsInSlots [ i ] ;
int nWeaponIndex = ASWEquipmentList ( ) - > GetIndexForSlot ( i , szWeaponClass ) ;
engine - > ClientCmd ( VarArgs ( " cl_loadout %d %d %d " , pProfile - > m_ProfileIndex , i , nWeaponIndex ) ) ;
}
}
# else
// SERVER
# if !defined(NO_STEAM)
void CASW_Player : : Steam_OnGSStatsReceived ( GSStatsReceived_t * pGSStatsReceived , bool bError )
{
Assert ( Steam3Server ( ) . SteamGameServerStats ( ) ) ;
if ( ! Steam3Server ( ) . SteamGameServerStats ( ) )
return ;
if ( pGSStatsReceived - > m_eResult ! = k_EResultOK )
{
Msg ( " CASW_Player: Server failed to download stats from Steam, EResult %d \n " , pGSStatsReceived - > m_eResult ) ;
//Msg( " SteamID = %I64u\n", pGSStatsReceived->m_steamIDUser.ConvertToUint64() );
m_bPendingSteamStats = false ;
return ;
}
CSteamID steamIDForPlayer ;
if ( ! GetSteamID ( & steamIDForPlayer ) )
return ;
if ( steamIDForPlayer ! = pGSStatsReceived - > m_steamIDUser )
return ;
# ifdef USE_XP_FROM_STEAM
if ( Steam3Server ( ) . SteamGameServerStats ( ) - > GetUserStat ( steamIDForPlayer , " experience " , & m_iExperience ) )
{
m_bPendingSteamStats = false ;
}
else
{
Msg ( " Server error retrieving experience stat for player %s. \n " , GetPlayerName ( ) ) ;
}
Steam3Server ( ) . SteamGameServerStats ( ) - > GetUserStat ( steamIDForPlayer , " promotion " , & m_iPromotion )
# endif
}
# endif // NO_STEAM
# endif
int GetXPForMedal ( int nMedal )
{
return 50 ; // TODO: Different XP for different medal types?
}
int CASW_Player : : GetExperience ( )
{
# ifdef USE_XP_FROM_STEAM
return m_iExperience ; // stat taken from steam stats
# else
# ifdef CLIENT_DLL
if ( IsLocalPlayer ( ) )
{
return m_iExperience ; // XP read from medal store
}
# endif
return m_iNetworkedXP . Get ( ) ; // XP networked down from the server
# endif
}
int CASW_Player : : GetPromotion ( )
{
# ifdef USE_XP_FROM_STEAM
return m_iPromotion ; // stat taken from steam stats
# else
# ifdef CLIENT_DLL
if ( IsLocalPlayer ( ) )
{
return m_iPromotion ; // XP read from medal store
}
# endif
return m_iNetworkedPromotion . Get ( ) ; // XP networked down from the server
# endif
}