565 lines
20 KiB
C++
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
|