mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-23 14:46:53 +00:00
527 lines
14 KiB
C++
527 lines
14 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose: The TF Game rules object
|
|
//
|
|
// $Workfile: $
|
|
// $Date: $
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
#ifndef DOD_GAMERULES_H
|
|
#define DOD_GAMERULES_H
|
|
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
#include "teamplay_gamerules.h"
|
|
#include "convar.h"
|
|
#include "dod_shareddefs.h"
|
|
#include "gamevars_shared.h"
|
|
#include "weapon_dodbase.h"
|
|
#include "dod_round_timer.h"
|
|
|
|
#ifdef CLIENT_DLL
|
|
#include "c_baseplayer.h"
|
|
#else
|
|
#include "player.h"
|
|
#include "dod_player.h"
|
|
#include "utlqueue.h"
|
|
#include "playerclass_info_parse.h"
|
|
#include "voice_gamemgr.h"
|
|
#include "dod_gamestats.h"
|
|
#endif
|
|
|
|
#ifdef CLIENT_DLL
|
|
#define CDODGameRules C_DODGameRules
|
|
#define CDODGameRulesProxy C_DODGameRulesProxy
|
|
#else
|
|
extern IVoiceGameMgrHelper *g_pVoiceGameMgrHelper;
|
|
extern IUploadGameStats *gamestatsuploader;
|
|
#endif
|
|
|
|
#ifndef CLIENT_DLL
|
|
|
|
class CSpawnPoint : public CPointEntity
|
|
{
|
|
public:
|
|
bool IsDisabled() { return m_bDisabled; }
|
|
void InputEnable( inputdata_t &inputdata ) { m_bDisabled = false; }
|
|
void InputDisable( inputdata_t &inputdata ) { m_bDisabled = true; }
|
|
|
|
private:
|
|
bool m_bDisabled;
|
|
DECLARE_DATADESC();
|
|
};
|
|
|
|
#endif
|
|
|
|
class CDODGameRulesProxy : public CGameRulesProxy
|
|
{
|
|
public:
|
|
DECLARE_CLASS( CDODGameRulesProxy, CGameRulesProxy );
|
|
DECLARE_NETWORKCLASS();
|
|
};
|
|
|
|
class CDODGameRules;
|
|
|
|
class CDODRoundStateInfo
|
|
{
|
|
public:
|
|
DODRoundState m_iRoundState;
|
|
const char *m_pStateName;
|
|
|
|
void (CDODGameRules::*pfnEnterState)(); // Init and deinit the state.
|
|
void (CDODGameRules::*pfnLeaveState)();
|
|
void (CDODGameRules::*pfnThink)(); // Do a PreThink() in this state.
|
|
};
|
|
|
|
typedef enum
|
|
{
|
|
STARTROUND_ATTACK = 0,
|
|
STARTROUND_DEFEND,
|
|
|
|
STARTROUND_BEACH,
|
|
|
|
STARTROUND_ATTACK_TIMED,
|
|
STARTROUND_DEFEND_TIMED,
|
|
|
|
STARTROUND_FLAGS,
|
|
} startround_voice_t;
|
|
|
|
class CDODGamePlayRules
|
|
{
|
|
public:
|
|
DECLARE_CLASS_NOBASE( CDODGamePlayRules );
|
|
DECLARE_EMBEDDED_NETWORKVAR();
|
|
|
|
DECLARE_SIMPLE_DATADESC();
|
|
|
|
CDODGamePlayRules()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
// This virtual method is necessary to generate a vtable in all cases
|
|
// (DECLARE_PREDICTABLE will generate a vtable also)!
|
|
virtual ~CDODGamePlayRules() {}
|
|
|
|
void Reset( void )
|
|
{
|
|
//RespawnFactor
|
|
m_fAlliesRespawnFactor = 1.0f;
|
|
m_fAxisRespawnFactor = 1.0f;
|
|
}
|
|
|
|
//Respawn Factors
|
|
float m_fAlliesRespawnFactor; //How delayed are respawning players
|
|
float m_fAxisRespawnFactor; //1.0 is normal, 2.0 is twice as long
|
|
|
|
int m_iAlliesStartRoundVoice; // Which voice to play at round start
|
|
int m_iAxisStartRoundVoice;
|
|
};
|
|
|
|
|
|
//Mapper interface for gamerules
|
|
class CDODDetect : public CBaseEntity
|
|
{
|
|
public:
|
|
DECLARE_CLASS( CDODDetect, CBaseEntity );
|
|
|
|
CDODDetect();
|
|
void Spawn( void );
|
|
virtual bool KeyValue( const char *szKeyName, const char *szValue );
|
|
|
|
bool IsMasteredOn( void );
|
|
|
|
inline CDODGamePlayRules *GetGamePlay() { return &m_GamePlayRules; }
|
|
CDODGamePlayRules m_GamePlayRules;
|
|
|
|
private:
|
|
// string_t m_sMaster;
|
|
};
|
|
|
|
class CDODViewVectors : public CViewVectors
|
|
{
|
|
public:
|
|
CDODViewVectors(
|
|
Vector vView,
|
|
Vector vHullMin,
|
|
Vector vHullMax,
|
|
Vector vDuckHullMin,
|
|
Vector vDuckHullMax,
|
|
Vector vDuckView,
|
|
Vector vObsHullMin,
|
|
Vector vObsHullMax,
|
|
Vector vDeadViewHeight,
|
|
Vector vProneHullMin,
|
|
Vector vProneHullMax ) :
|
|
CViewVectors(
|
|
vView,
|
|
vHullMin,
|
|
vHullMax,
|
|
vDuckHullMin,
|
|
vDuckHullMax,
|
|
vDuckView,
|
|
vObsHullMin,
|
|
vObsHullMax,
|
|
vDeadViewHeight )
|
|
{
|
|
m_vProneHullMin = vProneHullMin;
|
|
m_vProneHullMax = vProneHullMax;
|
|
}
|
|
|
|
Vector m_vProneHullMin;
|
|
Vector m_vProneHullMax;
|
|
};
|
|
|
|
//GAMERULES
|
|
class CDODGameRules : public CTeamplayRules
|
|
{
|
|
public:
|
|
DECLARE_CLASS( CDODGameRules, CTeamplayRules );
|
|
|
|
virtual bool ShouldCollide( int collisionGroup0, int collisionGroup1 );
|
|
|
|
inline DODRoundState State_Get( void ) { return m_iRoundState; }
|
|
|
|
int GetSubTeam( int team );
|
|
|
|
bool IsGameUnderTimeLimit( void );
|
|
int GetTimeLeft( void );
|
|
|
|
int GetReinforcementTimerSeconds( int team, float flSpawnEligibleTime );
|
|
|
|
bool IsFriendlyFireOn( void );
|
|
bool IsInBonusRound( void );
|
|
|
|
// Get the view vectors for this mod.
|
|
virtual const CViewVectors* GetViewVectors() const;
|
|
virtual const CDODViewVectors *GetDODViewVectors() const;
|
|
virtual const unsigned char *GetEncryptionKey( void ) { return (unsigned char *)"Wl0u5B3F"; }
|
|
|
|
bool AwaitingReadyRestart( void ) { return m_bAwaitingReadyRestart; }
|
|
float GetRoundRestartTime( void ) { return m_flRestartRoundTime; }
|
|
|
|
bool IsInWarmup( void ) { return m_bInWarmup; }
|
|
|
|
bool IsBombingTeam( int team );
|
|
|
|
virtual bool IsConnectedUserInfoChangeAllowed( CBasePlayer *pPlayer );
|
|
|
|
#ifndef CLIENT_DLL
|
|
float GetPresentDropChance( void ); // holiday 2011, presents instead of ammo boxes
|
|
#endif
|
|
|
|
#ifdef CLIENT_DLL
|
|
|
|
DECLARE_CLIENTCLASS_NOBASE(); // This makes datatables able to access our private vars.
|
|
|
|
void SetRoundState( int iRoundState );
|
|
float m_flLastRoundStateChangeTime;
|
|
|
|
#else
|
|
|
|
DECLARE_SERVERCLASS_NOBASE(); // This makes datatables able to access our private vars.
|
|
|
|
CDODGameRules();
|
|
virtual ~CDODGameRules();
|
|
|
|
virtual void LevelShutdown( void );
|
|
void UploadLevelStats( void );
|
|
|
|
virtual bool ClientCommand( CBaseEntity *pEdict, const CCommand &args );
|
|
virtual void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore );
|
|
virtual void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore, CBaseEntity *pEntityIgnore, bool bIgnoreWorld = false );
|
|
void RadiusStun( const CTakeDamageInfo &info, const Vector &vecSrc, float flRadius );
|
|
virtual void Think();
|
|
virtual void PlayerKilled( CBasePlayer *pVictim, const CTakeDamageInfo &info );
|
|
virtual void ClientDisconnected( edict_t *pClient );
|
|
virtual float FlPlayerFallDamage( CBasePlayer *pPlayer );
|
|
|
|
virtual const char *GetGameDescription( void )
|
|
{
|
|
return "Day of Defeat: Source";
|
|
}
|
|
|
|
void CreateStandardEntities( void );
|
|
|
|
virtual const char *GetChatPrefix( bool bTeamOnly, CBasePlayer *pPlayer );
|
|
|
|
CBaseEntity *GetPlayerSpawnSpot( CBasePlayer *pPlayer );
|
|
bool IsSpawnPointValid( CBaseEntity *pSpot, CBasePlayer *pPlayer );
|
|
virtual void PlayerSpawn( CBasePlayer *pPlayer );
|
|
|
|
int DODPointsForKill( CBasePlayer *pVictim, const CTakeDamageInfo &info );
|
|
|
|
//Round state machine
|
|
void State_Transition( DODRoundState newState );
|
|
void State_Enter( DODRoundState newState ); // Initialize the new state.
|
|
void State_Leave(); // Cleanup the previous state.
|
|
void State_Think(); // Update the current state.
|
|
|
|
CDODRoundStateInfo *m_pCurStateInfo; //Fn ptrs for the current state
|
|
float m_flStateTransitionTime; //Timer for round states
|
|
|
|
// Find the state info for the specified state.
|
|
static CDODRoundStateInfo* State_LookupInfo( DODRoundState state );
|
|
|
|
//State Functions
|
|
void State_Enter_INIT( void );
|
|
void State_Think_INIT( void );
|
|
|
|
void State_Enter_PREGAME( void );
|
|
void State_Think_PREGAME( void );
|
|
|
|
void State_Enter_STARTGAME( void );
|
|
void State_Think_STARTGAME( void );
|
|
|
|
void State_Enter_PREROUND( void );
|
|
void State_Think_PREROUND( void );
|
|
|
|
void State_Enter_RND_RUNNING( void );
|
|
void State_Think_RND_RUNNING( void );
|
|
|
|
void State_Enter_ALLIES_WIN( void );
|
|
void State_Think_ALLIES_WIN( void );
|
|
|
|
void State_Enter_AXIS_WIN( void );
|
|
void State_Think_AXIS_WIN( void );
|
|
|
|
void State_Enter_RESTART( void );
|
|
void State_Think_RESTART( void );
|
|
|
|
void SetInWarmup( bool bWarmup );
|
|
void CheckWarmup( void );
|
|
void CheckRestartRound( void );
|
|
void CheckRespawnWaves( void );
|
|
|
|
void InitTeams( void );
|
|
|
|
void RoundRespawn( void );
|
|
void CleanUpMap( void );
|
|
void ResetScores( void );
|
|
|
|
// Respawn everyone regardless of state - round reset
|
|
inline void RespawnAllPlayers( void ) { RespawnPlayers( true ); }
|
|
|
|
// Respawn only one team, players that are ready to spawn - wave reset
|
|
inline void RespawnTeam( int iTeam ) { RespawnPlayers( false, true, iTeam ); }
|
|
|
|
void RespawnPlayers( bool bForceRespawn, bool bTeam = false, int iTeam = TEAM_UNASSIGNED );
|
|
|
|
void FailSafeSpawnPlayersOnTeam( int iTeam );
|
|
|
|
bool IsPlayerClassOnTeam( int cls, int team );
|
|
bool CanPlayerJoinClass( CDODPlayer *pPlayer, int cls );
|
|
void ChooseRandomClass( CDODPlayer *pPlayer );
|
|
bool ReachedClassLimit( int team, int cls );
|
|
int CountPlayerClass( int team, int cls );
|
|
int GetClassLimit( int team, int cls );
|
|
|
|
int CountActivePlayers( void ); //How many players have chosen a team?
|
|
|
|
void SetWinningTeam( int team );
|
|
void PlayWinSong( int team );
|
|
void PlayStartRoundVoice( void );
|
|
void BroadcastSound( const char *sound );
|
|
void PlaySpawnSoundToTeam( const char *sound, int team );
|
|
|
|
int SelectDefaultTeam( void );
|
|
|
|
void CopyGamePlayLogic( const CDODGamePlayRules otherGamePlay );
|
|
|
|
|
|
void DeathNotice( CBasePlayer *pVictim, const CTakeDamageInfo &info );
|
|
|
|
virtual bool CanHavePlayerItem( CBasePlayer *pPlayer, CBaseCombatWeapon *pWeapon );
|
|
|
|
bool TeamFull( int team_id );
|
|
bool TeamStacked( int iNewTeam, int iCurTeam );
|
|
|
|
const char *GetPlayerClassName( int cls, int team );
|
|
|
|
virtual void ClientSettingsChanged( CBasePlayer *pPlayer );
|
|
|
|
void CheckChatForReadySignal( CDODPlayer *pPlayer, const char *chatmsg );
|
|
bool AreAlliesReady( void ) { return m_bHeardAlliesReady; }
|
|
bool AreAxisReady( void ) { return m_bHeardAxisReady; }
|
|
|
|
void CreateOrJoinRespawnWave( CDODPlayer *pPlayer );
|
|
|
|
virtual bool InRoundRestart( void );
|
|
|
|
void SendTeamScoresEvent( void );
|
|
|
|
void WriteStatsFile( const char *pszLogName );
|
|
|
|
void AddTimerSeconds( int iSecondsToAdd );
|
|
int GetTimerSeconds( void );
|
|
|
|
void CapEvent( int event, int team );
|
|
int m_iLastAlliesCapEvent;
|
|
int m_iLastAxisCapEvent;
|
|
|
|
// Set the time at which the map was reset to 'now'
|
|
// and send an event with the time remaining until map change
|
|
void ResetMapTime( void );
|
|
|
|
virtual CBaseCombatWeapon *GetNextBestWeapon( CBaseCombatCharacter *pPlayer, CBaseCombatWeapon *pCurrentWeapon );
|
|
|
|
virtual bool CanEntityBeUsePushed( CBaseEntity *pEnt );
|
|
|
|
virtual void CalcDominationAndRevenge( CDODPlayer *pAttacker, CDODPlayer *pVictim, int *piDeathFlags );
|
|
|
|
float m_flNextFailSafeWaveCheckTime;
|
|
|
|
CUtlVector<EHANDLE> *GetSpawnPointListForTeam( int iTeam );
|
|
|
|
virtual void GetTaggedConVarList( KeyValues *pCvarTagList );
|
|
|
|
protected:
|
|
virtual void GoToIntermission( void );
|
|
virtual bool UseSuicidePenalty() { return false; }
|
|
|
|
void CheckPlayerPositions( void );
|
|
|
|
private:
|
|
bool CheckTimeLimit( void );
|
|
bool CheckWinLimit( void );
|
|
|
|
void RadiusDamage( const CTakeDamageInfo &info, const Vector &vecSrcIn, float flRadius, int iClassIgnore, bool bIgnoreWorld );
|
|
float GetExplosionDamageAdjustment(Vector & vecSrc, Vector & vecEnd, CBaseEntity *pTarget, CBaseEntity *pEntityToIgnore); // returns multiplier between 0.0 and 1.0 that is the percentage of any damage done from vecSrc to vecEnd that actually makes it.
|
|
float GetAmountOfEntityVisible(Vector & src, CBaseEntity *pTarget, CBaseEntity *pEntityToIgnore); // returns a value from 0 to 1 that is the percentage of player visible from src.
|
|
|
|
void CheckLevelInitialized( void );
|
|
bool m_bLevelInitialized;
|
|
|
|
int m_iSpawnPointCount_Allies; //number of allies spawns on the map
|
|
int m_iSpawnPointCount_Axis; //number of axis spawns on the map
|
|
|
|
#define MAX_PLAYERCLASSES_PER_TEAM 16
|
|
|
|
PLAYERCLASS_FILE_INFO_HANDLE m_hPlayerClassInfoHandles[2][MAX_PLAYERCLASSES_PER_TEAM];
|
|
|
|
// restart and warmup variables
|
|
float m_flWarmupTimeEnds;
|
|
float m_flNextPeriodicThink;
|
|
|
|
Vector2D m_vecPlayerPositions[MAX_PLAYERS];
|
|
|
|
|
|
//BELOW HERE NEED TO BE HOOKED UP
|
|
|
|
|
|
int m_iNumAlliesAlive; //the number of players alive on each team
|
|
int m_iNumAxisAlive;
|
|
int m_iNumAlliesOnTeam; //the number of players on each team
|
|
int m_iNumAxisOnTeam;
|
|
|
|
bool m_bClanMatch;
|
|
bool m_bClanMatchActive;
|
|
|
|
float GetMaxWaveTime( int iTeam );
|
|
float GetWaveTime( int iTeam );
|
|
void AddWaveTime( int team, float flTime );
|
|
void PopWaveTime( int team );
|
|
|
|
void DetectGameRules( void );
|
|
|
|
bool m_bHeardAlliesReady;
|
|
bool m_bHeardAxisReady;
|
|
|
|
bool m_bUsingTimer;
|
|
int m_iTimerWinTeam;
|
|
CHandle< CDODRoundTimer > m_pRoundTimer;
|
|
|
|
bool m_bPlayTimerWarning_1Minute;
|
|
bool m_bPlayTimerWarning_2Minute;
|
|
|
|
bool m_bInitialSpawn; // first time activating? longer wait time for people to join
|
|
|
|
bool m_bChangeLevelOnRoundEnd;
|
|
|
|
#endif //CLIENT_DLL
|
|
|
|
CNetworkVarEmbedded( CDODGamePlayRules, m_GamePlayRules );
|
|
|
|
CNetworkVar( DODRoundState, m_iRoundState );
|
|
|
|
#define DOD_RESPAWN_QUEUE_SIZE 10
|
|
|
|
CNetworkArray( float, m_AlliesRespawnQueue, DOD_RESPAWN_QUEUE_SIZE );
|
|
CNetworkArray( float, m_AxisRespawnQueue, DOD_RESPAWN_QUEUE_SIZE );
|
|
|
|
CNetworkVar( int, m_iAlliesRespawnHead );
|
|
CNetworkVar( int, m_iAlliesRespawnTail );
|
|
|
|
CNetworkVar( int, m_iAxisRespawnHead );
|
|
CNetworkVar( int, m_iAxisRespawnTail );
|
|
|
|
int m_iNumAlliesRespawnWaves;
|
|
int m_iNumAxisRespawnWaves;
|
|
|
|
CNetworkVar( bool, m_bInWarmup );
|
|
CNetworkVar( bool, m_bAwaitingReadyRestart );
|
|
CNetworkVar( float, m_flRestartRoundTime );
|
|
CNetworkVar( float, m_flMapResetTime ); // time that the map was reset
|
|
|
|
CNetworkVar( bool, m_bAlliesAreBombing );
|
|
CNetworkVar( bool, m_bAxisAreBombing );
|
|
|
|
#ifndef CLIENT_DLL
|
|
public:
|
|
// Stats
|
|
void Stats_PlayerKill( int team, int cls );
|
|
void Stats_PlayerCap( int team, int cls );
|
|
void Stats_PlayerDefended( int team, int cls );
|
|
void Stats_WeaponFired( int weaponID );
|
|
void Stats_WeaponHit( int weaponID, float flDist );
|
|
int Stats_WeaponDistanceToBucket( int weaponID, float flDist );
|
|
|
|
float m_flSecondsPlayedPerClass_Allies[7];
|
|
float m_flSecondsPlayedPerClass_Axis[7];
|
|
|
|
int m_iStatsKillsPerClass_Allies[6];
|
|
int m_iStatsKillsPerClass_Axis[6];
|
|
|
|
int m_iStatsSpawnsPerClass_Allies[6];
|
|
int m_iStatsSpawnsPerClass_Axis[6];
|
|
|
|
int m_iStatsCapsPerClass_Allies[6];
|
|
int m_iStatsCapsPerClass_Axis[6];
|
|
|
|
int m_iStatsDefensesPerClass_Allies[6];
|
|
int m_iStatsDefensesPerClass_Axis[6];
|
|
|
|
int m_iWeaponShotsFired[WEAPON_MAX];
|
|
int m_iWeaponShotsHit[WEAPON_MAX];
|
|
int m_iWeaponDistanceBuckets[WEAPON_MAX][DOD_NUM_WEAPON_DISTANCE_BUCKETS]; // distances of buckets are defined per-weapon
|
|
|
|
// List of spawn points
|
|
CUtlVector<EHANDLE> m_AlliesSpawnPoints;
|
|
CUtlVector<EHANDLE> m_AxisSpawnPoints;
|
|
|
|
bool m_bWinterHolidayActive;
|
|
|
|
#endif // ndef CLIENTDLL
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Gets us at the team fortress game rules
|
|
//-----------------------------------------------------------------------------
|
|
|
|
inline CDODGameRules* DODGameRules()
|
|
{
|
|
return static_cast<CDODGameRules*>(g_pGameRules);
|
|
}
|
|
|
|
#ifdef CLIENT_DLL
|
|
|
|
#else
|
|
bool EntityPlacementTest( CBaseEntity *pMainEnt, const Vector &vOrigin, Vector &outPos, bool bDropToGround );
|
|
#endif //CLIENT_DLL
|
|
|
|
|
|
#endif // DOD_GAMERULES_H
|