source-engine/game/shared/dod/dod_gamerules.h
2022-04-16 12:05:19 +03:00

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