548 lines
13 KiB
C++
548 lines
13 KiB
C++
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================
|
||
|
|
||
|
|
||
|
#include "cbase.h"
|
||
|
#include "achievementmgr.h"
|
||
|
#include "baseachievement.h"
|
||
|
|
||
|
#ifdef GAME_DLL
|
||
|
#include "prop_portal.h"
|
||
|
#include "util.h"
|
||
|
|
||
|
CAchievementMgr g_AchievementMgrPortal; // global achievement mgr for Portal
|
||
|
|
||
|
class CAchievementPortalInfiniteFall : public CBaseAchievement
|
||
|
{
|
||
|
DECLARE_CLASS( CAchievementPortalInfiniteFall, CBaseAchievement );
|
||
|
|
||
|
public:
|
||
|
void Init()
|
||
|
{
|
||
|
SetFlags( ACH_SAVE_WITH_GAME );
|
||
|
SetGameDirFilter( "portal" );
|
||
|
SetGoal( 1 );
|
||
|
m_fAccumulatedDistance = 0.0f;
|
||
|
m_bIsFlinging = false;
|
||
|
}
|
||
|
virtual void ListenForEvents()
|
||
|
{
|
||
|
ListenForGameEvent( "portal_player_portaled" );
|
||
|
ListenForGameEvent( "portal_player_touchedground" );
|
||
|
}
|
||
|
virtual void PreRestoreSavedGame()
|
||
|
{
|
||
|
m_fAccumulatedDistance = 0.0f;
|
||
|
m_bIsFlinging = false;
|
||
|
BaseClass::PreRestoreSavedGame();
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
virtual void FireGameEvent( IGameEvent *event )
|
||
|
{
|
||
|
const char *name = event->GetName();
|
||
|
if ( 0 == Q_strcmp( name, "portal_player_portaled" ) )
|
||
|
{
|
||
|
bool bIsPortal2 = event->GetBool( "portal2", false );
|
||
|
// Get the portals that they teleported through
|
||
|
CProp_Portal *pInPortal = CProp_Portal::FindPortal( 0, bIsPortal2, false );
|
||
|
CProp_Portal *pOutPortal = CProp_Portal::FindPortal( 0, !bIsPortal2, false );
|
||
|
|
||
|
if ( pInPortal && pOutPortal )
|
||
|
{
|
||
|
if ( m_bIsFlinging )
|
||
|
{
|
||
|
// Add up how far we traveled since the last teleport
|
||
|
m_fAccumulatedDistance += m_fZPortalPosition - pInPortal->GetAbsOrigin().z;
|
||
|
|
||
|
if ( m_fAccumulatedDistance > 30000.0f * 12 )
|
||
|
IncrementCount();
|
||
|
}
|
||
|
|
||
|
// Remember the Z position to get the distance when the teleport again or land
|
||
|
m_fZPortalPosition = pOutPortal->GetAbsOrigin().z;
|
||
|
m_bIsFlinging = true;
|
||
|
}
|
||
|
}
|
||
|
else if ( 0 == Q_strcmp( name, "portal_player_touchedground" ) )
|
||
|
{
|
||
|
if ( m_bIsFlinging )
|
||
|
{
|
||
|
CBasePlayer *pLocalPlayer = UTIL_GetLocalPlayer();
|
||
|
|
||
|
if ( pLocalPlayer )
|
||
|
{
|
||
|
m_fAccumulatedDistance += m_fZPortalPosition - pLocalPlayer->GetAbsOrigin().z;
|
||
|
|
||
|
if ( m_fAccumulatedDistance > 30000.0f * 12 )
|
||
|
IncrementCount();
|
||
|
|
||
|
m_fAccumulatedDistance = 0.0f;
|
||
|
m_bIsFlinging = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
bool m_bIsFlinging;
|
||
|
float m_fAccumulatedDistance;
|
||
|
float m_fZPortalPosition;
|
||
|
};
|
||
|
DECLARE_ACHIEVEMENT( CAchievementPortalInfiniteFall, ACHIEVEMENT_PORTAL_INFINITEFALL, "PORTAL_INFINITEFALL", 5 );
|
||
|
|
||
|
class CAchievementPortalLongJump : public CBaseAchievement
|
||
|
{
|
||
|
DECLARE_CLASS( CAchievementPortalLongJump, CBaseAchievement );
|
||
|
|
||
|
public:
|
||
|
void Init()
|
||
|
{
|
||
|
SetFlags( ACH_SAVE_WITH_GAME );
|
||
|
SetGameDirFilter( "portal" );
|
||
|
SetGoal( 1 );
|
||
|
m_fAccumulatedDistance = 0.0f;
|
||
|
m_bIsFlinging = false;
|
||
|
}
|
||
|
virtual void ListenForEvents()
|
||
|
{
|
||
|
ListenForGameEvent( "portal_player_portaled" );
|
||
|
ListenForGameEvent( "portal_player_touchedground" );
|
||
|
}
|
||
|
virtual void PreRestoreSavedGame()
|
||
|
{
|
||
|
m_fAccumulatedDistance = 0.0f;
|
||
|
m_bIsFlinging = false;
|
||
|
BaseClass::PreRestoreSavedGame();
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
virtual void FireGameEvent( IGameEvent *event )
|
||
|
{
|
||
|
const char *name = event->GetName();
|
||
|
if ( 0 == Q_strcmp( name, "portal_player_portaled" ) )
|
||
|
{
|
||
|
bool bIsPortal2 = event->GetBool( "portal2", false );
|
||
|
// Get the portals that they teleported through
|
||
|
CProp_Portal *pInPortal = CProp_Portal::FindPortal( 0, bIsPortal2, false );
|
||
|
CProp_Portal *pOutPortal = CProp_Portal::FindPortal( 0, !bIsPortal2, false );
|
||
|
|
||
|
if ( pInPortal && pOutPortal )
|
||
|
{
|
||
|
if ( m_bIsFlinging )
|
||
|
{
|
||
|
// Add up how far we traveled since the last teleport
|
||
|
float flDist = pInPortal->GetAbsOrigin().AsVector2D().DistTo( m_vec2DPortalPosition );
|
||
|
|
||
|
// Ignore small distances that can be caused by microadjustments in infinite falls
|
||
|
if ( flDist > 63.0f )
|
||
|
{
|
||
|
m_fAccumulatedDistance += flDist;
|
||
|
}
|
||
|
|
||
|
if ( m_fAccumulatedDistance > 300.0f * 12 )
|
||
|
IncrementCount();
|
||
|
}
|
||
|
|
||
|
// Remember the 2D position to get the distance when the teleport again or land
|
||
|
m_vec2DPortalPosition = pOutPortal->GetAbsOrigin().AsVector2D();
|
||
|
m_bIsFlinging = true;
|
||
|
}
|
||
|
}
|
||
|
else if ( 0 == Q_strcmp( name, "portal_player_touchedground" ) )
|
||
|
{
|
||
|
if ( m_bIsFlinging )
|
||
|
{
|
||
|
CBasePlayer *pLocalPlayer = UTIL_GetLocalPlayer();
|
||
|
|
||
|
if ( pLocalPlayer )
|
||
|
{
|
||
|
float flDist = pLocalPlayer->GetAbsOrigin().AsVector2D().DistTo( m_vec2DPortalPosition );
|
||
|
|
||
|
// Ignore small distances that can be caused by microadjustments in infinite falls
|
||
|
if ( flDist > 63.0f )
|
||
|
{
|
||
|
m_fAccumulatedDistance += flDist;
|
||
|
}
|
||
|
|
||
|
if ( m_fAccumulatedDistance > 300.0f * 12 )
|
||
|
IncrementCount();
|
||
|
|
||
|
m_fAccumulatedDistance = 0.0f;
|
||
|
m_bIsFlinging = false;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
bool m_bIsFlinging;
|
||
|
float m_fAccumulatedDistance;
|
||
|
Vector2D m_vec2DPortalPosition;
|
||
|
};
|
||
|
DECLARE_ACHIEVEMENT( CAchievementPortalLongJump, ACHIEVEMENT_PORTAL_LONGJUMP, "PORTAL_LONGJUMP", 5 );
|
||
|
|
||
|
class CAchievementPortalBeat2AdvancedMaps: public CBaseAchievement
|
||
|
{
|
||
|
public:
|
||
|
virtual void Init()
|
||
|
{
|
||
|
SetFlags( ACH_SAVE_GLOBAL );
|
||
|
SetGoal( 2 );
|
||
|
m_iProgressMsgMinimum = 0;
|
||
|
}
|
||
|
virtual void ListenForEvents()
|
||
|
{
|
||
|
ListenForGameEvent( "advanced_map_complete" );
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
virtual void FireGameEvent( IGameEvent* event )
|
||
|
{
|
||
|
if ( !Q_stricmp( event->GetName(), "advanced_map_complete" ) )
|
||
|
{
|
||
|
if ( !IsAchieved() )
|
||
|
{
|
||
|
int iNumAdvanced = event->GetInt( "numadvanced" );
|
||
|
|
||
|
SetCount ( iNumAdvanced );
|
||
|
if ( iNumAdvanced >= GetGoal() )
|
||
|
{
|
||
|
AwardAchievement();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HandleProgressUpdate();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
virtual void CalcProgressMsgIncrement()
|
||
|
{
|
||
|
// show progress every tick
|
||
|
m_iProgressMsgIncrement = 1;
|
||
|
}
|
||
|
};
|
||
|
DECLARE_ACHIEVEMENT( CAchievementPortalBeat2AdvancedMaps, ACHIEVEMENT_PORTAL_BEAT_2ADVANCEDMAPS, "PORTAL_BEAT_2ADVANCEDMAPS", 10 );
|
||
|
|
||
|
class CAchievementPortalBeat4AdvancedMaps : public CBaseAchievement
|
||
|
{
|
||
|
public:
|
||
|
virtual void Init()
|
||
|
{
|
||
|
SetFlags( ACH_SAVE_GLOBAL );
|
||
|
SetGoal( 4 );
|
||
|
m_iProgressMsgMinimum = 3;
|
||
|
}
|
||
|
virtual void ListenForEvents()
|
||
|
{
|
||
|
ListenForGameEvent( "advanced_map_complete" );
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
virtual void FireGameEvent( IGameEvent* event )
|
||
|
{
|
||
|
if ( !Q_stricmp( event->GetName(), "advanced_map_complete" ) )
|
||
|
{
|
||
|
if ( !IsAchieved() )
|
||
|
{
|
||
|
int iNumAdvanced = event->GetInt( "numadvanced" );
|
||
|
|
||
|
SetCount ( iNumAdvanced );
|
||
|
if ( iNumAdvanced >= GetGoal() )
|
||
|
{
|
||
|
AwardAchievement();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HandleProgressUpdate();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
virtual void CalcProgressMsgIncrement()
|
||
|
{
|
||
|
// show progress every tick
|
||
|
m_iProgressMsgIncrement = 1;
|
||
|
}
|
||
|
};
|
||
|
DECLARE_ACHIEVEMENT( CAchievementPortalBeat4AdvancedMaps, ACHIEVEMENT_PORTAL_BEAT_4ADVANCEDMAPS, "PORTAL_BEAT_4ADVANCEDMAPS", 20 );
|
||
|
|
||
|
class CAchievementPortalBeat6AdvancedMaps : public CBaseAchievement
|
||
|
{
|
||
|
public:
|
||
|
virtual void Init()
|
||
|
{
|
||
|
SetFlags( ACH_SAVE_GLOBAL );
|
||
|
SetGoal( 6 );
|
||
|
m_iProgressMsgMinimum = 5;
|
||
|
}
|
||
|
virtual void ListenForEvents()
|
||
|
{
|
||
|
ListenForGameEvent( "advanced_map_complete" );
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
virtual void FireGameEvent( IGameEvent* event )
|
||
|
{
|
||
|
if ( !Q_stricmp( event->GetName(), "advanced_map_complete" ) )
|
||
|
{
|
||
|
if ( !IsAchieved() )
|
||
|
{
|
||
|
int iNumAdvanced = event->GetInt( "numadvanced" );
|
||
|
|
||
|
SetCount ( iNumAdvanced );
|
||
|
if ( iNumAdvanced >= GetGoal() )
|
||
|
{
|
||
|
AwardAchievement();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HandleProgressUpdate();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
virtual void CalcProgressMsgIncrement()
|
||
|
{
|
||
|
// show progress every tick
|
||
|
m_iProgressMsgIncrement = 1;
|
||
|
}
|
||
|
};
|
||
|
DECLARE_ACHIEVEMENT( CAchievementPortalBeat6AdvancedMaps, ACHIEVEMENT_PORTAL_BEAT_6ADVANCEDMAPS, "PORTAL_BEAT_6ADVANCEDMAPS", 30 );
|
||
|
|
||
|
class CAchievementPortalGetAllBronze : public CBaseAchievement
|
||
|
{
|
||
|
public:
|
||
|
virtual void Init()
|
||
|
{
|
||
|
SetFlags( ACH_SAVE_GLOBAL );
|
||
|
SetGoal( 18 );
|
||
|
}
|
||
|
virtual void ListenForEvents()
|
||
|
{
|
||
|
ListenForGameEvent( "challenge_map_complete" );
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
virtual void FireGameEvent( IGameEvent* event )
|
||
|
{
|
||
|
if ( !Q_stricmp( event->GetName(), "challenge_map_complete" ) )
|
||
|
{
|
||
|
if ( !IsAchieved() )
|
||
|
{
|
||
|
int iBronzeCount = event->GetInt( "numbronze" );
|
||
|
|
||
|
SetCount ( iBronzeCount );
|
||
|
if ( iBronzeCount >= GetGoal() )
|
||
|
{
|
||
|
AwardAchievement();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HandleProgressUpdate();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
virtual void CalcProgressMsgIncrement()
|
||
|
{
|
||
|
// show progress every tick
|
||
|
m_iProgressMsgIncrement = 1;
|
||
|
}
|
||
|
};
|
||
|
DECLARE_ACHIEVEMENT( CAchievementPortalGetAllBronze, ACHIEVEMENT_PORTAL_GET_ALLBRONZE, "PORTAL_GET_ALLBRONZE", 10 );
|
||
|
|
||
|
class CAchievementPortalGetAllSilver : public CBaseAchievement
|
||
|
{
|
||
|
public:
|
||
|
virtual void Init()
|
||
|
{
|
||
|
SetFlags( ACH_SAVE_GLOBAL );
|
||
|
SetGoal( 18 );
|
||
|
}
|
||
|
virtual void ListenForEvents()
|
||
|
{
|
||
|
ListenForGameEvent( "challenge_map_complete" );
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
virtual void FireGameEvent( IGameEvent* event )
|
||
|
{
|
||
|
if ( !Q_stricmp( event->GetName(), "challenge_map_complete" ) )
|
||
|
{
|
||
|
if ( !IsAchieved() )
|
||
|
{
|
||
|
int iSilverCount = event->GetInt( "numsilver" );
|
||
|
|
||
|
SetCount ( iSilverCount );
|
||
|
if ( iSilverCount >= GetGoal() )
|
||
|
{
|
||
|
AwardAchievement();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HandleProgressUpdate();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
virtual void CalcProgressMsgIncrement()
|
||
|
{
|
||
|
// show progress every tick
|
||
|
m_iProgressMsgIncrement = 1;
|
||
|
}
|
||
|
};
|
||
|
DECLARE_ACHIEVEMENT( CAchievementPortalGetAllSilver, ACHIEVEMENT_PORTAL_GET_ALLSILVER, "PORTAL_GET_ALLSILVER", 20 );
|
||
|
|
||
|
class CAchievementPortalGetAllGold : public CBaseAchievement
|
||
|
{
|
||
|
public:
|
||
|
virtual void Init()
|
||
|
{
|
||
|
SetFlags( ACH_SAVE_GLOBAL );
|
||
|
SetGoal( 18 );
|
||
|
}
|
||
|
virtual void ListenForEvents()
|
||
|
{
|
||
|
ListenForGameEvent( "challenge_map_complete" );
|
||
|
}
|
||
|
|
||
|
protected:
|
||
|
virtual void FireGameEvent( IGameEvent* event )
|
||
|
{
|
||
|
if ( !Q_stricmp( event->GetName(), "challenge_map_complete" ) )
|
||
|
{
|
||
|
if ( !IsAchieved() )
|
||
|
{
|
||
|
int iGoldCount = event->GetInt( "numgold" );
|
||
|
|
||
|
SetCount ( iGoldCount );
|
||
|
if ( iGoldCount >= GetGoal() )
|
||
|
{
|
||
|
AwardAchievement();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
HandleProgressUpdate();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
virtual void CalcProgressMsgIncrement()
|
||
|
{
|
||
|
// show progress every tick
|
||
|
m_iProgressMsgIncrement = 1;
|
||
|
}
|
||
|
};
|
||
|
DECLARE_ACHIEVEMENT( CAchievementPortalGetAllGold, ACHIEVEMENT_PORTAL_GET_ALLGOLD, "PORTAL_GET_ALLGOLD", 40 );
|
||
|
|
||
|
|
||
|
class CAchievementPortalDetachAllCameras : public CBaseAchievement
|
||
|
{
|
||
|
protected:
|
||
|
virtual void ListenForEvents()
|
||
|
{
|
||
|
ListenForGameEvent( "security_camera_detached" );
|
||
|
}
|
||
|
|
||
|
void FireGameEvent_Internal( IGameEvent *event )
|
||
|
{
|
||
|
if ( 0 == Q_strcmp( event->GetName(), "security_camera_detached" ) )
|
||
|
{
|
||
|
IncrementCount();
|
||
|
}
|
||
|
}
|
||
|
public:
|
||
|
virtual void Init()
|
||
|
{
|
||
|
SetFlags( ACH_SAVE_WITH_GAME );
|
||
|
SetGoal( 33 );
|
||
|
ListenForGameEvent( "security_camera_detached" );
|
||
|
}
|
||
|
};
|
||
|
DECLARE_ACHIEVEMENT( CAchievementPortalDetachAllCameras, ACHIEVEMENT_PORTAL_DETACH_ALL_CAMERAS, "PORTAL_DETACH_ALL_CAMERAS", 5 );
|
||
|
|
||
|
|
||
|
class CAchievementPortalHitTurretWithTurret : public CBaseAchievement
|
||
|
{
|
||
|
protected:
|
||
|
virtual void ListenForEvents()
|
||
|
{
|
||
|
ListenForGameEvent( "turret_hit_turret" );
|
||
|
}
|
||
|
|
||
|
void FireGameEvent_Internal( IGameEvent *event )
|
||
|
{
|
||
|
if ( 0 == Q_strcmp( event->GetName(), "turret_hit_turret" ) )
|
||
|
{
|
||
|
IncrementCount();
|
||
|
}
|
||
|
}
|
||
|
public:
|
||
|
virtual void Init()
|
||
|
{
|
||
|
SetFlags( ACH_SAVE_GLOBAL );
|
||
|
SetGoal( 1 );
|
||
|
ListenForGameEvent( "turret_hit_turret" );
|
||
|
}
|
||
|
};
|
||
|
DECLARE_ACHIEVEMENT( CAchievementPortalHitTurretWithTurret, ACHIEVEMENT_PORTAL_HIT_TURRET_WITH_TURRET, "PORTAL_HIT_TURRET_WITH_TURRET", 5 );
|
||
|
|
||
|
|
||
|
#ifndef _XBOX
|
||
|
class CAchievementPortalFindAllDinosaurs : public CBaseAchievement
|
||
|
{
|
||
|
DECLARE_CLASS( CAchievementPortalFindAllDinosaurs, CBaseAchievement );
|
||
|
void Init()
|
||
|
{
|
||
|
SetFlags( ACH_HAS_COMPONENTS | ACH_SAVE_GLOBAL );
|
||
|
m_iNumComponents = 26;
|
||
|
SetStoreProgressInSteam( true );
|
||
|
SetGoal( m_iNumComponents );
|
||
|
BaseClass::Init();
|
||
|
m_iProgressMsgMinimum = 1;
|
||
|
}
|
||
|
virtual void ListenForEvents()
|
||
|
{
|
||
|
ListenForGameEvent( "dinosaur_signal_found" );
|
||
|
}
|
||
|
virtual void FireGameEvent_Internal( IGameEvent *event )
|
||
|
{
|
||
|
if ( 0 == Q_strcmp( event->GetName(), "dinosaur_signal_found" ) )
|
||
|
{
|
||
|
int id = event->GetInt( "id", -1 );
|
||
|
Assert( id >= 0 && id < m_iNumComponents );
|
||
|
if ( id >= 0 && id < m_iNumComponents )
|
||
|
{
|
||
|
EnsureComponentBitSetAndEvaluate( id );
|
||
|
|
||
|
// Update our Steam stat
|
||
|
steamapicontext->SteamUserStats()->SetStat( "PORTAL_TRANSMISSION_RECEIVED_STAT", m_iCount );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Warning( "Failed to set achievement progress. Dinosaur ID(%d) out of range (0 to %d)\n", id, m_iNumComponents );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
virtual void CalcProgressMsgIncrement()
|
||
|
{
|
||
|
// Show progress every tick
|
||
|
m_iProgressMsgIncrement = 1;
|
||
|
}
|
||
|
};
|
||
|
DECLARE_ACHIEVEMENT( CAchievementPortalFindAllDinosaurs, ACHIEVEMENT_PORTAL_TRANSMISSION_RECEIVED, "PORTAL_TRANSMISSION_RECEIVED", 0 );
|
||
|
#endif // _XBOX
|
||
|
|
||
|
// achievements which are won by a map event firing once
|
||
|
DECLARE_MAP_EVENT_ACHIEVEMENT( ACHIEVEMENT_PORTAL_GET_PORTALGUNS, "PORTAL_GET_PORTALGUNS", 5 );
|
||
|
DECLARE_MAP_EVENT_ACHIEVEMENT( ACHIEVEMENT_PORTAL_KILL_COMPANIONCUBE, "PORTAL_KILL_COMPANIONCUBE", 5 );
|
||
|
DECLARE_MAP_EVENT_ACHIEVEMENT( ACHIEVEMENT_PORTAL_ESCAPE_TESTCHAMBERS, "PORTAL_ESCAPE_TESTCHAMBERS", 5 );
|
||
|
DECLARE_MAP_EVENT_ACHIEVEMENT( ACHIEVEMENT_PORTAL_BEAT_GAME, "PORTAL_BEAT_GAME", 10 );
|
||
|
|
||
|
#endif // GAME_DLL
|