This repository has been archived on 2024-06-13. You can view files and clone it, but cannot push or open issues or pull requests.
2020-08-04 13:13:01 -04:00

565 lines
20 KiB
C++

//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef GAMERULES_H
#define GAMERULES_H
#ifdef _WIN32
#pragma once
#endif
// Debug history should be disabled in release builds
//#define DISABLE_DEBUG_HISTORY
#ifdef CLIENT_DLL
#include "c_baseentity.h"
#define CGameRules C_GameRules
#define CGameRulesProxy C_GameRulesProxy
#else
#include "baseentity.h"
#include "recipientfilter.h"
#endif
#include "gamerules_register.h"
#include "igamesystem.h"
//#include "items.h"
class CBaseCombatWeapon;
class CBaseCombatCharacter;
class CBasePlayer;
class CItem;
class CAmmoDef;
class CTacticalMissionManager;
extern ConVar sk_autoaim_mode;
// Autoaiming modes
enum {
AUTOAIM_NONE = 0, // No autoaim at all.
AUTOAIM_ON, // Autoaim is on.
AUTOAIM_ON_CONSOLE, // Autoaim is on, including enhanced features for
// Console gaming (more assistance, etc)
};
// weapon respawning return codes
enum {
GR_NONE = 0,
GR_WEAPON_RESPAWN_YES,
GR_WEAPON_RESPAWN_NO,
GR_AMMO_RESPAWN_YES,
GR_AMMO_RESPAWN_NO,
GR_ITEM_RESPAWN_YES,
GR_ITEM_RESPAWN_NO,
GR_PLR_DROP_GUN_ALL,
GR_PLR_DROP_GUN_ACTIVE,
GR_PLR_DROP_GUN_NO,
GR_PLR_DROP_AMMO_ALL,
GR_PLR_DROP_AMMO_ACTIVE,
GR_PLR_DROP_AMMO_NO,
};
// Player relationship return codes
enum {
GR_NOTTEAMMATE = 0,
GR_TEAMMATE,
GR_ENEMY,
GR_ALLY,
GR_NEUTRAL,
};
// This class has the data tables and gets the CGameRules data to the client.
class CGameRulesProxy : public CBaseEntity {
public:
DECLARE_CLASS(CGameRulesProxy, CBaseEntity);
DECLARE_NETWORKCLASS();
CGameRulesProxy();
~CGameRulesProxy();
// UNDONE: Is this correct, Mike?
// Don't carry these across a transition, they are recreated.
virtual int ObjectCaps(void) {
return BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION;
}
// ALWAYS transmit to all clients.
virtual int UpdateTransmitState(void);
// CGameRules chains its NetworkStateChanged calls to here, since this
// is the actual entity that will send the data.
static void NotifyNetworkStateChanged();
private:
static CGameRulesProxy *s_pGameRulesProxy;
};
abstract_class CGameRules : public CAutoGameSystemPerFrame {
public:
DECLARE_CLASS_GAMEROOT(CGameRules, CAutoGameSystemPerFrame);
virtual char const *Name() { return "CGameRules"; }
// Stuff shared between client and server.
CGameRules(void);
virtual ~CGameRules(void);
// Damage Queries - these need to be implemented by the various subclasses
// (single-player, multi-player, etc). The queries represent queries against
// damage types and properties.
virtual bool Damage_IsTimeBased(
int iDmgType) = 0; // Damage types that are time-based.
virtual bool Damage_ShouldGibCorpse(
int iDmgType) = 0; // Damage types that gib the corpse.
virtual bool Damage_ShowOnHUD(
int iDmgType) = 0; // Damage types that have client HUD art.
virtual bool Damage_NoPhysicsForce(
int iDmgType) = 0; // Damage types that don't have to supply a physics
// force & position.
virtual bool Damage_ShouldNotBleed(
int iDmgType) = 0; // Damage types that don't make the player bleed.
// Temp: These will go away once DamageTypes become enums.
virtual int Damage_GetTimeBased(void) = 0; // Actual bit-fields.
virtual int Damage_GetShouldGibCorpse(void) = 0;
virtual int Damage_GetShowOnHud(void) = 0;
virtual int Damage_GetNoPhysicsForce(void) = 0;
virtual int Damage_GetShouldNotBleed(void) = 0;
// Ammo Definitions
// CAmmoDef* GetAmmoDef();
virtual bool SwitchToNextBestWeapon(
CBaseCombatCharacter * pPlayer,
CBaseCombatWeapon * pCurrentWeapon); // Switch to the next best weapon
virtual CBaseCombatWeapon *GetNextBestWeapon(
CBaseCombatCharacter * pPlayer,
CBaseCombatWeapon *
pCurrentWeapon); // I can't use this weapon anymore, get me the
// next best one.
virtual bool ShouldCollide(int collisionGroup0, int collisionGroup1);
virtual int DefaultFOV(void) { return 90; }
// This function is here for our CNetworkVars.
inline void NetworkStateChanged() {
// Forward the call to the entity that will send the data.
CGameRulesProxy::NotifyNetworkStateChanged();
}
inline void NetworkStateChanged(void *pVar) {
// Forward the call to the entity that will send the data.
CGameRulesProxy::NotifyNetworkStateChanged();
}
// Get the view vectors for this mod.
virtual const CViewVectors *GetViewVectors() const;
// Damage rules for ammo types
virtual float GetAmmoDamage(CBaseEntity * pAttacker, CBaseEntity * pVictim,
int nAmmoType);
virtual float GetDamageMultiplier(void) { return 1.0f; }
// Functions to verify the single/multiplayer status of a game
virtual bool IsMultiplayer(
void) = 0; // is this a multiplayer game? (either coop or deathmatch)
virtual const unsigned char *GetEncryptionKey() { return NULL; }
virtual bool InRoundRestart(void) { return false; }
// Allow thirdperson camera.
virtual bool AllowThirdPersonCamera(void) { return false; }
virtual void ClientCommandKeyValues(edict_t * pEntity,
KeyValues * pKeyValues) {}
// IsConnectedUserInfoChangeAllowed allows the clients to change
// cvars with the FCVAR_NOT_CONNECTED rule if it returns true
virtual bool IsConnectedUserInfoChangeAllowed(CBasePlayer * pPlayer) {
Assert(!IsMultiplayer());
return true;
}
#ifdef CLIENT_DLL
virtual bool IsBonusChallengeTimeBased(void);
virtual bool AllowMapParticleEffect(const char *pszParticleEffect) {
return true;
}
virtual bool AllowWeatherParticles(void) { return true; }
virtual bool AllowMapVisionFilterShaders(void) { return false; }
virtual const char *TranslateEffectForVisionFilter(
const char *pchEffectType, const char *pchEffectName) {
return pchEffectName;
}
virtual bool IsLocalPlayer(int nEntIndex);
virtual void ModifySentChat(char *pBuf, int iBufSize) { return; }
virtual bool ShouldWarnOfAbandonOnQuit() { return false; }
#else
virtual void Status(void (*print)(const char *fmt, ...)) {}
virtual void GetTaggedConVarList(KeyValues * pCvarTagList) {}
// NVNT see if the client of the player entered is using a haptic device.
virtual void CheckHaptics(CBasePlayer * pPlayer);
// CBaseEntity overrides.
public:
// Setup
// Called when game rules are destroyed by CWorld
virtual void LevelShutdown(void) { return; };
virtual void Precache(void) { return; };
virtual void RefreshSkillData(
bool forceUpdate); // fill skill data struct with proper values
// Called each frame. This just forwards the call to Think().
virtual void FrameUpdatePostEntityThink();
virtual void Think(
void) = 0; // GR_Think - runs every server frame, should handle any
// timer tasks, periodic events, etc.
virtual bool IsAllowedToSpawn(CBaseEntity *
pEntity) = 0; // Can this item spawn (eg NPCs
// don't spawn in deathmatch).
// Called at the end of GameFrame (i.e. after all game logic has run this
// frame)
virtual void EndGameFrame(void);
virtual bool IsSkillLevel(int iLevel) { return GetSkillLevel() == iLevel; }
virtual int GetSkillLevel() { return g_iSkillLevel; }
virtual void OnSkillLevelChanged(int iNewLevel){};
virtual void SetSkillLevel(int iLevel) {
int oldLevel = g_iSkillLevel;
if (iLevel < 1) {
iLevel = 1;
} else if (iLevel > 3) {
iLevel = 3;
}
g_iSkillLevel = iLevel;
if (g_iSkillLevel != oldLevel) {
OnSkillLevelChanged(g_iSkillLevel);
}
}
virtual bool FAllowFlashlight(
void) = 0; // Are players allowed to switch on their flashlight?
virtual bool FShouldSwitchWeapon(
CBasePlayer * pPlayer,
CBaseCombatWeapon *
pWeapon) = 0; // should the player switch to this weapon?
// Functions to verify the single/multiplayer status of a game
virtual bool IsDeathmatch(void) = 0; // is this a deathmatch game?
virtual bool IsTeamplay(void) {
return FALSE;
}; // is this deathmatch game being played with team rules?
virtual bool IsCoOp(void) = 0; // is this a coop game?
virtual const char *GetGameDescription(void) {
return "Half-Life 2";
} // this is the game name that gets seen in the server browser
// Client connection/disconnection
virtual bool ClientConnected(
edict_t * pEntity, const char *pszName, const char *pszAddress,
char *reject,
int maxrejectlen) = 0; // a client just connected to the server (player
// hasn't spawned yet)
virtual void InitHUD(CBasePlayer *
pl) = 0; // the client dll is ready for updating
virtual void ClientDisconnected(
edict_t * pClient) = 0; // a client just disconnected from the server
// Client damage rules
virtual float FlPlayerFallDamage(
CBasePlayer * pPlayer) = 0; // this client just hit the ground after a
// fall. How much damage?
virtual bool FPlayerCanTakeDamage(CBasePlayer * pPlayer,
CBaseEntity * pAttacker,
const CTakeDamageInfo &info) {
return TRUE;
}; // can this player take damage from this attacker?
virtual bool ShouldAutoAim(CBasePlayer * pPlayer, edict_t * target) {
return TRUE;
}
virtual float GetAutoAimScale(CBasePlayer * pPlayer) { return 1.0f; }
virtual int GetAutoAimMode() { return AUTOAIM_ON; }
virtual bool ShouldUseRobustRadiusDamage(CBaseEntity * pEntity) {
return false;
}
virtual void RadiusDamage(const CTakeDamageInfo &info, const Vector &vecSrc,
float flRadius, int iClassIgnore,
CBaseEntity *pEntityIgnore);
// Let the game rules specify if fall death should fade screen to black
virtual bool FlPlayerFallDeathDoesScreenFade(CBasePlayer * pl) {
return TRUE;
}
virtual bool AllowDamage(CBaseEntity * pVictim,
const CTakeDamageInfo &info) = 0;
// Client spawn/respawn control
virtual void PlayerSpawn(
CBasePlayer * pPlayer) = 0; // called by CBasePlayer::Spawn just before
// releasing player into the game
virtual void PlayerThink(
CBasePlayer *
pPlayer) = 0; // called by CBasePlayer::PreThink every frame, before
// physics are run and after keys are accepted
virtual bool FPlayerCanRespawn(
CBasePlayer * pPlayer) = 0; // is this player allowed to respawn now?
virtual float FlPlayerSpawnTime(
CBasePlayer *
pPlayer) = 0; // When in the future will this player be able to spawn?
virtual CBaseEntity *GetPlayerSpawnSpot(
CBasePlayer * pPlayer); // Place this player on their spawnspot and
// face them the proper direction.
virtual bool IsSpawnPointValid(CBaseEntity * pSpot, CBasePlayer * pPlayer);
virtual bool AllowAutoTargetCrosshair(void) { return TRUE; };
virtual bool ClientCommand(
CBaseEntity * pEdict,
const CCommand &args); // handles the user commands; returns TRUE if
// command handled properly
virtual void ClientSettingsChanged(
CBasePlayer * pPlayer); // the player has changed cvars
// Client kills/scoring
virtual int IPointsForKill(
CBasePlayer * pAttacker,
CBasePlayer * pKilled) = 0; // how many points do I award whoever kills
// this player?
virtual void PlayerKilled(
CBasePlayer * pVictim,
const CTakeDamageInfo &info) = 0; // Called each time a player dies
virtual void DeathNotice(
CBasePlayer * pVictim,
const CTakeDamageInfo &info) = 0; // Call this from within a GameRules
// class to report an obituary.
virtual const char *GetDamageCustomString(const CTakeDamageInfo &info) {
return NULL;
}
// Weapon Damage
// Determines how much damage Player's attacks inflict, based on skill
// level.
virtual float AdjustPlayerDamageInflicted(float damage) { return damage; }
virtual void AdjustPlayerDamageTaken(CTakeDamageInfo *
pInfo){}; // Base class does nothing.
// Weapon retrieval
virtual bool CanHavePlayerItem(
CBasePlayer * pPlayer,
CBaseCombatWeapon *
pWeapon); // The player is touching an CBaseCombatWeapon, do I give
// it to him?
// Weapon spawn/respawn control
virtual int WeaponShouldRespawn(
CBaseCombatWeapon * pWeapon) = 0; // should this weapon respawn?
virtual float FlWeaponRespawnTime(
CBaseCombatWeapon * pWeapon) = 0; // when may this weapon respawn?
virtual float FlWeaponTryRespawn(
CBaseCombatWeapon * pWeapon) = 0; // can i respawn now, and if not,
// when should i try again?
virtual Vector VecWeaponRespawnSpot(
CBaseCombatWeapon *
pWeapon) = 0; // where in the world should this weapon respawn?
// Item retrieval
virtual bool CanHaveItem(
CBasePlayer * pPlayer,
CItem * pItem) = 0; // is this player allowed to take this item?
virtual void PlayerGotItem(
CBasePlayer * pPlayer,
CItem * pItem) = 0; // call each time a player picks up an item
// (battery, healthkit)
// Item spawn/respawn control
virtual int ItemShouldRespawn(CItem *
pItem) = 0; // Should this item respawn?
virtual float FlItemRespawnTime(CItem *
pItem) = 0; // when may this item respawn?
virtual Vector VecItemRespawnSpot(
CItem * pItem) = 0; // where in the world should this item respawn?
virtual QAngle VecItemRespawnAngles(
CItem * pItem) = 0; // what angles should this item use when respawing?
// Ammo retrieval
virtual bool CanHaveAmmo(
CBaseCombatCharacter * pPlayer,
int iAmmoIndex); // can this player take more of this ammo?
virtual bool CanHaveAmmo(CBaseCombatCharacter * pPlayer,
const char *szName);
virtual void PlayerGotAmmo(
CBaseCombatCharacter * pPlayer, char *szName,
int iCount) = 0; // called each time a player picks up some ammo in the
// world
virtual float GetAmmoQuantityScale(int iAmmoIndex) { return 1.0f; }
// AI Definitions
virtual void InitDefaultAIRelationships(void) { return; }
virtual const char *AIClassText(int classType) { return NULL; }
// Healthcharger respawn control
virtual float FlHealthChargerRechargeTime(
void) = 0; // how long until a depleted HealthCharger recharges itself?
virtual float FlHEVChargerRechargeTime(void) {
return 0;
} // how long until a depleted HealthCharger recharges itself?
// What happens to a dead player's weapons
virtual int DeadPlayerWeapons(
CBasePlayer *
pPlayer) = 0; // what do I do with a player's weapons when he's killed?
// What happens to a dead player's ammo
virtual int DeadPlayerAmmo(
CBasePlayer *
pPlayer) = 0; // Do I drop ammo when the player dies? How much?
// Teamplay stuff
virtual const char *GetTeamID(CBaseEntity *
pEntity) = 0; // what team is this entity on?
virtual int PlayerRelationship(
CBaseEntity * pPlayer,
CBaseEntity * pTarget) = 0; // What is the player's relationship with
// this entity?
virtual bool PlayerCanHearChat(CBasePlayer * pListener,
CBasePlayer * pSpeaker) = 0;
virtual void CheckChatText(CBasePlayer * pPlayer, char *pText) { return; }
virtual int GetTeamIndex(const char *pTeamName) { return -1; }
virtual const char *GetIndexedTeamName(int teamIndex) { return ""; }
virtual bool IsValidTeam(const char *pTeamName) { return true; }
virtual void ChangePlayerTeam(CBasePlayer * pPlayer, const char *pTeamName,
bool bKill, bool bGib) {}
virtual const char *SetDefaultPlayerTeam(CBasePlayer * pPlayer) {
return "";
}
virtual void UpdateClientData(CBasePlayer * pPlayer){};
// Sounds
virtual bool PlayTextureSounds(void) { return TRUE; }
virtual bool PlayFootstepSounds(CBasePlayer * pl) { return TRUE; }
// NPCs
virtual bool FAllowNPCs(void) = 0; // are NPCs allowed
// Immediately end a multiplayer game
virtual void EndMultiplayerGame(void) {}
// trace line rules
virtual float WeaponTraceEntity(
CBaseEntity * pEntity, const Vector &vecStart, const Vector &vecEnd,
unsigned int mask, trace_t *ptr);
// Setup g_pPlayerResource (some mods use a different entity type here).
virtual void CreateStandardEntities();
// Team name, etc shown in chat and dedicated server console
virtual const char *GetChatPrefix(bool bTeamOnly, CBasePlayer *pPlayer);
// Location name shown in chat
virtual const char *GetChatLocation(bool bTeamOnly, CBasePlayer *pPlayer) {
return NULL;
}
// VGUI format string for chat, if desired
virtual const char *GetChatFormat(bool bTeamOnly, CBasePlayer *pPlayer) {
return NULL;
}
// Whether props that are on fire should get a DLIGHT.
virtual bool ShouldBurningPropsEmitLight() { return false; }
virtual bool CanEntityBeUsePushed(CBaseEntity * pEnt) { return true; }
virtual void CreateCustomNetworkStringTables(void) {}
// Game Achievements (server version)
virtual void MarkAchievement(IRecipientFilter & filter,
char const *pchAchievementName);
virtual void ResetMapCycleTimeStamp(void) { return; }
virtual void OnNavMeshLoad(void) { return; }
// game-specific factories
virtual CTacticalMissionManager *TacticalMissionManagerFactory(void);
virtual void ProcessVerboseLogOutput(void) {}
#endif
virtual const char *GetGameTypeName(void) { return NULL; }
virtual int GetGameType(void) { return 0; }
virtual bool ShouldDrawHeadLabels() { return true; }
virtual void ClientSpawned(edict_t * pPlayer) { return; }
virtual void OnFileReceived(const char *fileName, unsigned int transferID) {
return;
}
virtual bool IsHolidayActive(/*EHoliday*/ int eHoliday) const {
return false;
}
virtual bool IsManualMapChangeOkay(const char **pszReason) { return true; }
#ifndef CLIENT_DLL
private:
float m_flNextVerboseLogOutput;
#endif // CLIENT_DLL
};
#ifndef CLIENT_DLL
void InstallGameRules();
// Create user messages for game here, calls into static player class creation
// functions
void RegisterUserMessages(void);
#endif
extern ConVar g_Language;
//-----------------------------------------------------------------------------
// Gets us at the game rules
//-----------------------------------------------------------------------------
extern CGameRules *g_pGameRules;
inline CGameRules *GameRules() { return g_pGameRules; }
#endif // GAMERULES_H