/* * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * In addition, as a special exception, the author gives permission to * link the code of this program with the Half-Life Game Engine ("HL * Engine") and Modified Game Libraries ("MODs") developed by Valve, * L.L.C ("Valve"). You must obey the GNU General Public License in all * respects for all of the code used other than the HL Engine and MODs * from Valve. If you modify this file, you may extend this exception * to your version of the file, but you are not obligated to do so. If * you do not wish to do so, delete this exception statement from your * version. * */ #pragma once #include "pm_materials.h" #include "hintmessage.h" #include "unisignals.h" #define MIN_BUY_TIME 15 // the minimum threshold values for cvar mp_buytime 15 sec's #define MAX_BUFFER_MENU 175 #define MAX_BUFFER_MENU_BRIEFING 50 #define MAX_PLAYER_NAME_LENGTH 32 #define MAX_AUTOBUY_LENGTH 256 #define MAX_REBUY_LENGTH 256 #define MAX_RECENT_PATH 20 #define MAX_HOSTAGE_ICON 4 // the maximum number of icons of the hostages in the HUD #define SUITUPDATETIME 3.5 #define SUITFIRSTUPDATETIME 0.1 #define PLAYER_FATAL_FALL_SPEED 1100.0f #define PLAYER_MAX_SAFE_FALL_SPEED 500.0f #define PLAYER_USE_RADIUS 64.0f #define ARMOR_RATIO 0.5 // Armor Takes 50% of the damage #define ARMOR_BONUS 0.5 // Each Point of Armor is work 1/x points of health #define FLASH_DRAIN_TIME 1.2 // 100 units/3 minutes #define FLASH_CHARGE_TIME 0.2 // 100 units/20 seconds (seconds per unit) // damage per unit per second. #define DAMAGE_FOR_FALL_SPEED 100.0f / (PLAYER_FATAL_FALL_SPEED - PLAYER_MAX_SAFE_FALL_SPEED) #define PLAYER_MIN_BOUNCE_SPEED 350.0f // won't punch player's screen/make scrape noise unless player falling at least this fast. #define PLAYER_FALL_PUNCH_THRESHHOLD 250.0f // Money blinks few of times on the freeze period // NOTE: It works for CZ #define MONEY_BLINK_AMOUNT 30 // Player physics flags bits // CBasePlayer::m_afPhysicsFlags #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. #define TRAIN_OFF 0x00 #define TRAIN_NEUTRAL 0x01 #define TRAIN_SLOW 0x02 #define TRAIN_MEDIUM 0x03 #define TRAIN_FAST 0x04 #define TRAIN_BACK 0x05 #define TRAIN_ACTIVE 0x80 #define TRAIN_NEW 0xc0 #define SIGNAL_BUY (1<<0) #define SIGNAL_BOMB (1<<1) #define SIGNAL_RESCUE (1<<2) #define SIGNAL_ESCAPE (1<<3) #define SIGNAL_VIPSAFETY (1<<4) #define IGNOREMSG_NONE 0 #define IGNOREMSG_ENEMY 1 #define IGNOREMSG_TEAM 2 // max of 4 suit sentences queued up at any time #define CSUITPLAYLIST 4 #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 TEAM_NAME_LENGTH 16 #define MAX_ID_RANGE 2048.0f #define MAX_SPECTATOR_ID_RANGE 8192.0f #define SBAR_STRING_SIZE 128 #define SBAR_TARGETTYPE_TEAMMATE 1 #define SBAR_TARGETTYPE_ENEMY 2 #define SBAR_TARGETTYPE_HOSTAGE 3 #define CHAT_INTERVAL 1.0f #define CSUITNOREPEAT 32 #define AUTOAIM_2DEGREES 0.0348994967025 #define AUTOAIM_5DEGREES 0.08715574274766 #define AUTOAIM_8DEGREES 0.1391731009601 #define AUTOAIM_10DEGREES 0.1736481776669 #define SOUND_FLASHLIGHT_ON "items/flashlight1.wav" #define SOUND_FLASHLIGHT_OFF "items/flashlight1.wav" // custom enum enum RewardType { RT_NONE, RT_ROUND_BONUS, RT_PLAYER_RESET, RT_PLAYER_JOIN, RT_PLAYER_SPEC_JOIN, RT_PLAYER_BOUGHT_SOMETHING, RT_HOSTAGE_TOOK, RT_HOSTAGE_RESCUED, RT_HOSTAGE_DAMAGED, RT_HOSTAGE_KILLED, RT_TEAMMATES_KILLED, RT_ENEMY_KILLED, RT_INTO_GAME, RT_VIP_KILLED, RT_VIP_RESCUED_MYSELF }; enum PLAYER_ANIM { PLAYER_IDLE, PLAYER_WALK, PLAYER_JUMP, PLAYER_SUPERJUMP, PLAYER_DIE, PLAYER_ATTACK1, PLAYER_ATTACK2, PLAYER_FLINCH, PLAYER_LARGE_FLINCH, PLAYER_RELOAD, PLAYER_HOLDBOMB }; enum _Menu { Menu_OFF, Menu_ChooseTeam, Menu_IGChooseTeam, Menu_ChooseAppearance, Menu_Buy, Menu_BuyPistol, Menu_BuyRifle, Menu_BuyMachineGun, Menu_BuyShotgun, Menu_BuySubMachineGun, Menu_BuyItem, Menu_Radio1, Menu_Radio2, Menu_Radio3, Menu_ClientBuy }; enum TeamName { UNASSIGNED, TERRORIST, CT, SPECTATOR, }; enum ModelName { MODEL_UNASSIGNED, MODEL_URBAN, MODEL_TERROR, MODEL_LEET, MODEL_ARCTIC, MODEL_GSG9, MODEL_GIGN, MODEL_SAS, MODEL_GUERILLA, MODEL_VIP, MODEL_MILITIA, MODEL_SPETSNAZ, MODEL_AUTO }; enum JoinState { JOINED, SHOWLTEXT, READINGLTEXT, SHOWTEAMSELECT, PICKINGTEAM, GETINTOGAME }; enum TrackCommands { CMD_SAY = 0, CMD_SAYTEAM, CMD_FULLUPDATE, CMD_VOTE, CMD_VOTEMAP, CMD_LISTMAPS, CMD_LISTPLAYERS, CMD_NIGHTVISION, COMMANDS_TO_TRACK, }; struct RebuyStruct { int m_primaryWeapon; int m_primaryAmmo; int m_secondaryWeapon; int m_secondaryAmmo; int m_heGrenade; int m_flashbang; int m_smokeGrenade; int m_defuser; int m_nightVision; ArmorType m_armor; }; enum ThrowDirection { THROW_NONE, THROW_FORWARD, THROW_BACKWARD, THROW_HITVEL, THROW_BOMB, THROW_GRENADE, THROW_HITVEL_MINUS_AIRVEL }; enum sbar_data { SBAR_ID_TARGETTYPE = 1, SBAR_ID_TARGETNAME, SBAR_ID_TARGETHEALTH, SBAR_END }; enum MusicState { SILENT, CALM, INTENSE }; class CCSPlayer; class CStripWeapons: public CPointEntity { public: virtual void Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value) = 0; }; // Multiplayer intermission spots. class CInfoIntermission: public CPointEntity { public: virtual void Spawn() = 0; virtual void Think() = 0; }; // Dead HEV suit prop class CDeadHEV: public CBaseMonster { public: virtual void Spawn() = 0; virtual void KeyValue(KeyValueData *pkvd) = 0; virtual int Classify() = 0; public: int m_iPose; // which sequence to display -- temporary, don't need to save static char *m_szPoses[4]; }; class CSprayCan: public CBaseEntity { public: virtual void Think() = 0; virtual int ObjectCaps() = 0; }; class CBloodSplat: public CBaseEntity { public: }; class CBasePlayer: public CBaseMonster { public: virtual void Spawn() = 0; virtual void Precache() = 0; virtual int Save(CSave &save) = 0; virtual int Restore(CRestore &restore) = 0; virtual int ObjectCaps() = 0; virtual int Classify() = 0; virtual void TraceAttack(entvars_t *pevAttacker, float flDamage, Vector vecDir, TraceResult *ptr, int bitsDamageType) = 0; virtual BOOL TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, float flDamage, int bitsDamageType) = 0; virtual BOOL TakeHealth(float flHealth, int bitsDamageType) = 0; virtual void Killed(entvars_t *pevAttacker, int iGib) = 0; virtual void AddPoints(int score, BOOL bAllowNegativeScore) = 0; virtual void AddPointsToTeam(int score, BOOL bAllowNegativeScore) = 0; virtual BOOL AddPlayerItem(CBasePlayerItem *pItem) = 0; virtual BOOL RemovePlayerItem(CBasePlayerItem *pItem) = 0; virtual int GiveAmmo(int iAmount, char *szName, int iMax = -1) = 0; virtual void StartSneaking() = 0; virtual void UpdateOnRemove() = 0; virtual BOOL IsSneaking() = 0; virtual BOOL IsAlive() = 0; virtual BOOL IsPlayer() = 0; virtual BOOL IsNetClient() = 0; virtual const char *TeamID() = 0; virtual BOOL FBecomeProne() = 0; virtual Vector BodyTarget(const Vector &posSrc) = 0; virtual int Illumination() = 0; virtual BOOL ShouldFadeOnDeath() = 0; virtual void ResetMaxSpeed() = 0; virtual void Jump() = 0; virtual void Duck() = 0; virtual void PreThink() = 0; virtual void PostThink() = 0; virtual Vector GetGunPosition() = 0; virtual BOOL IsBot() = 0; virtual void UpdateClientData() = 0; virtual void ImpulseCommands() = 0; virtual void RoundRespawn() = 0; virtual Vector GetAutoaimVector(float flDelta) = 0; virtual void Blind(float flUntilTime, float flHoldTime, float flFadeTime, int iAlpha) = 0; virtual void OnTouchingWeapon(CWeaponBox *pWeapon) = 0; public: static CBasePlayer *Instance(edict_t *pent) { return (CBasePlayer *)GET_PRIVATE(pent ? pent : ENT(0)); } static CBasePlayer *Instance(entvars_t *pev) { return Instance(ENT(pev)); } static CBasePlayer *Instance(int offset) { return Instance(ENT(offset)); } int IsObserver() { return pev->iuser1; } void SetWeaponAnimType(const char *szExtention) { strcpy(m_szAnimExtention, szExtention); } bool IsProtectedByShield() { return m_bOwnsShield && m_bShieldDrawn; } bool IsReloading() const; bool IsBlind() const { return (m_blindUntilTime > gpGlobals->time); } bool IsAutoFollowAllowed() const { return (gpGlobals->time > m_allowAutoFollowTime); } void InhibitAutoFollow(float duration) { m_allowAutoFollowTime = gpGlobals->time + duration; } void AllowAutoFollow() { m_allowAutoFollowTime = 0; } void SetObserverAutoDirector(bool val) { m_bObserverAutoDirector = val; } bool CanSwitchObserverModes() const { return m_canSwitchObserverModes; } CCSPlayer *CSPlayer() const; // templates template CBasePlayerItem *ForEachItem(int slot, const Functor &func) { auto item = m_rgpPlayerItems[ slot ]; while (item) { if (func(item)) return item; item = item->m_pNext; } return nullptr; } template CBasePlayerItem *ForEachItem(const Functor &func) { for (auto item : m_rgpPlayerItems) { while (item) { if (func(item)) return item; item = item->m_pNext; } } return nullptr; } public: enum { MaxLocationLen = 32 }; int random_seed; unsigned short m_usPlayerBleed; EHANDLE m_hObserverTarget; float m_flNextObserverInput; int m_iObserverWeapon; int m_iObserverC4State; bool m_bObserverHasDefuser; int m_iObserverLastMode; float m_flFlinchTime; float m_flAnimTime; bool m_bHighDamage; float m_flVelocityModifier; int m_iLastZoom; bool m_bResumeZoom; float m_flEjectBrass; ArmorType m_iKevlar; bool m_bNotKilled; TeamName m_iTeam; int m_iAccount; bool m_bHasPrimary; float m_flDeathThrowTime; int m_iThrowDirection; float m_flLastTalk; bool m_bJustConnected; bool m_bContextHelp; JoinState m_iJoiningState; CBaseEntity *m_pIntroCamera; float m_fIntroCamTime; float m_fLastMovement; bool m_bMissionBriefing; bool m_bTeamChanged; ModelName m_iModelName; int m_iTeamKills; int m_iIgnoreGlobalChat; bool m_bHasNightVision; bool m_bNightVisionOn; Vector m_vRecentPath[MAX_RECENT_PATH]; float m_flIdleCheckTime; float m_flRadioTime; int m_iRadioMessages; bool m_bIgnoreRadio; bool m_bHasC4; bool m_bHasDefuser; bool m_bKilledByBomb; Vector m_vBlastVector; bool m_bKilledByGrenade; CHintMessageQueue m_hintMessageQueue; int m_flDisplayHistory; _Menu m_iMenu; int m_iChaseTarget; CBaseEntity *m_pChaseTarget; float m_fCamSwitch; bool m_bEscaped; bool m_bIsVIP; float m_tmNextRadarUpdate; Vector m_vLastOrigin; int m_iCurrentKickVote; float m_flNextVoteTime; bool m_bJustKilledTeammate; int m_iHostagesKilled; int m_iMapVote; bool m_bCanShoot; float m_flLastFired; float m_flLastAttackedTeammate; bool m_bHeadshotKilled; bool m_bPunishedForTK; bool m_bReceivesNoMoneyNextRound; int m_iTimeCheckAllowed; bool m_bHasChangedName; char m_szNewName[MAX_PLAYER_NAME_LENGTH]; bool m_bIsDefusing; float m_tmHandleSignals; CUnifiedSignals m_signals; edict_t *m_pentCurBombTarget; int m_iPlayerSound; int m_iTargetVolume; int m_iWeaponVolume; int m_iExtraSoundTypes; int m_iWeaponFlash; float m_flStopExtraSoundTime; float m_flFlashLightTime; int m_iFlashBattery; int m_afButtonLast; int m_afButtonPressed; int m_afButtonReleased; edict_t *m_pentSndLast; float m_flSndRoomtype; float m_flSndRange; float m_flFallVelocity; int m_rgItems[MAX_ITEMS]; int m_fNewAmmo; unsigned int m_afPhysicsFlags; float m_fNextSuicideTime; float m_flTimeStepSound; float m_flTimeWeaponIdle; float m_flSwimTime; float m_flDuckTime; float m_flWallJumpTime; float m_flSuitUpdate; int m_rgSuitPlayList[CSUITPLAYLIST]; int m_iSuitPlayNext; int m_rgiSuitNoRepeat[CSUITNOREPEAT]; float m_rgflSuitNoRepeatTime[CSUITNOREPEAT]; int m_lastDamageAmount; float m_tbdPrev; float m_flgeigerRange; float m_flgeigerDelay; int m_igeigerRangePrev; int m_iStepLeft; char m_szTextureName[CBTEXTURENAMEMAX]; char m_chTextureType; int m_idrowndmg; int m_idrownrestored; int m_bitsHUDDamage; BOOL m_fInitHUD; BOOL m_fGameHUDInitialized; int m_iTrain; BOOL m_fWeapon; EHANDLE m_pTank; float m_fDeadTime; BOOL m_fNoPlayerSound; BOOL m_fLongJump; float m_tSneaking; int m_iUpdateTime; int m_iClientHealth; int m_iClientBattery; int m_iHideHUD; int m_iClientHideHUD; int m_iFOV; int m_iClientFOV; int m_iNumSpawns; CBaseEntity *m_pObserver; CBasePlayerItem *m_rgpPlayerItems[MAX_ITEM_TYPES]; CBasePlayerItem *m_pActiveItem; CBasePlayerItem *m_pClientActiveItem; CBasePlayerItem *m_pLastItem; int m_rgAmmo[MAX_AMMO_SLOTS]; int m_rgAmmoLast[MAX_AMMO_SLOTS]; Vector m_vecAutoAim; BOOL m_fOnTarget; int m_iDeaths; int m_izSBarState[SBAR_END]; float m_flNextSBarUpdateTime; float m_flStatusBarDisappearDelay; char m_SbarString0[SBAR_STRING_SIZE]; int m_lastx; int m_lasty; int m_nCustomSprayFrames; float m_flNextDecalTime; char m_szTeamName[TEAM_NAME_LENGTH]; int m_modelIndexPlayer; char m_szAnimExtention[32]; int m_iGaitsequence; float m_flGaitframe; float m_flGaityaw; Vector m_prevgaitorigin; float m_flPitch; float m_flYaw; float m_flGaitMovement; int m_iAutoWepSwitch; bool m_bVGUIMenus; bool m_bShowHints; bool m_bShieldDrawn; bool m_bOwnsShield; bool m_bWasFollowing; float m_flNextFollowTime; float m_flYawModifier; float m_blindUntilTime; float m_blindStartTime; float m_blindHoldTime; float m_blindFadeTime; int m_blindAlpha; float m_allowAutoFollowTime; char m_autoBuyString[MAX_AUTOBUY_LENGTH]; char *m_rebuyString; RebuyStruct m_rebuyStruct; bool m_bIsInRebuy; float m_flLastUpdateTime; char m_lastLocation[MaxLocationLen]; float m_progressStart; float m_progressEnd; bool m_bObserverAutoDirector; bool m_canSwitchObserverModes; float m_heartBeatTime; float m_intenseTimestamp; float m_silentTimestamp; MusicState m_musicState; float m_flLastCommandTime[COMMANDS_TO_TRACK]; }; class CWShield: public CBaseEntity { public: virtual void Spawn() = 0; virtual void Touch(CBaseEntity *pOther) = 0; public: void SetCantBePickedUpByUser(CBaseEntity *pEntity, float time) { m_hEntToIgnoreTouchesFrom = pEntity; m_flTimeToIgnoreTouches = gpGlobals->time + time; } public: EHANDLE m_hEntToIgnoreTouchesFrom; float m_flTimeToIgnoreTouches; }; inline bool CBasePlayer::IsReloading() const { CBasePlayerWeapon *weapon = static_cast(m_pActiveItem); if (weapon && weapon->m_fInReload) return true; return false; } inline CCSPlayer *CBasePlayer::CSPlayer() const { return reinterpret_cast(this->m_pEntity); } // returns a CBaseEntity pointer to a player by index. Only returns if the player is spawned and connected otherwise returns NULL // Index is 1 based inline CBasePlayer *UTIL_PlayerByIndex(int playerIndex) { return (CBasePlayer *)GET_PRIVATE(INDEXENT(playerIndex)); } inline CBasePlayer *UTIL_PlayerByIndexSafe(int playerIndex) { CBasePlayer *player = nullptr; if (likely(playerIndex > 0 && playerIndex <= gpGlobals->maxClients)) player = UTIL_PlayerByIndex(playerIndex); return player; }