hlsdk-xash3d/dlls/player.h

671 lines
20 KiB
C++

/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
* Use, distribution, and modification of this source code and/or resulting
* object code is restricted to non-commercial enhancements to products from
* Valve LLC. All other use, distribution, or modification is prohibited
* without written permission from Valve LLC.
*
****/
#pragma once
#if !defined(PLAYER_H)
#define PLAYER_H
#include "pm_materials.h"
//++ BulliT
#include "items.h"
#include "gamerules.h"
#include "agglobal.h"
#include "agclient.h"
extern int gmsgSpectator;
//-- Martin Webrant
#define PLAYER_FATAL_FALL_SPEED 1024// approx 60 feet
#define PLAYER_MAX_SAFE_FALL_SPEED 580// approx 20 feet
#define DAMAGE_FOR_FALL_SPEED (float) 100 / ( PLAYER_FATAL_FALL_SPEED - PLAYER_MAX_SAFE_FALL_SPEED )// damage per unit per second.
#define PLAYER_MIN_BOUNCE_SPEED 200
#define PLAYER_FALL_PUNCH_THRESHHOLD (float)350 // won't punch player's screen/make scrape noise unless player falling at least this fast.
//
// Player PHYSICS FLAGS bits
//
#define PFLAG_ONLADDER ( 1<<0 )
#define PFLAG_ONSWING ( 1<<0 )
#define PFLAG_ONTRAIN ( 1<<1 )
#define PFLAG_ONBARNACLE ( 1<<2 )
#define PFLAG_DUCKING ( 1<<3 ) // In the process of ducking, but totally squatted yet
#define PFLAG_USING ( 1<<4 ) // Using a continuous entity
#define PFLAG_OBSERVER ( 1<<5 ) // player is locked in stationary cam mode. Spectators can move, observers can't.
//
// generic player
//
//-----------------------------------------------------
//This is Half-Life player entity
//-----------------------------------------------------
#define CSUITPLAYLIST 4 // max of 4 suit sentences queued up at any time
#define SUIT_GROUP TRUE
#define SUIT_SENTENCE FALSE
#define SUIT_REPEAT_OK 0
#define SUIT_NEXT_IN_30SEC 30
#define SUIT_NEXT_IN_1MIN 60
#define SUIT_NEXT_IN_5MIN 300
#define SUIT_NEXT_IN_10MIN 600
#define SUIT_NEXT_IN_30MIN 1800
#define SUIT_NEXT_IN_1HOUR 3600
#define CSUITNOREPEAT 32
#define SOUND_FLASHLIGHT_ON "items/flashlight1.wav"
#define SOUND_FLASHLIGHT_OFF "items/flashlight1.wav"
#define TEAM_NAME_LENGTH 16
typedef enum
{
PLAYER_IDLE,
PLAYER_WALK,
PLAYER_JUMP,
PLAYER_SUPERJUMP,
PLAYER_DIE,
PLAYER_ATTACK1
} PLAYER_ANIM;
#define MAX_ID_RANGE 2048
#define SBAR_STRING_SIZE 128
enum sbar_data
{
SBAR_ID_TARGETNAME = 1,
SBAR_ID_TARGETHEALTH,
SBAR_ID_TARGETARMOR,
SBAR_END
};
#define CHAT_INTERVAL 1.0f
class CBasePlayer : public CBaseMonster
{
public:
// Spectator camera
void Observer_FindNextPlayer( bool bReverse );
void Observer_HandleButtons();
void Observer_SetMode( int iMode );
void Observer_CheckTarget();
void Observer_CheckProperties();
EHANDLE m_hObserverTarget;
float m_flNextObserverInput;
int m_iObserverWeapon; // weapon of current tracked target
int m_iObserverLastMode;// last used observer mode
int IsObserver() { return pev->iuser1; };
int random_seed; // See that is shared between client & server for shared weapons code
int m_iPlayerSound;// the index of the sound list slot reserved for this player
int m_iTargetVolume;// ideal sound volume.
int m_iWeaponVolume;// how loud the player's weapon is right now.
int m_iExtraSoundTypes;// additional classification for this weapon's sound
int m_iWeaponFlash;// brightness of the weapon flash
float m_flStopExtraSoundTime;
float m_flFlashLightTime; // Time until next battery draw/Recharge
int m_iFlashBattery; // Flashlight Battery Draw
int m_afButtonLast;
int m_afButtonPressed;
int m_afButtonReleased;
edict_t *m_pentSndLast; // last sound entity to modify player room type
float m_flSndRoomtype; // last roomtype set by sound entity
float m_flSndRange; // dist from player to sound entity
float m_flFallVelocity;
int m_rgItems[MAX_ITEMS];
int m_fKnownItem; // True when a new item needs to be added
int m_fNewAmmo; // True when a new item has been added
unsigned int m_afPhysicsFlags; // physics flags - set when 'normal' physics should be revisited or overriden
float m_fNextSuicideTime; // the time after which the player can next use the suicide command
// these are time-sensitive things that we keep track of
float m_flTimeStepSound; // when the last stepping sound was made
float m_flTimeWeaponIdle; // when to play another weapon idle animation.
float m_flSwimTime; // how long player has been underwater
float m_flDuckTime; // how long we've been ducking
float m_flWallJumpTime; // how long until next walljump
float m_flSuitUpdate; // when to play next suit update
int m_rgSuitPlayList[CSUITPLAYLIST];// next sentencenum to play for suit update
int m_iSuitPlayNext; // next sentence slot for queue storage;
int m_rgiSuitNoRepeat[CSUITNOREPEAT]; // suit sentence no repeat list
float m_rgflSuitNoRepeatTime[CSUITNOREPEAT]; // how long to wait before allowing repeat
int m_lastDamageAmount; // Last damage taken
float m_tbdPrev; // Time-based damage timer
float m_flgeigerRange; // range to nearest radiation source
float m_flgeigerDelay; // delay per update of range msg to client
int m_igeigerRangePrev;
int m_iStepLeft; // alternate left/right foot stepping sound
char m_szTextureName[CBTEXTURENAMEMAX]; // current texture name we're standing on
char m_chTextureType; // current texture type
int m_idrowndmg; // track drowning damage taken
int m_idrownrestored; // track drowning damage restored
int m_bitsHUDDamage; // Damage bits for the current fame. These get sent to
// the hude via the DAMAGE message
BOOL m_fInitHUD; // True when deferred HUD restart msg needs to be sent
BOOL m_fGameHUDInitialized;
int m_iTrain; // Train control position
BOOL m_fWeapon; // Set this to FALSE to force a reset of the current weapon HUD info
EHANDLE m_pTank; // the tank which the player is currently controlling, NULL if no tank
float m_fDeadTime; // the time at which the player died (used in PlayerDeathThink())
BOOL m_fNoPlayerSound; // a debugging feature. Player makes no sound if this is true.
BOOL m_fLongJump; // does this player have the longjump module?
float m_tSneaking;
int m_iUpdateTime; // stores the number of frame ticks before sending HUD update messages
int m_iClientHealth; // the health currently known by the client. If this changes, send a new
int m_iClientBattery; // the Battery currently known by the client. If this changes, send a new
int m_iHideHUD; // the players hud weapon info is to be hidden
int m_iClientHideHUD;
int m_iFOV; // field of view
int m_iClientFOV; // client's known FOV
// usable player items
CBasePlayerItem *m_rgpPlayerItems[MAX_ITEM_TYPES];
CBasePlayerItem *m_pActiveItem;
CBasePlayerItem *m_pClientActiveItem; // client version of the active item
CBasePlayerItem *m_pLastItem;
// shared ammo slots
int m_rgAmmo[MAX_AMMO_SLOTS];
int m_rgAmmoLast[MAX_AMMO_SLOTS];
Vector m_vecAutoAim;
BOOL m_fOnTarget;
int m_iDeaths;
float m_flRespawnTimer; // used in PlayerDeathThink() to make sure players can always respawn
int m_lastx, m_lasty; // These are the previous update's crosshair angles, DON"T SAVE/RESTORE
int m_nCustomSprayFrames;// Custom clan logo frames for this player
float m_flNextDecalTime;// next time this player can spray a decal
char m_szTeamName[TEAM_NAME_LENGTH];
virtual void Spawn( void );
void Pain( void );
//virtual void Think( void );
virtual void Jump( void );
virtual void Duck( void );
virtual void PreThink( void );
virtual void PostThink( void );
virtual Vector GetGunPosition( void );
virtual int TakeHealth( float flHealth, int bitsDamageType );
virtual void TraceAttack( entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType);
virtual int TakeDamage( entvars_t* pevInflictor, entvars_t* pevAttacker, float flDamage, int bitsDamageType);
virtual void Killed( entvars_t *pevAttacker, int iGib );
virtual Vector BodyTarget( const Vector &posSrc ) { return Center( ) + pev->view_ofs * RANDOM_FLOAT( 0.5, 1.1 ); }; // position to shoot at
virtual void StartSneaking( void ) { m_tSneaking = gpGlobals->time - 1; }
virtual void StopSneaking( void ) { m_tSneaking = gpGlobals->time + 30; }
virtual BOOL IsSneaking( void ) { return m_tSneaking <= gpGlobals->time; }
virtual BOOL IsAlive( void ) { return (pev->deadflag == DEAD_NO) && pev->health > 0; }
virtual BOOL ShouldFadeOnDeath( void ) { return FALSE; }
//++ BulliT
virtual BOOL IsPlayer( void ) { return !IsSpectator(); } // Spectators should return FALSE for this, they aren't "players" as far as game logic is concerned
//-- Martin Webrant
virtual BOOL IsNetClient( void ) { return TRUE; } // Bots should return FALSE for this, they can't receive NET messages
// Spectators should return TRUE for this
virtual const char *TeamID( void );
virtual int Save( CSave &save );
virtual int Restore( CRestore &restore );
void RenewItems(void);
void PackDeadPlayerItems( void );
void RemoveAllItems( BOOL removeSuit );
BOOL SwitchWeapon( CBasePlayerItem *pWeapon );
// JOHN: sends custom messages if player HUD data has changed (eg health, ammo)
virtual void UpdateClientData( void );
static TYPEDESCRIPTION m_playerSaveData[];
// Player is moved across the transition by other means
virtual int ObjectCaps( void ) { return CBaseMonster :: ObjectCaps() & ~FCAP_ACROSS_TRANSITION; }
virtual void Precache( void );
BOOL IsOnLadder( void );
BOOL FlashlightIsOn( void );
void FlashlightTurnOn( void );
void FlashlightTurnOff( void );
void UpdatePlayerSound ( void );
void DeathSound ( void );
int Classify ( void );
void SetAnimation( PLAYER_ANIM playerAnim );
void SetWeaponAnimType( const char *szExtention );
char m_szAnimExtention[32];
// custom player functions
virtual void ImpulseCommands( void );
void CheatImpulseCommands( int iImpulse );
void StartDeathCam( void );
void StartObserver( Vector vecPosition, Vector vecViewAngle );
void StopObserver();
void AddPoints( int score, BOOL bAllowNegativeScore );
void AddPointsToTeam( int score, BOOL bAllowNegativeScore );
BOOL AddPlayerItem( CBasePlayerItem *pItem );
BOOL RemovePlayerItem( CBasePlayerItem *pItem, bool bCallHoster );
void DropPlayerItem ( char *pszItemName );
BOOL HasPlayerItem( CBasePlayerItem *pCheckItem );
BOOL HasNamedPlayerItem( const char *pszItemName );
BOOL HasPlayerItemFromID( int nID );
BOOL HasWeapons( void );// do I have ANY weapons?
void SelectPrevItem( int iItem );
void SelectNextItem( int iItem );
void SelectLastItem(void);
void SelectItem(const char *pstr);
void ItemPreFrame( void );
void ItemPostFrame( void );
void GiveNamedItem( const char *szName );
void EnableControl(BOOL fControl);
int GiveAmmo( int iAmount, const char *szName, int iMax );
void SendAmmoUpdate(void);
void WaterMove( void );
void EXPORT PlayerDeathThink( void );
void PlayerUse( void );
void CheckSuitUpdate();
void SetSuitUpdate( const char *name, int fgroup, int iNoRepeat );
void UpdateGeigerCounter( void );
void CheckTimeBasedDamage( void );
BOOL FBecomeProne ( void );
void BarnacleVictimBitten ( entvars_t *pevBarnacle );
void BarnacleVictimReleased ( void );
static int GetAmmoIndex(const char *psz);
int AmmoInventory( int iAmmoIndex );
int Illumination( void );
void ResetAutoaim( void );
Vector GetAutoaimVector( float flDelta );
Vector AutoaimDeflection( Vector &vecSrc, float flDist, float flDelta );
void ForceClientDllUpdate( void ); // Forces all client .dll specific data to be resent to client.
void DeathMessage( entvars_t *pevKiller );
void SetCustomDecalFrames( int nFrames );
int GetCustomDecalFrames( void );
void TabulateAmmo( void );
float m_flStartCharge;
float m_flAmmoStartCharge;
float m_flPlayAftershock;
float m_flNextAmmoBurn;// while charging, when to absorb another unit of player's ammo?
// Player ID
void InitStatusBar( void );
void UpdateStatusBar( void );
int m_izSBarState[SBAR_END];
float m_flNextSBarUpdateTime;
float m_flStatusBarDisappearDelay;
char m_SbarString0[SBAR_STRING_SIZE];
char m_SbarString1[SBAR_STRING_SIZE];
void SetPrefsFromUserinfo( char *infobuffer );
float m_flNextChatTime;
//++ BulliT
protected:
bool m_bAdmin; //Player gained admin status.
bool m_bIngame; //Player was in the game when match started.
float m_fPlayerIdCheck; //Next time to check player id.
float m_fDisplayGamemode; //Next time to display gamemode.
float m_fLongjumpTimer; //Long jump timer.
Vector m_vKilled; //Where the player got killed last time.
double m_fFloodLockTill; //Flood protection: Locked from talking
double m_afFloodWhen[10]; //Flood protection: When messages were said
int m_iFloodWhenHead; //Flood protection: Head pointer for when said
double m_fPrevSoundFlood;
double m_fPrevTextFlood;
bool m_bSpawnFull; //Spawn with all weapons.
double m_fSpectateTime; //Dont flood the spectate functions.
int m_iSpectateWeapon;
int m_iSpectateAmmoClip;
int m_iSpot; //Info intermission spot.
bool m_bSentWallhackInfo;
//int m_iWeaponWeight[MAX_WEAPONS];
bool m_bInitLocation; //True to init location on client.
int m_iLastPlayerId;
float m_fNextPlayerId;
bool m_bSentCheatCheck;
public:
int m_iVote; //What player voted. -1 (not voted), 0 no, 1 yes.
bool m_bDoneFirstSpawn; //True if player has done the first spawn.
bool m_bInSpawn; //True if player is spawning.
bool m_bReady; //True if player is ready to enter lts/lms
int m_iNumTeams;
//Userinfo
int m_iDisableSpecs;
int m_iAutoWepSwitch;
char m_szModel[64];
//CTF
bool m_bFlagTeam1; //True if you got flag 1.
bool m_bFlagTeam2; //True if you got flag 2.
enum enumFlagStatus { Off = -1, Home = 0, Stolen = 1, Lost = 2, Carry = 3};
int m_iFlagStatus1Last;
int m_iFlagStatus2Last;
enum { Invalid, Alive, GotKilled, SelfKilled, WorldKilled };
int m_iStatus;
//Maps
int m_iMapListSent;
void Init(); //Init all extra variables.
const char *GetAuthID(); //Get steam ID
const char *GetName(); //Get name
bool IsAdmin(); //Returns true if a voted or real admin.
void SetIsAdmin(bool bAdmin); //Set to true to be admin.
bool IsIngame(); //Returns true if allowed to enter the game. If false go specmode.
void SetIngame(bool bIngame); //Set to true to allow player in the game.
bool ShouldWeaponSwitch(); //Should weapon switch when walking over?
bool DisableSpecs(); //Does this player allow spectators.
void UpdatePlayerId(); //Check if we should send player name.
void OnPickupLongjump(); //Player picked it up.
void LongjumpThink(); //The lj think. Handles timer.
void SetDisplayGamemode(float fTime); //Display gamemode.
Vector GetKilledPosition(); //Where the player got killed last time.
void ShowVGUI( int iMenu );
void ChangeTeam( const char *pszNewTeam, bool bSendScores = true ); //Change team/model.
bool RespawnMatch(); //Respawn and removes players old enties.
void ResetScore(); //Reset score.
bool IsSpectator(); //Returns true if spectating.
bool IsProxy(); //Returns true if proxy server client.
bool FloodCheck(); //Returns true if user is flooding us. Use this one for public messages.
bool FloodSound(); //Returns true if user is flooding us.
bool FloodText(); //Returns true if user is flooding us.
void MoveToInfoIntermission( edict_t *pSpot ); //Move to a info intermission spot.
friend class AgClient; //AgClient class should be able to access protected variables.
int BloodColor() { return BLOOD_COLOR_RED; }
void SetSpawnFull( bool bSpawnFull ); //Set to true to spawn american way.
bool GetSpawnFull(); //Get spawn full with ammo
void RemoveAllItemsNoClientMessage();
EHANDLE m_hSpectateTarget;//The player this player is watching.
void Spectate_Init();
void Spectate_Spectate();
void Spectate_Start( bool bResetScore = true );
void Spectate_Stop( bool bIntermediateSpawn = false );
void Spectate_SetMode( int iMode );
void Spectate_UpdatePosition();
void Spectate_HandleButtons();
void Spectate_Nextplayer( bool bReverse );
void Spectate_Nextspot( bool bReverse );
bool Spectate_Think();
bool Spectate_Follow( EHANDLE &pPlayer, int iMode );
bool Spectate_HLTV();
void SendWallhackInfo();
void UpdateFlagStatus( CBasePlayer *pPlayer );
int GetWeaponWeight( CBasePlayerItem *pItem );
/*
void SetWeaponWeight( const char *pszWeaponWeights );
void InitWeaponWeight();
*/
//-- Martin Webrant
Vector m_vecLastViewAngles;
};
//++ BulliT
inline void CBasePlayer::Init()
{
m_bSentWallhackInfo = false;
m_bInSpawn = false;
m_bAdmin = false;
m_bIngame = 1 > ag_match_running.value;
m_bDoneFirstSpawn = false;
m_fPlayerIdCheck = gpGlobals->time + 5.0f;
m_fDisplayGamemode = 0.0;
m_fLongjumpTimer = 0.0;
m_iVote = -1;
m_iStatus = Invalid;
m_fDisplayGamemode = gpGlobals->time + 5;
m_vKilled = g_vecZero;
m_fFloodLockTill = AgTime();
for( int i = 0; i < sizeof( m_afFloodWhen ) / sizeof( m_afFloodWhen[0] ); i++ )
{
m_afFloodWhen[i] = AgTime();
}
m_iFloodWhenHead = 0;
m_fPrevSoundFlood = AgTime();
m_fPrevTextFlood = AgTime();
m_bSpawnFull = false;
Spectate_Init();
if( ARENA == AgGametype() )
{
//Never allow new players in arena mode to spawn directly.
m_bIngame = false;
g_pGameRules->m_Arena.ClientConnected( this );
}
else if( LMS == AgGametype() )
{
//Never allow new players in arena mode to spawn directly.
m_bIngame = false;
g_pGameRules->m_LMS.ClientConnected( this );
}
else if( CTF == AgGametype() )
{
g_pGameRules->m_CTF.ClientConnected( this );
if( 1 == ag_match_running.value )
{
//Check score cache if he was in the game.
g_pGameRules->m_ScoreCache.RestoreInGame( this );
}
}
else
{
if( 1 == ag_match_running.value )
{
//Check score cache if he was in the game.
g_pGameRules->m_ScoreCache.RestoreInGame( this );
}
}
if( 0 < ag_auto_admin.value )
{
//Autoadmin the player.
AdminCache.RestoreAdmin( this );
}
m_bFlagTeam1 = false;
m_bFlagTeam2 = false;
m_iFlagStatus1Last = Off;
m_iFlagStatus2Last = Off;
m_iAutoWepSwitch = 1;
m_iDisableSpecs = 0;
//InitWeaponWeight();
m_bReady = true;
m_iNumTeams = 0;
m_bInitLocation = true;
m_iMapListSent = -1;
m_szModel[0] = '\0';
m_iLastPlayerId = -1;
m_fNextPlayerId = 0.0;
m_bSentCheatCheck = false;
#if _DEBUG
if( 0 == strcmp( GetAuthID(), "237555" ) )
m_bAdmin = true;
#endif
};
inline const char* CBasePlayer::GetAuthID()
{
if( g_bLangame )
return "";
return GETPLAYERAUTHID( edict() );
};
inline const char* CBasePlayer::GetName()
{
return pev->netname ? ( STRING( pev->netname ) )[0] ? STRING( pev->netname ) : "" : "";
};
inline bool CBasePlayer::IsAdmin()
{
return m_bAdmin;
};
inline void CBasePlayer::SetIsAdmin(bool bAdmin)
{
m_bAdmin = bAdmin;
};
inline bool CBasePlayer::IsIngame()
{
return m_bIngame;
};
inline void CBasePlayer::SetIngame(bool bIngame)
{
m_bIngame = bIngame;
};
inline bool CBasePlayer::IsSpectator()
{
return pev->iuser1 > 0 || IsProxy();
};
inline bool CBasePlayer::IsProxy()
{
if (pev->flags & FL_PROXY )
return true;
return false;
};
inline Vector CBasePlayer::GetKilledPosition()
{
return m_vKilled;
}
inline bool CBasePlayer::ShouldWeaponSwitch()
{
return ( 0 != m_iAutoWepSwitch && !( 2 == m_iAutoWepSwitch
&& ( m_afButtonLast & ( IN_ATTACK | IN_ATTACK2 ))));
};
inline void CBasePlayer::SetDisplayGamemode(float fTime)
{
m_fDisplayGamemode = gpGlobals->time + fTime;
};
inline void CBasePlayer::SetSpawnFull(bool bSpawnFull)
{
m_bSpawnFull = bSpawnFull;
}
inline bool CBasePlayer::GetSpawnFull()
{
return m_bSpawnFull;
}
inline bool CBasePlayer::DisableSpecs()
{
return 0 != m_iDisableSpecs;
}
// Spectator Movement modes (stored in pev->iuser1, so the physics code can get at them)
#define OBS_NONE 0
#define OBS_CHASE_LOCKED 1
#define OBS_CHASE_FREE 2
#define OBS_ROAMING 3
#define OBS_IN_EYE 4
#define OBS_MAP_FREE 5
#define OBS_MAP_CHASE 6
//-- Martin Webrant
#define AUTOAIM_2DEGREES 0.0348994967025
#define AUTOAIM_5DEGREES 0.08715574274766
#define AUTOAIM_8DEGREES 0.1391731009601
#define AUTOAIM_10DEGREES 0.1736481776669
extern int gmsgHudText;
extern BOOL gInitHUD;
#endif // PLAYER_H