2015-09-30 03:49:22 +03:00
/*
2017-10-19 20:12:02 +03:00
*
* 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 .
*
2015-09-30 03:49:22 +03:00
*/
2017-10-19 20:12:02 +03:00
# include "precompiled.h"
2015-09-30 03:49:22 +03:00
2017-10-19 20:12:02 +03:00
BOOL gInitHUD = TRUE ;
2015-09-30 03:49:22 +03:00
TYPEDESCRIPTION CBasePlayer : : m_playerSaveData [ ] =
{
DEFINE_FIELD ( CBasePlayer , m_flFlashLightTime , FIELD_TIME ) ,
DEFINE_FIELD ( CBasePlayer , m_iFlashBattery , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_afButtonLast , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_afButtonPressed , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_afButtonReleased , FIELD_INTEGER ) ,
DEFINE_ARRAY ( CBasePlayer , m_rgItems , FIELD_INTEGER , MAX_ITEMS ) ,
DEFINE_FIELD ( CBasePlayer , m_afPhysicsFlags , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_flTimeStepSound , FIELD_TIME ) ,
DEFINE_FIELD ( CBasePlayer , m_flTimeWeaponIdle , FIELD_TIME ) ,
DEFINE_FIELD ( CBasePlayer , m_flSwimTime , FIELD_TIME ) ,
DEFINE_FIELD ( CBasePlayer , m_flDuckTime , FIELD_TIME ) ,
DEFINE_FIELD ( CBasePlayer , m_flWallJumpTime , FIELD_TIME ) ,
DEFINE_FIELD ( CBasePlayer , m_flSuitUpdate , FIELD_TIME ) ,
2017-10-12 17:50:56 +03:00
DEFINE_ARRAY ( CBasePlayer , m_rgSuitPlayList , FIELD_INTEGER , MAX_SUIT_PLAYLIST ) ,
2015-09-30 03:49:22 +03:00
DEFINE_FIELD ( CBasePlayer , m_iSuitPlayNext , FIELD_INTEGER ) ,
2017-10-12 17:50:56 +03:00
DEFINE_ARRAY ( CBasePlayer , m_rgiSuitNoRepeat , FIELD_INTEGER , MAX_SUIT_NOREPEAT ) ,
DEFINE_ARRAY ( CBasePlayer , m_rgflSuitNoRepeatTime , FIELD_TIME , MAX_SUIT_NOREPEAT ) ,
2015-09-30 03:49:22 +03:00
DEFINE_FIELD ( CBasePlayer , m_lastDamageAmount , FIELD_INTEGER ) ,
DEFINE_ARRAY ( CBasePlayer , m_rgpPlayerItems , FIELD_CLASSPTR , MAX_ITEM_TYPES ) ,
DEFINE_FIELD ( CBasePlayer , m_pActiveItem , FIELD_CLASSPTR ) ,
DEFINE_FIELD ( CBasePlayer , m_pLastItem , FIELD_CLASSPTR ) ,
DEFINE_ARRAY ( CBasePlayer , m_rgAmmo , FIELD_INTEGER , MAX_AMMO_SLOTS ) ,
DEFINE_FIELD ( CBasePlayer , m_idrowndmg , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_idrownrestored , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_tSneaking , FIELD_TIME ) ,
DEFINE_FIELD ( CBasePlayer , m_iTrain , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_bitsHUDDamage , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_flFallVelocity , FIELD_FLOAT ) ,
DEFINE_FIELD ( CBasePlayer , m_iTargetVolume , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_iWeaponVolume , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_iExtraSoundTypes , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_iWeaponFlash , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_fLongJump , FIELD_BOOLEAN ) ,
DEFINE_FIELD ( CBasePlayer , m_fInitHUD , FIELD_BOOLEAN ) ,
DEFINE_FIELD ( CBasePlayer , m_tbdPrev , FIELD_TIME ) ,
DEFINE_FIELD ( CBasePlayer , m_pTank , FIELD_EHANDLE ) ,
DEFINE_FIELD ( CBasePlayer , m_iHideHUD , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_iFOV , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_flDisplayHistory , FIELD_INTEGER ) ,
DEFINE_FIELD ( CBasePlayer , m_iJoiningState , FIELD_INTEGER ) ,
} ;
2017-10-19 20:12:02 +03:00
const char * CDeadHEV : : m_szPoses [ ] =
2015-09-30 03:49:22 +03:00
{
" deadback " ,
" deadsitting " ,
" deadstomach " ,
" deadtable "
} ;
2017-01-29 02:56:29 +03:00
LINK_ENTITY_TO_CLASS ( player , CBasePlayer , CCSPlayer )
2015-09-30 03:49:22 +03:00
2017-11-01 21:23:23 +03:00
# ifdef REGAMEDLL_API
void CBasePlayer : : OnCreate ( )
{
;
}
void CBasePlayer : : OnDestroy ( )
{
if ( m_rebuyString )
{
delete [ ] m_rebuyString ;
m_rebuyString = nullptr ;
}
2020-11-21 22:19:50 +03:00
m_hintMessageQueue . Reset ( ) ;
2017-11-01 21:23:23 +03:00
}
# endif
2016-06-02 01:08:22 +03:00
void CBasePlayer : : SendItemStatus ( )
2015-09-30 03:49:22 +03:00
{
int itemStatus = 0 ;
2016-06-02 01:08:22 +03:00
if ( m_bHasNightVision )
2015-09-30 03:49:22 +03:00
itemStatus | = ITEM_STATUS_NIGHTVISION ;
2016-06-02 01:08:22 +03:00
if ( m_bHasDefuser )
2015-09-30 03:49:22 +03:00
itemStatus | = ITEM_STATUS_DEFUSER ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgItemStatus , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( itemStatus ) ;
MESSAGE_END ( ) ;
}
const char * GetCSModelName ( int item_id )
{
2017-10-12 17:50:56 +03:00
const char * modelName = nullptr ;
2015-09-30 03:49:22 +03:00
switch ( item_id )
{
2017-10-12 17:50:56 +03:00
case WEAPON_P228 : modelName = " models/w_p228.mdl " ; break ;
case WEAPON_SCOUT : modelName = " models/w_scout.mdl " ; break ;
case WEAPON_HEGRENADE : modelName = " models/w_hegrenade.mdl " ; break ;
case WEAPON_XM1014 : modelName = " models/w_xm1014.mdl " ; break ;
2017-11-01 18:01:24 +03:00
case WEAPON_C4 : modelName = " models/w_backpack.mdl " ; break ;
2017-10-12 17:50:56 +03:00
case WEAPON_MAC10 : modelName = " models/w_mac10.mdl " ; break ;
case WEAPON_AUG : modelName = " models/w_aug.mdl " ; break ;
case WEAPON_SMOKEGRENADE : modelName = " models/w_smokegrenade.mdl " ; break ;
case WEAPON_ELITE : modelName = " models/w_elite.mdl " ; break ;
case WEAPON_FIVESEVEN : modelName = " models/w_fiveseven.mdl " ; break ;
case WEAPON_UMP45 : modelName = " models/w_ump45.mdl " ; break ;
case WEAPON_SG550 : modelName = " models/w_sg550.mdl " ; break ;
case WEAPON_GALIL : modelName = " models/w_galil.mdl " ; break ;
case WEAPON_FAMAS : modelName = " models/w_famas.mdl " ; break ;
case WEAPON_USP : modelName = " models/w_usp.mdl " ; break ;
case WEAPON_GLOCK18 : modelName = " models/w_glock18.mdl " ; break ;
case WEAPON_AWP : modelName = " models/w_awp.mdl " ; break ;
case WEAPON_MP5N : modelName = " models/w_mp5.mdl " ; break ;
case WEAPON_M249 : modelName = " models/w_m249.mdl " ; break ;
case WEAPON_M3 : modelName = " models/w_m3.mdl " ; break ;
case WEAPON_M4A1 : modelName = " models/w_m4a1.mdl " ; break ;
case WEAPON_TMP : modelName = " models/w_tmp.mdl " ; break ;
case WEAPON_G3SG1 : modelName = " models/w_g3sg1.mdl " ; break ;
case WEAPON_FLASHBANG : modelName = " models/w_flashbang.mdl " ; break ;
case WEAPON_DEAGLE : modelName = " models/w_deagle.mdl " ; break ;
case WEAPON_SG552 : modelName = " models/w_sg552.mdl " ; break ;
case WEAPON_AK47 : modelName = " models/w_ak47.mdl " ; break ;
case WEAPON_KNIFE : modelName = " models/w_knife.mdl " ; break ;
case WEAPON_P90 : modelName = " models/w_p90.mdl " ; break ;
case WEAPON_SHIELDGUN : modelName = " models/w_shield.mdl " ; break ;
2015-09-30 03:49:22 +03:00
default :
ALERT ( at_console , " CBasePlayer::PackDeadPlayerItems(): Unhandled item- not creating weaponbox \n " ) ;
}
return modelName ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CHAIN ( bool , CBasePlayer , SetClientUserInfoName , ( char * infobuffer , char * szNewName ) , infobuffer , szNewName )
2016-06-03 18:32:33 +03:00
2016-12-06 22:21:52 +03:00
bool EXT_FUNC CBasePlayer : : __API_HOOK ( SetClientUserInfoName ) ( char * infobuffer , char * szNewName )
2016-06-03 18:32:33 +03:00
{
int nClientIndex = entindex ( ) ;
2019-08-11 16:20:21 +03:00
# ifdef REGAMEDLL_FIXES
if ( IsProxy ( ) )
{
SET_CLIENT_KEY_VALUE ( nClientIndex , infobuffer , " name " , szNewName ) ;
return true ;
}
# endif
2016-06-03 18:32:33 +03:00
if ( pev - > deadflag ! = DEAD_NO )
{
m_bHasChangedName = true ;
Q_snprintf ( m_szNewName , sizeof ( m_szNewName ) , " %s " , szNewName ) ;
ClientPrint ( pev , HUD_PRINTTALK , " #Name_change_at_respawn " ) ;
2016-12-06 22:21:52 +03:00
return false ;
2016-06-03 18:32:33 +03:00
}
2016-12-06 22:21:52 +03:00
// Set the name
SET_CLIENT_KEY_VALUE ( nClientIndex , infobuffer , " name " , szNewName ) ;
2016-06-03 18:32:33 +03:00
2016-12-06 22:21:52 +03:00
MESSAGE_BEGIN ( MSG_BROADCAST , gmsgSayText ) ;
WRITE_BYTE ( nClientIndex ) ;
WRITE_STRING ( " #Cstrike_Name_Change " ) ;
WRITE_STRING ( STRING ( pev - > netname ) ) ;
WRITE_STRING ( szNewName ) ;
MESSAGE_END ( ) ;
UTIL_LogPrintf ( " \" %s<%i><%s><%s> \" changed name to \" %s \" \n " , STRING ( pev - > netname ) , GETPLAYERUSERID ( edict ( ) ) , GETPLAYERAUTHID ( edict ( ) ) , GetTeam ( m_iTeam ) , szNewName ) ;
return true ;
2016-06-03 18:32:33 +03:00
}
2016-05-30 14:19:56 +03:00
void EXT_FUNC CBasePlayer : : SetClientUserInfoModel_api ( char * infobuffer , char * szNewModel )
{
SET_CLIENT_KEY_VALUE ( entindex ( ) , infobuffer , " model " , szNewModel ) ;
}
void CBasePlayer : : SetClientUserInfoModel ( char * infobuffer , char * szNewModel )
{
if ( szNewModel = = nullptr )
return ;
if ( Q_strcmp ( GET_KEY_VALUE ( infobuffer , " model " ) , szNewModel ) ! = 0 )
{
g_ReGameHookchains . m_CBasePlayer_SetClientUserInfoModel . callChain ( & CBasePlayer : : SetClientUserInfoModel_api , this , infobuffer , szNewModel ) ;
}
}
2015-09-30 03:49:22 +03:00
void CBasePlayer : : SetPlayerModel ( BOOL HasC4 )
{
char * infobuffer = GET_INFO_BUFFER ( edict ( ) ) ;
char * model ;
2016-05-30 14:19:56 +03:00
# ifdef REGAMEDLL_ADD
2017-01-29 02:56:29 +03:00
auto modelEx = CSPlayer ( ) - > m_szModel ;
if ( modelEx [ 0 ] ! = ' \0 ' ) {
2016-05-31 17:04:51 +03:00
model = modelEx ;
2016-05-30 14:19:56 +03:00
} else
# endif
2015-09-30 03:49:22 +03:00
if ( m_iTeam = = CT )
{
switch ( m_iModelName )
{
case MODEL_URBAN :
model = " urban " ;
break ;
case MODEL_GSG9 :
model = " gsg9 " ;
break ;
case MODEL_GIGN :
model = " gign " ;
break ;
case MODEL_SAS :
model = " sas " ;
break ;
case MODEL_VIP :
model = " vip " ;
break ;
case MODEL_SPETSNAZ :
2017-10-12 17:50:56 +03:00
if ( AreRunningCZero ( ) )
2015-09-30 03:49:22 +03:00
{
model = " spetsnaz " ;
break ;
}
default :
{
if ( IsBot ( ) )
{
model = ( char * ) TheBotProfiles - > GetCustomSkinModelname ( m_iModelName ) ;
if ( ! model )
model = " urban " ;
}
else
model = " urban " ;
break ;
}
}
}
else if ( m_iTeam = = TERRORIST )
{
switch ( m_iModelName )
{
case MODEL_TERROR :
model = " terror " ;
break ;
case MODEL_LEET :
model = " leet " ;
break ;
case MODEL_ARCTIC :
model = " arctic " ;
break ;
case MODEL_GUERILLA :
model = " guerilla " ;
break ;
case MODEL_MILITIA :
2017-10-12 17:50:56 +03:00
if ( AreRunningCZero ( ) )
2015-09-30 03:49:22 +03:00
{
model = " militia " ;
break ;
}
default :
{
if ( IsBot ( ) )
{
model = ( char * ) TheBotProfiles - > GetCustomSkinModelname ( m_iModelName ) ;
if ( ! model )
model = " terror " ;
}
else
model = " terror " ;
break ;
}
}
}
else
model = " urban " ;
2016-05-30 14:19:56 +03:00
SetClientUserInfoModel ( infobuffer , model ) ;
2015-09-30 03:49:22 +03:00
}
2016-01-06 15:50:26 +03:00
CBasePlayer * CBasePlayer : : GetNextRadioRecipient ( CBasePlayer * pStartPlayer )
2015-09-30 03:49:22 +03:00
{
2016-02-23 02:13:52 +03:00
CBaseEntity * pEntity = static_cast < CBaseEntity * > ( pStartPlayer ) ;
2016-12-06 22:21:52 +03:00
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-09-30 03:49:22 +03:00
{
if ( FNullEnt ( pEntity - > edict ( ) ) )
break ;
2016-02-23 02:13:52 +03:00
bool bSend = false ;
2016-03-17 20:44:52 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
2015-09-30 03:49:22 +03:00
if ( pEntity - > IsPlayer ( ) )
{
if ( pEntity - > IsDormant ( ) )
continue ;
if ( pPlayer & & pPlayer - > m_iTeam = = m_iTeam )
2016-02-23 02:13:52 +03:00
bSend = true ;
2015-09-30 03:49:22 +03:00
}
else if ( pPlayer )
{
2018-02-08 12:37:02 +03:00
int iSpecMode = GetObserverMode ( ) ;
2015-09-30 03:49:22 +03:00
if ( iSpecMode ! = OBS_CHASE_LOCKED & & iSpecMode ! = OBS_CHASE_FREE & & iSpecMode ! = OBS_IN_EYE )
continue ;
if ( ! FNullEnt ( m_hObserverTarget ) )
continue ;
2016-06-14 01:13:13 +03:00
CBasePlayer * pTarget = CBasePlayer : : Instance ( pPlayer - > m_hObserverTarget - > pev ) ;
2016-12-06 22:21:52 +03:00
if ( pTarget & & pTarget - > m_iTeam = = m_iTeam )
2015-09-30 03:49:22 +03:00
{
2016-02-23 02:13:52 +03:00
bSend = true ;
2015-09-30 03:49:22 +03:00
}
}
if ( bSend )
{
return pPlayer ;
}
}
2017-10-13 03:04:37 +03:00
return nullptr ;
2015-09-30 03:49:22 +03:00
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , Radio , ( const char * msg_id , const char * msg_verbose , short pitch , bool showIcon ) , msg_id , msg_verbose , pitch , showIcon )
2016-12-06 22:21:52 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( Radio ) ( const char * msg_id , const char * msg_verbose , short pitch , bool showIcon )
2015-09-30 03:49:22 +03:00
{
// Spectators don't say radio messages.
if ( ! IsPlayer ( ) )
return ;
// Neither do dead guys.
if ( pev - > deadflag ! = DEAD_NO & & ! IsBot ( ) )
return ;
2017-10-13 03:04:37 +03:00
CBaseEntity * pEntity = nullptr ;
2016-12-06 22:21:52 +03:00
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-09-30 03:49:22 +03:00
{
if ( FNullEnt ( pEntity - > edict ( ) ) )
break ;
2016-02-23 02:13:52 +03:00
bool bSend = false ;
2016-03-17 20:44:52 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
2015-09-30 03:49:22 +03:00
2017-10-13 03:04:37 +03:00
if ( ! pPlayer )
2015-09-30 03:49:22 +03:00
continue ;
2019-12-25 15:36:26 +03:00
// ignorerad command
if ( pPlayer - > m_bIgnoreRadio )
continue ;
2015-09-30 03:49:22 +03:00
// are we a regular player? (not spectator)
if ( pPlayer - > IsPlayer ( ) )
{
if ( pPlayer - > IsDormant ( ) )
continue ;
// is this player on our team? (even dead players hear our radio calls)
2024-04-15 11:49:44 +03:00
if ( g_pGameRules - > PlayerRelationship ( this , pPlayer ) = = GR_TEAMMATE )
2016-02-23 02:13:52 +03:00
bSend = true ;
2015-09-30 03:49:22 +03:00
}
// this means we're a spectator
else
{
// do this when spectator mode is in
2018-02-08 12:37:02 +03:00
int iSpecMode = pPlayer - > GetObserverMode ( ) ;
2015-09-30 03:49:22 +03:00
if ( iSpecMode ! = OBS_CHASE_LOCKED & & iSpecMode ! = OBS_CHASE_FREE & & iSpecMode ! = OBS_IN_EYE )
continue ;
2019-12-26 12:36:38 +03:00
if ( FNullEnt ( pPlayer - > m_hObserverTarget ) )
2015-09-30 03:49:22 +03:00
continue ;
2024-04-15 11:49:44 +03:00
if ( pPlayer - > m_hObserverTarget & & g_pGameRules - > PlayerRelationship ( this , pPlayer - > m_hObserverTarget ) = = GR_TEAMMATE )
2015-09-30 03:49:22 +03:00
{
2016-02-23 02:13:52 +03:00
bSend = true ;
2015-09-30 03:49:22 +03:00
}
}
if ( bSend )
{
2019-12-25 15:36:26 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgSendAudio , nullptr , pEntity - > pev ) ;
WRITE_BYTE ( ENTINDEX ( edict ( ) ) ) ;
WRITE_STRING ( msg_id ) ;
WRITE_SHORT ( pitch ) ;
MESSAGE_END ( ) ;
// radio message icon
2024-04-15 11:49:44 +03:00
if ( msg_verbose & & msg_verbose [ 0 ] ! = 0 )
2015-09-30 03:49:22 +03:00
{
2019-12-25 15:36:26 +03:00
// search the place name where is located the player
const char * placeName = nullptr ;
2024-04-07 14:49:08 +03:00
if ( (
# ifdef REGAMEDLL_ADD
2024-04-08 12:42:08 +03:00
location_area_info . value > = 2 | |
2024-04-07 14:49:08 +03:00
# endif
AreRunningCZero ( ) ) & & TheBotPhrases )
2015-09-30 03:49:22 +03:00
{
2019-12-25 15:36:26 +03:00
Place playerPlace = TheNavAreaGrid . GetPlace ( & pev - > origin ) ;
const BotPhraseList * placeList = TheBotPhrases - > GetPlaceList ( ) ;
for ( auto phrase : * placeList )
2015-09-30 03:49:22 +03:00
{
2019-12-25 15:36:26 +03:00
if ( phrase - > GetID ( ) = = playerPlace )
2015-09-30 03:49:22 +03:00
{
2019-12-25 15:36:26 +03:00
placeName = phrase - > GetName ( ) ;
break ;
2015-09-30 03:49:22 +03:00
}
}
2024-04-07 14:49:08 +03:00
2024-04-08 12:42:08 +03:00
if ( ! placeName )
2024-04-07 14:49:08 +03:00
placeName = TheNavAreaGrid . IDToName ( playerPlace ) ;
2015-09-30 03:49:22 +03:00
}
2024-04-07 14:49:08 +03:00
2024-04-08 12:42:08 +03:00
if ( placeName & & placeName [ 0 ] )
{
bool bUseLocFallback = false ;
# ifdef REGAMEDLL_ADD
if ( chat_loc_fallback . value )
bUseLocFallback = true ;
# endif
ClientPrint ( pEntity - > pev , HUD_PRINTRADIO , NumAsString ( entindex ( ) ) , bUseLocFallback ? " \ x3%s1 \ x1 @ \ x4%s2 \ x1 (RADIO): %s3 " : " #Game_radio_location " , STRING ( pev - > netname ) , placeName , msg_verbose ) ;
}
2019-12-25 15:36:26 +03:00
else
2024-04-08 12:42:08 +03:00
{
2019-12-25 15:36:26 +03:00
ClientPrint ( pEntity - > pev , HUD_PRINTRADIO , NumAsString ( entindex ( ) ) , " #Game_radio " , STRING ( pev - > netname ) , msg_verbose ) ;
2024-04-08 12:42:08 +03:00
}
2019-12-25 15:36:26 +03:00
}
2015-09-30 03:49:22 +03:00
2019-12-25 15:36:26 +03:00
// icon over the head for teammates
2017-08-19 17:57:01 +03:00
# ifdef REGAMEDLL_ADD
2019-12-25 15:36:26 +03:00
if ( showIcon & & show_radioicon . value )
2017-08-19 17:57:01 +03:00
# else
2019-12-25 15:36:26 +03:00
if ( showIcon )
2017-08-19 17:57:01 +03:00
# endif
2019-12-25 15:36:26 +03:00
{
2015-09-30 03:49:22 +03:00
// put an icon over this guys head to show that he used the radio
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , SVC_TEMPENTITY , nullptr , pEntity - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( TE_PLAYERATTACHMENT ) ;
2016-02-23 02:13:52 +03:00
WRITE_BYTE ( ENTINDEX ( edict ( ) ) ) ; // byte (entity index of player)
2017-11-22 20:27:55 +03:00
WRITE_COORD ( 35 ) ; // coord (vertical offset) ( attachment origin.z = player origin.z + vertical offset)
2016-02-23 02:13:52 +03:00
WRITE_SHORT ( g_sModelIndexRadio ) ; // short (model index) of tempent
2017-11-22 20:27:55 +03:00
WRITE_SHORT ( 15 ) ; // short (life * 10 ) e.g. 40 = 4 seconds
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
}
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : SmartRadio ( )
2015-09-30 03:49:22 +03:00
{
;
}
2021-08-29 07:12:25 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , Pain , ( int iLastHitGroup , bool bHasArmour ) , iLastHitGroup , bHasArmour )
void EXT_FUNC CBasePlayer : : __API_HOOK ( Pain ) ( int iLastHitGroup , bool bHasArmour )
2015-09-30 03:49:22 +03:00
{
int temp = RANDOM_LONG ( 0 , 2 ) ;
2016-02-23 02:13:52 +03:00
if ( iLastHitGroup = = HITGROUP_HEAD )
2015-09-30 03:49:22 +03:00
{
2016-05-17 21:01:46 +03:00
if ( m_iKevlar = = ARMOR_VESTHELM )
2015-09-30 03:49:22 +03:00
{
EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/bhit_helmet-1.wav " , VOL_NORM , ATTN_NORM ) ;
return ;
}
switch ( temp )
{
2016-12-10 21:27:53 +03:00
case 0 : EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/headshot1.wav " , VOL_NORM , ATTN_NORM ) ; break ;
case 1 : EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/headshot2.wav " , VOL_NORM , ATTN_NORM ) ; break ;
2015-09-30 03:49:22 +03:00
default : EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/headshot3.wav " , VOL_NORM , ATTN_NORM ) ; break ;
}
}
else
{
2016-02-23 02:13:52 +03:00
if ( iLastHitGroup ! = HITGROUP_LEFTLEG & & iLastHitGroup ! = HITGROUP_RIGHTLEG )
2015-09-30 03:49:22 +03:00
{
2016-12-10 21:27:53 +03:00
if ( bHasArmour )
2015-09-30 03:49:22 +03:00
{
EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/bhit_kevlar-1.wav " , VOL_NORM , ATTN_NORM ) ;
return ;
}
}
switch ( temp )
{
2016-12-10 21:27:53 +03:00
case 0 : EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/bhit_flesh-1.wav " , VOL_NORM , ATTN_NORM ) ; break ;
case 1 : EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/bhit_flesh-2.wav " , VOL_NORM , ATTN_NORM ) ; break ;
2015-09-30 03:49:22 +03:00
default : EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/bhit_flesh-3.wav " , VOL_NORM , ATTN_NORM ) ; break ;
}
}
}
2016-12-10 21:27:53 +03:00
NOXREF Vector VecVelocityForDamage ( float flDamage )
2015-09-30 03:49:22 +03:00
{
Vector vec ( RANDOM_FLOAT ( - 100 , 100 ) , RANDOM_FLOAT ( - 100 , 100 ) , RANDOM_FLOAT ( 200 , 300 ) ) ;
if ( flDamage > - 50.0f )
vec = vec * 0.7f ;
else if ( flDamage > - 200.0f )
vec = vec * 2.0f ;
else
vec = vec * 10.0f ;
return vec ;
}
int TrainSpeed ( int iSpeed , int iMax )
{
float fMax ;
float fSpeed ;
int iRet = 0 ;
2016-02-23 02:13:52 +03:00
fMax = float ( iMax ) ;
2015-09-30 03:49:22 +03:00
fSpeed = iSpeed / fMax ;
if ( iSpeed < 0 )
iRet = TRAIN_BACK ;
else if ( iSpeed = = 0 )
iRet = TRAIN_NEUTRAL ;
2016-02-23 02:13:52 +03:00
else if ( fSpeed < 0.33f )
2015-09-30 03:49:22 +03:00
iRet = TRAIN_SLOW ;
2016-02-23 02:13:52 +03:00
else if ( fSpeed < 0.66f )
2015-09-30 03:49:22 +03:00
iRet = TRAIN_MEDIUM ;
else
iRet = TRAIN_FAST ;
return iRet ;
}
2021-08-29 07:12:25 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , DeathSound )
void EXT_FUNC CBasePlayer : : __API_HOOK ( DeathSound ) ( )
2015-09-30 03:49:22 +03:00
{
// temporarily using pain sounds for death sounds
switch ( RANDOM_LONG ( 1 , 4 ) )
{
case 1 : EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/die1.wav " , VOL_NORM , ATTN_NORM ) ; break ;
case 2 : EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/die2.wav " , VOL_NORM , ATTN_NORM ) ; break ;
case 3 : EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/die3.wav " , VOL_NORM , ATTN_NORM ) ; break ;
case 4 : EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/death6.wav " , VOL_NORM , ATTN_NORM ) ; break ;
}
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CHAIN ( BOOL , CBasePlayer , TakeHealth , ( float flHealth , int bitsDamageType ) , flHealth , bitsDamageType )
2016-04-05 03:12:05 +03:00
2015-09-30 03:49:22 +03:00
// override takehealth
// bitsDamageType indicates type of damage healed.
2017-07-01 23:40:10 +03:00
BOOL EXT_FUNC CBasePlayer : : __API_HOOK ( TakeHealth ) ( float flHealth , int bitsDamageType )
2015-09-30 03:49:22 +03:00
{
return CBaseMonster : : TakeHealth ( flHealth , bitsDamageType ) ;
}
2017-07-01 23:40:10 +03:00
Vector CBasePlayer : : GetGunPosition ( )
2015-09-30 03:49:22 +03:00
{
return pev - > origin + pev - > view_ofs ;
}
bool CBasePlayer : : IsHittingShield ( Vector & vecDirection , TraceResult * ptr )
{
2016-12-06 22:21:52 +03:00
if ( ( m_pActiveItem & & m_pActiveItem - > m_iId = = WEAPON_C4 ) | | ! HasShield ( ) )
2015-09-30 03:49:22 +03:00
return false ;
if ( ptr - > iHitgroup = = HITGROUP_SHIELD )
2017-11-01 18:01:24 +03:00
return true ;
2015-09-30 03:49:22 +03:00
if ( m_bShieldDrawn )
UTIL_MakeVectors ( pev - > angles ) ;
return false ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , TraceAttack , ( entvars_t * pevAttacker , float flDamage , Vector vecDir , TraceResult * ptr , int bitsDamageType ) , pevAttacker , flDamage , vecDir , ptr , bitsDamageType )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( TraceAttack ) ( entvars_t * pevAttacker , float flDamage , VectorRef vecDir , TraceResult * ptr , int bitsDamageType )
2015-09-30 03:49:22 +03:00
{
bool bShouldBleed = true ;
bool bShouldSpark = false ;
bool bHitShield = IsHittingShield ( vecDir , ptr ) ;
2016-06-14 01:13:13 +03:00
CBasePlayer * pAttacker = CBasePlayer : : Instance ( pevAttacker ) ;
2018-05-31 10:53:34 +03:00
2016-06-18 17:48:19 +03:00
# ifdef REGAMEDLL_ADD
2018-05-31 10:53:34 +03:00
if ( pAttacker & & pAttacker - > IsPlayer ( ) )
{
// don't take damage if victim has protection
if ( CSPlayer ( ) - > GetProtectionState ( ) = = CCSPlayer : : ProtectionSt_Active )
return ;
if ( ! CSGameRules ( ) - > FPlayerCanTakeDamage ( this , pAttacker ) )
bShouldBleed = false ;
}
2016-06-18 17:48:19 +03:00
# else
2016-12-06 22:21:52 +03:00
if ( pAttacker & & pAttacker - > IsPlayer ( ) & & m_iTeam = = pAttacker - > m_iTeam & & ! friendlyfire . value )
2016-02-04 03:18:26 +03:00
bShouldBleed = false ;
2016-06-18 17:48:19 +03:00
# endif
2015-09-30 03:49:22 +03:00
if ( pev - > takedamage = = DAMAGE_NO )
return ;
m_LastHitGroup = ptr - > iHitgroup ;
if ( bHitShield )
{
flDamage = 0 ;
bShouldBleed = false ;
if ( RANDOM_LONG ( 0 , 1 ) )
EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " weapons/ric_metal-1.wav " , VOL_NORM , ATTN_NORM ) ;
else
EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " weapons/ric_metal-2.wav " , VOL_NORM , ATTN_NORM ) ;
UTIL_Sparks ( ptr - > vecEndPos ) ;
pev - > punchangle . x = flDamage * RANDOM_FLOAT ( - 0.15 , 0.15 ) ;
pev - > punchangle . z = flDamage * RANDOM_FLOAT ( - 0.15 , 0.15 ) ;
if ( pev - > punchangle . x < 4 )
pev - > punchangle . x = - 4 ;
if ( pev - > punchangle . z < - 5 )
pev - > punchangle . z = - 5 ;
else if ( pev - > punchangle . z > 5 )
pev - > punchangle . z = 5 ;
}
else
{
switch ( ptr - > iHitgroup )
{
2015-12-29 01:54:08 +03:00
case HITGROUP_GENERIC :
break ;
2015-09-30 03:49:22 +03:00
2015-12-29 01:54:08 +03:00
case HITGROUP_HEAD :
{
2016-05-17 21:01:46 +03:00
if ( m_iKevlar = = ARMOR_VESTHELM )
2015-09-30 03:49:22 +03:00
{
2015-12-29 01:54:08 +03:00
bShouldBleed = false ;
bShouldSpark = true ;
}
2015-09-30 03:49:22 +03:00
2015-12-29 01:54:08 +03:00
flDamage * = 4 ;
if ( bShouldBleed )
{
pev - > punchangle . x = flDamage * - 0.5 ;
2015-09-30 03:49:22 +03:00
2015-12-29 01:54:08 +03:00
if ( pev - > punchangle . x < - 12 )
pev - > punchangle . x = - 12 ;
2015-09-30 03:49:22 +03:00
2015-12-29 01:54:08 +03:00
pev - > punchangle . z = flDamage * RANDOM_FLOAT ( - 1 , 1 ) ;
2015-09-30 03:49:22 +03:00
2015-12-29 01:54:08 +03:00
if ( pev - > punchangle . z < - 9 )
pev - > punchangle . z = - 9 ;
2015-09-30 03:49:22 +03:00
2015-12-29 01:54:08 +03:00
else if ( pev - > punchangle . z > 9 )
pev - > punchangle . z = 9 ;
2015-09-30 03:49:22 +03:00
}
2015-12-29 01:54:08 +03:00
break ;
}
case HITGROUP_CHEST :
{
flDamage * = 1 ;
2015-09-30 03:49:22 +03:00
2016-05-17 21:01:46 +03:00
if ( m_iKevlar ! = ARMOR_NONE )
2015-12-29 01:54:08 +03:00
bShouldBleed = false ;
2015-09-30 03:49:22 +03:00
2015-12-29 01:54:08 +03:00
else if ( bShouldBleed )
2015-09-30 03:49:22 +03:00
{
2015-12-29 01:54:08 +03:00
pev - > punchangle . x = flDamage * - 0.1 ;
2015-09-30 03:49:22 +03:00
2015-12-29 01:54:08 +03:00
if ( pev - > punchangle . x < - 4 )
pev - > punchangle . x = - 4 ;
}
break ;
}
case HITGROUP_STOMACH :
{
flDamage * = 1.25 ;
2015-09-30 03:49:22 +03:00
2016-05-17 21:01:46 +03:00
if ( m_iKevlar ! = ARMOR_NONE )
2015-12-29 01:54:08 +03:00
bShouldBleed = false ;
2015-09-30 03:49:22 +03:00
2015-12-29 01:54:08 +03:00
else if ( bShouldBleed )
2015-09-30 03:49:22 +03:00
{
2015-12-29 01:54:08 +03:00
pev - > punchangle . x = flDamage * - 0.1 ;
2015-09-30 03:49:22 +03:00
2015-12-29 01:54:08 +03:00
if ( pev - > punchangle . x < - 4 )
pev - > punchangle . x = - 4 ;
2015-09-30 03:49:22 +03:00
}
2015-12-29 01:54:08 +03:00
break ;
}
case HITGROUP_LEFTARM :
case HITGROUP_RIGHTARM :
{
2016-05-17 21:01:46 +03:00
if ( m_iKevlar ! = ARMOR_NONE )
2015-12-29 01:54:08 +03:00
bShouldBleed = false ;
break ;
}
case HITGROUP_LEFTLEG :
case HITGROUP_RIGHTLEG :
{
flDamage * = 0.75 ;
break ;
}
2015-09-30 03:49:22 +03:00
}
}
if ( bShouldBleed )
{
BloodSplat ( ptr - > vecEndPos , vecDir , ptr - > iHitgroup , flDamage * 5 ) ;
SpawnBlood ( ptr - > vecEndPos , BloodColor ( ) , flDamage ) ; // a little surface blood.
TraceBleed ( flDamage , vecDir , ptr , bitsDamageType ) ;
}
// they hit a helmet
else if ( ptr - > iHitgroup = = HITGROUP_HEAD & & bShouldSpark )
{
MESSAGE_BEGIN ( MSG_PVS , SVC_TEMPENTITY , ptr - > vecEndPos ) ;
WRITE_BYTE ( TE_STREAK_SPLASH ) ;
WRITE_COORD ( ptr - > vecEndPos . x ) ;
WRITE_COORD ( ptr - > vecEndPos . y ) ;
WRITE_COORD ( ptr - > vecEndPos . z ) ;
WRITE_COORD ( ptr - > vecPlaneNormal . x ) ;
WRITE_COORD ( ptr - > vecPlaneNormal . y ) ;
WRITE_COORD ( ptr - > vecPlaneNormal . z ) ;
WRITE_BYTE ( 5 ) ; // color
WRITE_SHORT ( 22 ) ; // count
WRITE_SHORT ( 25 ) ; // base speed
WRITE_SHORT ( 65 ) ; // ramdon velocity
MESSAGE_END ( ) ;
}
AddMultiDamage ( pevAttacker , this , flDamage , bitsDamageType ) ;
}
2023-09-28 12:18:15 +03:00
const char * CBasePlayer : : GetKillerWeaponName ( entvars_t * pevInflictor , entvars_t * pevKiller ) const
2015-09-30 03:49:22 +03:00
{
2016-06-14 01:13:13 +03:00
// by default, the player is killed by the world
2015-09-30 03:49:22 +03:00
const char * killer_weapon_name = " world " ;
2016-06-14 01:13:13 +03:00
// Is the killer a client?
2023-09-28 12:18:15 +03:00
if ( pevKiller - > flags & FL_CLIENT )
2015-09-30 03:49:22 +03:00
{
if ( pevInflictor )
{
2023-09-28 12:18:15 +03:00
if ( pevInflictor = = pevKiller )
2015-09-30 03:49:22 +03:00
{
2023-09-28 12:18:15 +03:00
# ifdef REGAMEDLL_FIXES
// Ignore the inflictor's weapon if victim killed self
if ( pevKiller ! = pev )
# endif
2015-09-30 03:49:22 +03:00
{
2023-09-28 12:18:15 +03:00
// If the inflictor is the killer, then it must be their current weapon doing the damage
CBasePlayer * pAttacker = CBasePlayer : : Instance ( pevKiller ) ;
if ( pAttacker & & pAttacker - > IsPlayer ( ) )
{
if ( pAttacker - > m_pActiveItem )
killer_weapon_name = pAttacker - > m_pActiveItem - > pszName ( ) ;
}
2015-09-30 03:49:22 +03:00
}
}
else
2016-06-14 01:13:13 +03:00
{
// it's just that easy
2015-09-30 03:49:22 +03:00
killer_weapon_name = STRING ( pevInflictor - > classname ) ;
2016-06-14 01:13:13 +03:00
}
2015-09-30 03:49:22 +03:00
}
}
else
2016-06-14 01:13:13 +03:00
# ifdef REGAMEDLL_FIXES
if ( pevInflictor )
# endif
{
2015-09-30 03:49:22 +03:00
killer_weapon_name = STRING ( pevInflictor - > classname ) ;
2016-06-14 01:13:13 +03:00
}
// strip the monster_* or weapon_* from the inflictor's classname
2023-09-28 12:18:15 +03:00
const char cut_weapon [ ] = " weapon_ " ;
2016-06-14 01:13:13 +03:00
const char cut_monster [ ] = " monster_ " ;
2023-09-28 12:18:15 +03:00
const char cut_func [ ] = " func_ " ;
2015-09-30 03:49:22 +03:00
2023-09-28 12:18:15 +03:00
// replace the code names with the 'real' names
2016-06-14 01:13:13 +03:00
if ( ! Q_strncmp ( killer_weapon_name , cut_weapon , sizeof ( cut_weapon ) - 1 ) )
killer_weapon_name + = sizeof ( cut_weapon ) - 1 ;
2015-09-30 03:49:22 +03:00
2016-06-14 01:13:13 +03:00
else if ( ! Q_strncmp ( killer_weapon_name , cut_monster , sizeof ( cut_monster ) - 1 ) )
killer_weapon_name + = sizeof ( cut_monster ) - 1 ;
2015-09-30 03:49:22 +03:00
2016-06-14 01:13:13 +03:00
else if ( ! Q_strncmp ( killer_weapon_name , cut_func , sizeof ( cut_func ) - 1 ) )
killer_weapon_name + = sizeof ( cut_func ) - 1 ;
2015-09-30 03:49:22 +03:00
return killer_weapon_name ;
}
void LogAttack ( CBasePlayer * pAttacker , CBasePlayer * pVictim , int teamAttack , int healthHit , int armorHit , int newHealth , int newArmor , const char * killer_weapon_name )
{
int detail = logdetail . value ;
if ( ! detail )
return ;
if ( ! pAttacker | | ! pVictim )
return ;
if ( ( teamAttack & & ( detail & LOG_TEAMMATEATTACK ) ) | | ( ! teamAttack & & ( detail & LOG_ENEMYATTACK ) ) )
{
2016-02-23 02:13:52 +03:00
UTIL_LogPrintf ( " \" %s<%i><%s><%s> \" attacked \" %s<%i><%s><%s> \" with \" %s \" (damage \" %d \" ) (damage_armor \" %d \" ) (health \" %d \" ) (armor \" %d \" ) \n " ,
STRING ( pAttacker - > pev - > netname ) , GETPLAYERUSERID ( pAttacker - > edict ( ) ) , GETPLAYERAUTHID ( pAttacker - > edict ( ) ) , GetTeam ( pAttacker - > m_iTeam ) ,
STRING ( pVictim - > pev - > netname ) , GETPLAYERUSERID ( pVictim - > edict ( ) ) , GETPLAYERAUTHID ( pVictim - > edict ( ) ) ,
GetTeam ( pVictim - > m_iTeam ) , killer_weapon_name , healthHit , armorHit , newHealth , newArmor ) ;
2015-09-30 03:49:22 +03:00
}
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CHAIN ( BOOL , CBasePlayer , TakeDamage , ( entvars_t * pevInflictor , entvars_t * pevAttacker , float flDamage , int bitsDamageType ) , pevInflictor , pevAttacker , flDamage , bitsDamageType )
2016-04-05 03:12:05 +03:00
2015-09-30 03:49:22 +03:00
// Take some damage.
2016-06-18 17:48:19 +03:00
// RETURN: TRUE took damage, FALSE otherwise
2015-09-30 03:49:22 +03:00
// NOTE: each call to TakeDamage with bitsDamageType set to a time-based damage
// type will cause the damage time countdown to be reset. Thus the ongoing effects of poison, radiation
// etc are implemented with subsequent calls to TakeDamage using DMG_GENERIC.
2017-07-01 23:40:10 +03:00
BOOL EXT_FUNC CBasePlayer : : __API_HOOK ( TakeDamage ) ( entvars_t * pevInflictor , entvars_t * pevAttacker , FloatRef flDamage , int bitsDamageType )
2015-09-30 03:49:22 +03:00
{
2016-06-18 17:48:19 +03:00
BOOL bTookDamage ;
2015-09-30 03:49:22 +03:00
float flRatio = ARMOR_RATIO ;
float flBonus = ARMOR_BONUS ;
int iGunType = 0 ;
float flShieldRatio = 0 ;
2016-02-23 02:13:52 +03:00
BOOL bTeamAttack = FALSE ;
2015-09-30 03:49:22 +03:00
int armorHit = 0 ;
2016-06-14 01:13:13 +03:00
CBasePlayer * pAttack = nullptr ;
2015-09-30 03:49:22 +03:00
2018-05-31 10:53:34 +03:00
# ifdef REGAMEDLL_ADD
{
CBaseEntity * pAttacker = GET_PRIVATE < CBaseEntity > ( ENT ( pevAttacker ) ) ;
// don't take damage if victim has protection
2021-04-12 15:55:03 +03:00
if ( ( ( pAttacker & & pAttacker - > IsPlayer ( ) ) | | ( bitsDamageType & DMG_FALL ) ) & & CSPlayer ( ) - > GetProtectionState ( ) = = CCSPlayer : : ProtectionSt_Active )
2018-05-31 10:53:34 +03:00
return FALSE ;
}
# endif
2015-09-30 03:49:22 +03:00
if ( bitsDamageType & ( DMG_EXPLOSION | DMG_BLAST | DMG_FALL ) )
m_LastHitGroup = HITGROUP_GENERIC ;
else if ( m_LastHitGroup = = HITGROUP_SHIELD & & ( bitsDamageType & DMG_BULLET ) )
2016-06-18 17:48:19 +03:00
return FALSE ;
2015-09-30 03:49:22 +03:00
if ( HasShield ( ) )
flShieldRatio = 0.2 ;
if ( m_bIsVIP )
flRatio * = 0.5 ;
if ( bitsDamageType & ( DMG_EXPLOSION | DMG_BLAST ) )
{
if ( ! IsAlive ( ) )
2016-06-18 17:48:19 +03:00
return FALSE ;
2015-09-30 03:49:22 +03:00
if ( bitsDamageType & DMG_EXPLOSION )
{
2016-03-17 20:44:52 +03:00
CBaseEntity * temp = GetClassPtr < CCSEntity > ( ( CBaseEntity * ) pevInflictor ) ;
2017-01-20 17:52:37 +03:00
if ( FClassnameIs ( temp - > pev , " grenade " ) )
2015-09-30 03:49:22 +03:00
{
2016-03-17 20:44:52 +03:00
CGrenade * pGrenade = GetClassPtr < CCSGrenade > ( ( CGrenade * ) pevInflictor ) ;
2015-09-30 03:49:22 +03:00
2019-06-08 19:22:56 +03:00
pAttack = CBasePlayer : : Instance ( pevAttacker ) ;
if (
# ifdef REGAMEDLL_ADD
! CSGameRules ( ) - > IsFreeForAll ( ) & &
# endif
pGrenade - > m_iTeam = = m_iTeam )
2015-09-30 03:49:22 +03:00
{
2019-06-08 19:22:56 +03:00
if ( friendlyfire . value )
{
2016-02-23 02:13:52 +03:00
bTeamAttack = TRUE ;
2019-06-06 00:33:16 +03:00
# ifdef REGAMEDLL_ADD
2019-06-08 19:22:56 +03:00
flDamage * = clamp ( ( ( pAttack = = this ) ?
ff_damage_reduction_grenade_self . value :
ff_damage_reduction_grenade . value ) , 0.0f , 1.0f ) ;
2019-06-06 00:33:16 +03:00
# endif
2019-06-08 19:22:56 +03:00
}
else if ( pAttack = = this )
{
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_ADD
2019-06-08 19:22:56 +03:00
flDamage * = clamp ( ff_damage_reduction_grenade_self . value , 0.0f , 1.0f ) ;
2016-12-06 22:21:52 +03:00
# endif
2019-06-08 19:22:56 +03:00
}
else
2019-06-06 00:20:19 +03:00
{
2019-06-08 19:22:56 +03:00
// if cvar friendlyfire is disabled
// and if the victim is teammate then ignore this damage
2019-06-06 00:20:19 +03:00
return FALSE ;
}
2015-09-30 03:49:22 +03:00
}
}
}
if ( ! FNullEnt ( ENT ( pevInflictor ) ) )
m_vBlastVector = pev - > origin - pevInflictor - > origin ;
if ( pev - > armorvalue ! = 0.0f & & IsArmored ( m_LastHitGroup ) )
{
2017-11-22 20:27:55 +03:00
real_t flNew = flRatio * flDamage ;
real_t flArmor = ( flDamage - flNew ) * flBonus ;
2015-09-30 03:49:22 +03:00
// Does this use more armor than we have?
if ( flArmor > pev - > armorvalue )
{
flNew = flDamage - pev - > armorvalue ;
armorHit = flArmor ;
pev - > armorvalue = 0 ;
}
else
{
int oldValue = pev - > armorvalue ;
if ( flArmor < 0.0 )
flArmor = 1.0 ;
pev - > armorvalue - = flArmor ;
armorHit = oldValue - pev - > armorvalue ;
}
flDamage = flNew ;
if ( pev - > armorvalue < = 0.0 )
2016-05-17 21:01:46 +03:00
m_iKevlar = ARMOR_NONE ;
2015-09-30 03:49:22 +03:00
Pain ( m_LastHitGroup , true ) ;
}
else
2017-11-22 20:27:55 +03:00
{
2015-09-30 03:49:22 +03:00
Pain ( m_LastHitGroup , false ) ;
2017-11-22 20:27:55 +03:00
}
2015-09-30 03:49:22 +03:00
m_lastDamageAmount = flDamage ;
if ( pev - > health > flDamage )
{
SetAnimation ( PLAYER_FLINCH ) ;
Pain ( m_LastHitGroup , false ) ;
}
else
{
if ( bitsDamageType & DMG_BLAST )
m_bKilledByBomb = true ;
else if ( bitsDamageType & DMG_EXPLOSION )
m_bKilledByGrenade = true ;
}
2023-09-28 12:18:15 +03:00
LogAttack ( pAttack , this , bTeamAttack , int ( flDamage ) , armorHit , pev - > health - flDamage , pev - > armorvalue , GetKillerWeaponName ( pevInflictor , pevAttacker ) ) ;
2016-06-18 17:48:19 +03:00
bTookDamage = CBaseMonster : : TakeDamage ( pevInflictor , pevAttacker , int ( flDamage ) , bitsDamageType ) ;
2015-09-30 03:49:22 +03:00
2016-06-18 17:48:19 +03:00
if ( bTookDamage )
2015-09-30 03:49:22 +03:00
{
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-12-05 22:40:30 +03:00
{
2015-09-30 03:49:22 +03:00
TheBots - > OnEvent ( EVENT_PLAYER_TOOK_DAMAGE , this , pAttack ) ;
2015-12-05 22:40:30 +03:00
}
2015-09-30 03:49:22 +03:00
2017-11-22 20:27:55 +03:00
if ( TheCareerTasks )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayerAttacker = CBasePlayer : : Instance ( pevAttacker ) ;
if ( pPlayerAttacker & & ! pPlayerAttacker - > IsBot ( ) & & pPlayerAttacker - > m_iTeam ! = m_iTeam )
2015-09-30 03:49:22 +03:00
{
2023-09-28 12:18:15 +03:00
TheCareerTasks - > HandleEnemyInjury ( GetKillerWeaponName ( pevInflictor , pevAttacker ) , pPlayerAttacker - > HasShield ( ) , pPlayerAttacker ) ;
2015-09-30 03:49:22 +03:00
}
}
2023-09-28 12:18:15 +03:00
# ifdef REGAMEDLL_API
CSPlayer ( ) - > RecordDamage ( pAttack , flDamage ) ;
# endif
2015-09-30 03:49:22 +03:00
}
{
// reset damage time countdown for each type of time based damage player just sustained
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < ITBD_END ; i + + )
2015-09-30 03:49:22 +03:00
{
if ( bitsDamageType & ( DMG_PARALYZE < < i ) )
m_rgbTimeBasedDamage [ i ] = 0 ;
}
}
// tell director about it
MESSAGE_BEGIN ( MSG_SPEC , SVC_DIRECTOR ) ;
2017-10-19 20:12:02 +03:00
WRITE_BYTE ( 9 ) ; // command length in bytes
WRITE_BYTE ( DRC_CMD_EVENT ) ; // take damage event
WRITE_SHORT ( ENTINDEX ( edict ( ) ) ) ; // index number of primary entity
WRITE_SHORT ( ENTINDEX ( ENT ( pevInflictor ) ) ) ; // index number of secondary entity
WRITE_LONG ( 5 ) ; // eventflags (priority and flags)
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_SPEC , gmsgHLTV ) ;
WRITE_BYTE ( ENTINDEX ( edict ( ) ) ) ;
2016-02-23 02:13:52 +03:00
WRITE_BYTE ( int ( Q_max ( pev - > health , 0.0f ) ) | DRC_FLAG_FACEPLAYER ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
2017-10-13 03:04:37 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
2015-09-30 03:49:22 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
2015-09-30 03:49:22 +03:00
if ( ! pPlayer | | pPlayer - > m_hObserverTarget ! = this )
continue ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgSpecHealth , nullptr , pPlayer - > edict ( ) ) ;
2016-02-23 02:13:52 +03:00
WRITE_BYTE ( int ( Q_max ( pev - > health , 0.0f ) ) ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
2016-06-18 17:48:19 +03:00
return bTookDamage ;
2015-09-30 03:49:22 +03:00
}
2017-11-22 20:27:55 +03:00
CBaseEntity * pAttacker = CBaseEntity : : Instance ( pevAttacker ) ;
2015-09-30 03:49:22 +03:00
2017-01-20 17:52:37 +03:00
if ( ! g_pGameRules - > FPlayerCanTakeDamage ( this , pAttacker ) & & ! FClassnameIs ( pevInflictor , " grenade " ) )
2015-09-30 03:49:22 +03:00
{
// Refuse the damage
2016-06-18 17:48:19 +03:00
return FALSE ;
2015-09-30 03:49:22 +03:00
}
2016-12-06 22:21:52 +03:00
if ( ( bitsDamageType & DMG_BLAST ) & & g_pGameRules - > IsMultiplayer ( ) )
2015-09-30 03:49:22 +03:00
{
// blasts damage armor more.
flBonus * = 2 ;
}
// Already dead
if ( ! IsAlive ( ) )
2016-06-18 17:48:19 +03:00
return FALSE ;
2015-09-30 03:49:22 +03:00
2016-03-17 20:44:52 +03:00
pAttacker = GetClassPtr < CCSEntity > ( ( CBaseEntity * ) pevAttacker ) ;
2015-09-30 03:49:22 +03:00
2023-09-30 10:54:32 +03:00
if ( pAttacker - > IsPlayer ( ) & & ! ( pAttacker = = this & & ( bitsDamageType & DMG_FALL ) ) )
2015-09-30 03:49:22 +03:00
{
2016-03-17 20:44:52 +03:00
pAttack = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pevAttacker ) ;
2015-09-30 03:49:22 +03:00
2016-01-06 15:50:26 +03:00
// warn about team attacks
2021-04-12 15:55:03 +03:00
if ( g_pGameRules - > PlayerRelationship ( this , pAttack ) = = GR_TEAMMATE )
2015-09-30 03:49:22 +03:00
{
2019-06-08 19:22:56 +03:00
if ( pAttack ! = this )
2015-09-30 03:49:22 +03:00
{
2019-06-08 19:22:56 +03:00
# ifndef REGAMEDLL_FIXES
if ( ! ( m_flDisplayHistory & DHF_FRIEND_INJURED ) )
{
m_flDisplayHistory | = DHF_FRIEND_INJURED ;
pAttack - > HintMessage ( " #Hint_try_not_to_injure_teammates " ) ;
}
2016-01-06 15:50:26 +03:00
# else
2019-06-08 19:22:56 +03:00
if ( ! ( pAttack - > m_flDisplayHistory & DHF_FRIEND_INJURED ) )
{
pAttack - > m_flDisplayHistory | = DHF_FRIEND_INJURED ;
pAttack - > HintMessage ( " #Hint_try_not_to_injure_teammates " ) ;
}
2016-02-23 02:13:52 +03:00
# endif
2015-09-30 03:49:22 +03:00
2019-06-08 19:22:56 +03:00
bTeamAttack = TRUE ;
if ( gpGlobals - > time > pAttack - > m_flLastAttackedTeammate + 0.6f )
2015-09-30 03:49:22 +03:00
{
2019-06-08 19:22:56 +03:00
CBaseEntity * pEntity = nullptr ;
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
{
if ( FNullEnt ( pEntity - > edict ( ) ) )
break ;
2015-09-30 03:49:22 +03:00
2019-06-08 19:22:56 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
2015-09-30 03:49:22 +03:00
2019-06-08 19:22:56 +03:00
if ( pPlayer - > m_iTeam = = m_iTeam )
{
ClientPrint ( pPlayer - > pev , HUD_PRINTTALK , " #Game_teammate_attack " , STRING ( pAttack - > pev - > netname ) ) ;
}
2015-09-30 03:49:22 +03:00
}
2019-06-08 19:22:56 +03:00
pAttack - > m_flLastAttackedTeammate = gpGlobals - > time ;
}
2015-09-30 03:49:22 +03:00
2019-06-06 00:20:19 +03:00
# ifdef REGAMEDLL_ADD
2023-09-29 20:18:37 +03:00
// bullets hurt teammates less
flDamage * = clamp ( ( ( bitsDamageType & DMG_BULLET ) ?
ff_damage_reduction_bullets . value :
ff_damage_reduction_other . value ) , 0.0f , 1.0f ) ;
2019-06-06 00:20:19 +03:00
# endif // #ifdef REGAMEDLL_ADD
2023-09-29 20:18:37 +03:00
}
# ifndef REGAMEDLL_ADD
flDamage * = 0.35 ;
# endif
2016-01-06 15:50:26 +03:00
}
2015-09-30 03:49:22 +03:00
if ( pAttack - > m_pActiveItem )
{
2016-01-06 12:09:50 +03:00
iGunType = pAttack - > m_pActiveItem - > m_iId ;
2015-09-30 03:49:22 +03:00
flRatio + = flShieldRatio ;
2016-01-06 15:50:26 +03:00
2015-09-30 03:49:22 +03:00
switch ( iGunType )
{
case WEAPON_AUG :
2017-10-12 17:50:56 +03:00
case WEAPON_M4A1 : flRatio * = 1.4 ; break ;
case WEAPON_AWP : flRatio * = 1.95 ; break ;
case WEAPON_G3SG1 : flRatio * = 1.65 ; break ;
case WEAPON_SG550 : flRatio * = 1.45 ; break ;
case WEAPON_M249 : flRatio * = 1.5 ; break ;
case WEAPON_ELITE : flRatio * = 1.05 ; break ;
case WEAPON_DEAGLE : flRatio * = 1.5 ; break ;
2015-09-30 03:49:22 +03:00
case WEAPON_GLOCK18 : flRatio * = 1.05 ; break ;
case WEAPON_FIVESEVEN :
2017-10-12 17:50:56 +03:00
case WEAPON_P90 :
flRatio * = 1.5 ;
break ;
case WEAPON_MAC10 :
flRatio * = 0.95 ;
break ;
case WEAPON_P228 :
flRatio * = 1.25 ;
break ;
2015-09-30 03:49:22 +03:00
case WEAPON_SCOUT :
2017-10-12 17:50:56 +03:00
case WEAPON_KNIFE :
flRatio * = 1.7 ;
break ;
2015-09-30 03:49:22 +03:00
case WEAPON_FAMAS :
2017-10-12 17:50:56 +03:00
case WEAPON_SG552 :
flRatio * = 1.4 ;
break ;
2015-09-30 03:49:22 +03:00
case WEAPON_GALIL :
2017-10-12 17:50:56 +03:00
case WEAPON_AK47 :
flRatio * = 1.55 ;
break ;
2015-09-30 03:49:22 +03:00
}
}
if ( ! ShouldDoLargeFlinch ( m_LastHitGroup , iGunType ) )
{
m_flVelocityModifier = 0.5f ;
if ( m_LastHitGroup = = HITGROUP_HEAD )
m_bHighDamage = ( flDamage > 60 ) ;
else
m_bHighDamage = ( flDamage > 20 ) ;
SetAnimation ( PLAYER_FLINCH ) ;
}
else
{
if ( pev - > velocity . Length ( ) < 300 )
{
Vector attack_velocity = ( pev - > origin - pAttack - > pev - > origin ) . Normalize ( ) * 170 ;
pev - > velocity = pev - > velocity + attack_velocity ;
m_flVelocityModifier = 0.65f ;
}
2017-11-22 20:27:55 +03:00
2015-09-30 03:49:22 +03:00
SetAnimation ( PLAYER_LARGE_FLINCH ) ;
}
}
// Armor
// armor doesn't protect against fall or drown damage!
if ( pev - > armorvalue ! = 0.0f & & ! ( bitsDamageType & ( DMG_DROWN | DMG_FALL ) ) & & IsArmored ( m_LastHitGroup ) )
{
2017-11-22 20:27:55 +03:00
real_t flNew = flRatio * flDamage ;
real_t flArmor = ( flDamage - flNew ) * flBonus ;
2015-09-30 03:49:22 +03:00
// Does this use more armor than we have?
if ( flArmor > pev - > armorvalue )
{
armorHit = flArmor ;
flArmor = pev - > armorvalue ;
flArmor * = ( 1 / flBonus ) ;
flNew = flDamage - flArmor ;
pev - > armorvalue = 0 ;
}
else
{
int oldValue = pev - > armorvalue ;
if ( flArmor < 0.0 )
flArmor = 1.0 ;
pev - > armorvalue - = flArmor ;
armorHit = oldValue - pev - > armorvalue ;
}
flDamage = flNew ;
if ( pev - > armorvalue < = 0.0f )
2016-05-17 21:01:46 +03:00
m_iKevlar = ARMOR_NONE ;
2015-09-30 03:49:22 +03:00
Pain ( m_LastHitGroup , true ) ;
}
else
2017-11-22 20:27:55 +03:00
{
2015-09-30 03:49:22 +03:00
Pain ( m_LastHitGroup , false ) ;
2017-11-22 20:27:55 +03:00
}
2023-09-28 12:18:15 +03:00
2023-09-05 06:53:22 +03:00
// keep track of amount of damage last sustained
m_lastDamageAmount = flDamage ;
2023-09-28 12:18:15 +03:00
LogAttack ( pAttack , this , bTeamAttack , flDamage , armorHit , pev - > health - flDamage , pev - > armorvalue , GetKillerWeaponName ( pevInflictor , pevAttacker ) ) ;
2015-09-30 03:49:22 +03:00
// this cast to INT is critical!!! If a player ends up with 0.5 health, the engine will get that
// as an int (zero) and think the player is dead! (this will incite a clientside screentilt, etc)
2016-06-18 17:48:19 +03:00
bTookDamage = CBaseMonster : : TakeDamage ( pevInflictor , pevAttacker , int ( flDamage ) , bitsDamageType ) ;
2015-09-30 03:49:22 +03:00
2016-06-18 17:48:19 +03:00
if ( bTookDamage )
2015-09-30 03:49:22 +03:00
{
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-09-30 03:49:22 +03:00
{
TheBots - > OnEvent ( EVENT_PLAYER_TOOK_DAMAGE , this , pAttack ) ;
}
2017-11-22 20:27:55 +03:00
if ( TheCareerTasks )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayerAttacker = CBasePlayer : : Instance ( pevAttacker ) ;
if ( pPlayerAttacker & & ! pPlayerAttacker - > IsBot ( ) & & pPlayerAttacker - > m_iTeam ! = m_iTeam )
2015-09-30 03:49:22 +03:00
{
2023-09-28 12:18:15 +03:00
TheCareerTasks - > HandleEnemyInjury ( GetKillerWeaponName ( pevInflictor , pevAttacker ) , pPlayerAttacker - > HasShield ( ) , pPlayerAttacker ) ;
2015-09-30 03:49:22 +03:00
}
}
2023-09-28 12:18:15 +03:00
# ifdef REGAMEDLL_API
CSPlayer ( ) - > RecordDamage ( pAttack , flDamage ) ;
# endif
2015-09-30 03:49:22 +03:00
}
{
// reset damage time countdown for each type of time based damage player just sustained
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < ITBD_END ; i + + )
2015-09-30 03:49:22 +03:00
{
if ( bitsDamageType & ( DMG_PARALYZE < < i ) )
m_rgbTimeBasedDamage [ i ] = 0 ;
}
}
// tell director about it
MESSAGE_BEGIN ( MSG_SPEC , SVC_DIRECTOR ) ;
2017-10-19 20:12:02 +03:00
WRITE_BYTE ( 9 ) ; // command length in bytes
WRITE_BYTE ( DRC_CMD_EVENT ) ; // take damage event
WRITE_SHORT ( ENTINDEX ( edict ( ) ) ) ; // index number of primary entity
2015-09-30 03:49:22 +03:00
WRITE_SHORT ( ENTINDEX ( ENT ( pevInflictor ) ) ) ; // index number of secondary entity
2017-10-19 20:12:02 +03:00
WRITE_LONG ( 5 ) ; // eventflags (priority and flags)
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_SPEC , gmsgHLTV ) ;
WRITE_BYTE ( ENTINDEX ( edict ( ) ) ) ;
2016-02-23 02:13:52 +03:00
WRITE_BYTE ( int ( Q_max ( pev - > health , 0.0f ) ) | DRC_FLAG_FACEPLAYER ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
2017-10-13 03:04:37 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
2015-09-30 03:49:22 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
2015-09-30 03:49:22 +03:00
if ( ! pPlayer )
continue ;
if ( pPlayer - > m_hObserverTarget = = this )
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgSpecHealth , nullptr , pPlayer - > edict ( ) ) ;
2016-02-23 02:13:52 +03:00
WRITE_BYTE ( int ( Q_max ( pev - > health , 0.0f ) ) ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
}
2016-12-09 15:39:16 +03:00
# ifdef REGAMEDLL_FIXES
if ( ( bitsDamageType & DMG_DROWN ) & & pev - > waterlevel = = 0 ) {
bitsDamageType & = ~ DMG_DROWN ;
}
# endif
2015-09-30 03:49:22 +03:00
// Save this so we can report it to the client
m_bitsHUDDamage = - 1 ;
// make sure the damage bits get resent
m_bitsDamageType | = bitsDamageType ;
2016-06-18 17:48:19 +03:00
return bTookDamage ;
2015-09-30 03:49:22 +03:00
}
2020-04-02 13:39:29 +03:00
LINK_HOOK_CHAIN ( CWeaponBox * , CreateWeaponBox , ( CBasePlayerItem * pItem , CBasePlayer * pPlayerOwner , const char * modelName , Vector & origin , Vector & angles , Vector & velocity , float lifeTime , bool packAmmo ) , pItem , pPlayerOwner , modelName , origin , angles , velocity , lifeTime , packAmmo )
2020-03-27 05:17:41 +03:00
2020-04-02 13:39:29 +03:00
CWeaponBox * EXT_FUNC __API_HOOK ( CreateWeaponBox ) ( CBasePlayerItem * pItem , CBasePlayer * pPlayerOwner , const char * modelName , Vector & origin , Vector & angles , Vector & velocity , float lifeTime , bool packAmmo )
2015-09-30 03:49:22 +03:00
{
2020-03-27 05:17:41 +03:00
// create a box to pack the stuff into.
2023-11-27 11:22:33 +03:00
CWeaponBox * pWeaponBox = ( CWeaponBox * ) CBaseEntity : : Create ( " weaponbox " , origin , angles , pPlayerOwner ? ENT ( pPlayerOwner - > pev ) : nullptr ) ;
2015-11-06 17:58:48 +03:00
2020-03-27 05:17:41 +03:00
if ( pWeaponBox )
2015-09-30 03:49:22 +03:00
{
2016-05-01 17:33:54 +03:00
// don't let weaponbox tilt.
2015-11-06 17:58:48 +03:00
pWeaponBox - > pev - > angles . x = 0 ;
pWeaponBox - > pev - > angles . z = 0 ;
2020-03-27 05:17:41 +03:00
pWeaponBox - > pev - > velocity = velocity ;
2015-11-06 17:58:48 +03:00
pWeaponBox - > SetThink ( & CWeaponBox : : Kill ) ;
2020-03-27 05:17:41 +03:00
pWeaponBox - > pev - > nextthink = gpGlobals - > time + lifeTime ;
2016-05-01 17:33:54 +03:00
pWeaponBox - > PackWeapon ( pItem ) ; // now pack all of the items in the lists
2015-09-30 03:49:22 +03:00
2024-01-31 15:35:26 +03:00
// player is the ammo source
if ( pPlayerOwner )
2015-11-06 17:58:48 +03:00
{
2023-07-10 15:45:24 +03:00
// by removing ammo ONLY on exhaustible weapons (slot 4 and 5)
// you are allowing to duplicate ammo whenever:
// (1) you have 2 weapons sharing the same ammo type (e.g. mp5navy and glock)
// (2) you are dropping a weapon alive and pickup another (with same ammo type) without ammo
// and, logically, you throw your ammo with your gun with packing enabled
2024-01-31 15:35:26 +03:00
bool exhaustibleAmmo = ( pItem - > iFlags ( ) & ITEM_FLAG_EXHAUSTIBLE ) = = ITEM_FLAG_EXHAUSTIBLE ;
// pack the primary ammo
if ( exhaustibleAmmo | | packAmmo )
{
# ifndef REGAMEDLL_ADD
pWeaponBox - > PackAmmo ( MAKE_STRING ( pItem - > pszAmmo1 ( ) ) , pPlayerOwner - > m_rgAmmo [ pItem - > PrimaryAmmoIndex ( ) ] ) ;
# else
pWeaponBox - > GiveAmmo ( pPlayerOwner - > m_rgAmmo [ pItem - > PrimaryAmmoIndex ( ) ] , ( char * ) pItem - > pszAmmo1 ( ) , pItem - > iMaxAmmo1 ( ) ) ;
# endif
# ifndef REGAMEDLL_FIXES
if ( exhaustibleAmmo )
2023-07-10 15:45:24 +03:00
# endif
2024-01-31 15:35:26 +03:00
{
pPlayerOwner - > m_rgAmmo [ pItem - > PrimaryAmmoIndex ( ) ] = 0 ;
}
}
// (3rd party support) now that reapi can register custom ammo
# ifdef REGAMEDLL_ADD
// use this flag if you don't want the player harvesting this kind of ammo from dropped weapons
bool exhaustSecondaryAmmo = ( pItem - > iFlags ( ) & ITEM_FLAG_EXHAUST_SECONDARYAMMO ) = = ITEM_FLAG_EXHAUST_SECONDARYAMMO ;
int iSecondaryAmmoIndex = pItem - > SecondaryAmmoIndex ( ) ;
// pack secondary ammo now (must be valid too)
if ( ( exhaustibleAmmo | | exhaustSecondaryAmmo | | packAmmo ) & & iSecondaryAmmoIndex ! = - 1 )
2020-03-27 05:17:41 +03:00
{
2024-01-31 15:35:26 +03:00
pWeaponBox - > GiveAmmo ( pPlayerOwner - > m_rgAmmo [ iSecondaryAmmoIndex ] , ( char * ) pItem - > pszAmmo2 ( ) , pItem - > iMaxAmmo2 ( ) ) ;
# ifndef REGAMEDLL_FIXES
if ( exhaustibleAmmo )
# endif
{
pPlayerOwner - > m_rgAmmo [ iSecondaryAmmoIndex ] = 0 ;
}
2020-03-27 05:17:41 +03:00
}
2024-01-31 15:35:26 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
2016-07-20 19:44:00 +03:00
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
pWeaponBox - > SetModel ( modelName ) ;
2015-09-30 03:49:22 +03:00
}
2020-03-27 05:17:41 +03:00
return pWeaponBox ;
}
2023-07-10 15:45:24 +03:00
CWeaponBox * PackPlayerItem ( CBasePlayer * pPlayer , CBasePlayerItem * pItem , bool packAmmo )
2020-03-27 05:17:41 +03:00
{
if ( ! pItem )
2023-07-10 15:45:24 +03:00
return nullptr ;
2020-03-27 05:17:41 +03:00
const char * modelName = GetCSModelName ( pItem - > m_iId ) ;
if ( modelName )
{
2020-04-02 13:39:29 +03:00
Vector vecOrigin = pPlayer - > pev - > origin ;
Vector vecAngles = pPlayer - > pev - > angles ;
Vector vecVelocity = pPlayer - > pev - > velocity * 0.75f ;
2020-03-27 05:17:41 +03:00
// create a box to pack the stuff into
2023-07-10 15:45:24 +03:00
return CreateWeaponBox ( pItem , pPlayer ,
2020-03-27 05:17:41 +03:00
modelName ,
2020-04-02 13:39:29 +03:00
vecOrigin ,
vecAngles ,
vecVelocity ,
2020-03-27 05:17:41 +03:00
CGameRules : : GetItemKillDelay ( ) , packAmmo
) ;
}
2023-07-10 15:45:24 +03:00
return nullptr ;
2015-09-30 03:49:22 +03:00
}
2016-04-07 23:20:45 +03:00
# ifdef REGAMEDLL_ADD
2017-11-01 18:01:24 +03:00
void PackPlayerNade ( CBasePlayer * pPlayer , CBasePlayerItem * pItem , bool packAmmo )
2016-04-07 23:20:45 +03:00
{
2016-06-14 01:13:13 +03:00
if ( ! pItem )
2016-04-07 23:20:45 +03:00
return ;
2019-10-09 13:18:42 +03:00
if ( pItem - > m_flStartThrow ! = 0.0f | | pPlayer - > m_rgAmmo [ pItem - > PrimaryAmmoIndex ( ) ] < = 0 ) {
return ;
}
2016-04-07 23:20:45 +03:00
const char * modelName = GetCSModelName ( pItem - > m_iId ) ;
2016-06-14 01:13:13 +03:00
if ( modelName )
2016-04-07 23:20:45 +03:00
{
float flOffset = 0.0f ;
switch ( pItem - > m_iId )
{
case WEAPON_HEGRENADE :
flOffset = 14.0f ;
break ;
case WEAPON_FLASHBANG :
flOffset = 0.0f ;
break ;
case WEAPON_SMOKEGRENADE :
flOffset = - 14.0f ;
break ;
}
Vector vecAngles = pPlayer - > pev - > angles ;
Vector dir ( Q_cos ( vecAngles . y ) * flOffset , Q_sin ( vecAngles . y ) * flOffset , 0.0f ) ;
vecAngles . x = 0.0f ;
vecAngles . y + = 45.0f ;
2020-04-02 13:39:29 +03:00
Vector vecOrigin = pPlayer - > pev - > origin + dir ;
Vector vecVelocity = pPlayer - > pev - > velocity * 0.75f ;
2016-05-01 17:33:54 +03:00
// create a box to pack the stuff into.
2020-03-27 05:17:41 +03:00
CreateWeaponBox ( pItem , pPlayer ,
modelName ,
2020-04-02 13:39:29 +03:00
vecOrigin ,
2020-03-27 05:17:41 +03:00
vecAngles ,
2020-04-02 13:39:29 +03:00
vecVelocity ,
2020-03-27 05:17:41 +03:00
CGameRules : : GetItemKillDelay ( ) ,
packAmmo ) ;
2016-04-07 23:20:45 +03:00
}
}
# endif
2016-05-01 17:33:54 +03:00
// PackDeadPlayerItems - call this when a player dies to
// pack up the appropriate weapons and ammo items, and to
// destroy anything that shouldn't be packed.
2016-02-04 03:18:26 +03:00
void CBasePlayer : : PackDeadPlayerItems ( )
2015-09-30 03:49:22 +03:00
{
2016-05-01 17:33:54 +03:00
// get the game rules
2023-07-10 15:45:24 +03:00
int iPackGun = g_pGameRules - > DeadPlayerWeapons ( this ) ;
2015-09-30 03:49:22 +03:00
bool bPackAmmo = ( g_pGameRules - > DeadPlayerAmmo ( this ) ! = GR_PLR_DROP_AMMO_NO ) ;
2023-07-10 15:45:24 +03:00
if ( iPackGun ! = GR_PLR_DROP_GUN_NO )
2015-09-30 03:49:22 +03:00
{
2023-07-10 15:45:24 +03:00
bool bSkipPrimSec = false ;
2015-09-30 03:49:22 +03:00
if ( HasShield ( ) )
{
DropShield ( ) ;
2023-07-10 15:45:24 +03:00
# ifdef REGAMEDLL_ADD
if ( iPackGun ! = GR_PLR_DROP_GUN_ALL )
# endif
{
bSkipPrimSec = true ;
}
2015-09-30 03:49:22 +03:00
}
int nBestWeight = 0 ;
2017-10-13 03:04:37 +03:00
CBasePlayerItem * pBestItem = nullptr ;
2015-09-30 03:49:22 +03:00
2023-09-28 12:18:15 +03:00
# ifdef REGAMEDLL_ADD
2023-07-10 15:45:24 +03:00
int iGunsPacked = 0 ;
2023-09-28 12:18:15 +03:00
if ( iPackGun = = GR_PLR_DROP_GUN_ACTIVE )
2015-09-30 03:49:22 +03:00
{
2023-09-28 12:18:15 +03:00
// check if we've just already dropped our active gun
2023-07-10 15:45:24 +03:00
if ( ! bSkipPrimSec & & m_pActiveItem & & m_pActiveItem - > CanDrop ( ) & & m_pActiveItem - > iItemSlot ( ) < KNIFE_SLOT )
{
pBestItem = m_pActiveItem ;
2015-09-30 03:49:22 +03:00
2023-07-10 15:45:24 +03:00
// if active item is undroppable, then nothing is dropped
}
// are we allowing nade drop?
2023-09-28 12:18:15 +03:00
if ( ( int ) nadedrops . value > = 1 )
2023-07-10 15:45:24 +03:00
{
// goto item loop but skip guns
iPackGun = GR_PLR_DROP_GUN_ALL ;
bSkipPrimSec = true ;
}
}
if ( iPackGun = = GR_PLR_DROP_GUN_ALL | | iPackGun = = GR_PLR_DROP_GUN_BEST )
# endif
{
for ( int n = 0 ; n < MAX_ITEM_TYPES ; n + + )
2015-09-30 03:49:22 +03:00
{
2023-07-10 15:45:24 +03:00
// there's a weapon here. Should I pack it?
CBasePlayerItem * pPlayerItem = m_rgpPlayerItems [ n ] ;
while ( pPlayerItem )
2015-09-30 03:49:22 +03:00
{
2023-07-10 15:45:24 +03:00
ItemInfo info ;
if ( pPlayerItem - > iItemSlot ( ) < KNIFE_SLOT & & ! bSkipPrimSec )
{
2020-02-12 14:34:40 +03:00
# ifdef REGAMEDLL_API
2023-07-10 15:45:24 +03:00
if ( pPlayerItem - > CSPlayerItem ( ) - > GetItemInfo ( & info )
2020-02-12 14:34:40 +03:00
# else
2023-07-10 15:45:24 +03:00
if ( pPlayerItem - > GetItemInfo ( & info )
2020-02-12 14:34:40 +03:00
# endif
2023-07-10 15:45:24 +03:00
# ifdef REGAMEDLL_FIXES
& & pPlayerItem - > CanDrop ( ) // needs to be droppable
# endif
)
2015-09-30 03:49:22 +03:00
{
2023-09-28 12:18:15 +03:00
# ifdef REGAMEDLL_ADD
2023-07-10 15:45:24 +03:00
if ( iPackGun = = GR_PLR_DROP_GUN_ALL )
{
CBasePlayerItem * pNext = pPlayerItem - > m_pNext ;
CWeaponBox * pWeaponBox = PackPlayerItem ( this , pPlayerItem , bPackAmmo ) ;
if ( pWeaponBox )
{
// just push a few units in forward to separate them
2023-09-28 12:18:15 +03:00
pWeaponBox - > pev - > velocity = pWeaponBox - > pev - > velocity * ( 1.0 + ( iGunsPacked * 0.2 ) ) ;
2023-07-10 15:45:24 +03:00
iGunsPacked + + ;
}
2023-09-28 12:18:15 +03:00
2023-07-10 15:45:24 +03:00
pPlayerItem = pNext ;
continue ;
}
# endif
if ( info . iWeight > nBestWeight )
{
nBestWeight = info . iWeight ;
pBestItem = pPlayerItem ;
}
2015-09-30 03:49:22 +03:00
}
}
2023-07-10 15:45:24 +03:00
// drop a grenade after death
else if ( pPlayerItem - > iItemSlot ( ) = = GRENADE_SLOT )
2019-10-09 13:18:42 +03:00
{
2023-07-10 15:45:24 +03:00
if ( AreRunningCZero ( ) )
{
2019-10-09 13:18:42 +03:00
# ifdef REGAMEDLL_FIXES
2023-07-10 15:45:24 +03:00
if ( pPlayerItem - > m_flStartThrow = = 0.0f & & m_rgAmmo [ pPlayerItem - > PrimaryAmmoIndex ( ) ] > 0 )
2019-10-09 13:18:42 +03:00
# endif
2023-07-10 15:45:24 +03:00
{
PackPlayerItem ( this , pPlayerItem , true ) ;
}
2019-10-09 13:18:42 +03:00
}
2016-04-07 23:20:45 +03:00
# ifdef REGAMEDLL_ADD
2023-07-10 15:45:24 +03:00
else
2016-04-07 23:20:45 +03:00
{
2023-07-10 15:45:24 +03:00
switch ( ( int ) nadedrops . value )
{
case 1 :
PackPlayerNade ( this , pPlayerItem , true ) ;
break ;
case 2 :
{
CBasePlayerItem * pNext = pPlayerItem - > m_pNext ;
PackPlayerNade ( this , pPlayerItem , true ) ;
pPlayerItem = pNext ;
continue ;
}
}
2016-04-07 23:20:45 +03:00
}
# endif
2023-07-10 15:45:24 +03:00
}
2015-09-30 03:49:22 +03:00
2023-07-10 15:45:24 +03:00
pPlayerItem = pPlayerItem - > m_pNext ;
}
2015-09-30 03:49:22 +03:00
}
}
2016-04-07 23:20:45 +03:00
2017-11-01 18:01:24 +03:00
PackPlayerItem ( this , pBestItem , bPackAmmo ) ;
2015-09-30 03:49:22 +03:00
}
2016-02-23 02:13:52 +03:00
2015-09-30 03:49:22 +03:00
RemoveAllItems ( TRUE ) ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , GiveDefaultItems )
2016-04-07 23:20:45 +03:00
2016-07-14 17:12:17 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( GiveDefaultItems ) ( )
2015-09-30 03:49:22 +03:00
{
RemoveAllItems ( FALSE ) ;
2017-01-29 02:56:29 +03:00
2017-07-25 19:51:04 +03:00
// NOTE: It is already does reset inside RemoveAllItems
2017-01-29 02:56:29 +03:00
# ifndef REGAMEDLL_FIXES
2015-09-30 03:49:22 +03:00
m_bHasPrimary = false ;
2017-01-29 02:56:29 +03:00
# endif
2015-09-30 03:49:22 +03:00
2016-06-22 22:50:14 +03:00
# ifdef REGAMEDLL_ADD
2020-06-17 19:42:40 +03:00
auto GiveWeapon = [ & ] ( int ammo , const char * pszWeaponName ) {
2019-09-22 17:49:52 +03:00
auto pItem = static_cast < CBasePlayerItem * > ( GiveNamedItemEx ( pszWeaponName ) ) ;
if ( pItem ) {
GiveAmmo ( refill_bpammo_weapons . value ! = 0.0f ? pItem - > iMaxAmmo1 ( ) : ammo , pItem - > pszAmmo1 ( ) , pItem - > iMaxAmmo1 ( ) ) ;
2017-07-25 19:51:04 +03:00
}
} ;
2020-06-17 19:42:40 +03:00
bool bGiveKnife = false ;
if ( m_iTeam = = CT )
bGiveKnife = ct_give_player_knife . value ! = 0 ;
else if ( m_iTeam = = TERRORIST )
bGiveKnife = t_give_player_knife . value ! = 0 ;
2016-06-22 22:50:14 +03:00
2020-06-17 19:42:40 +03:00
if ( bGiveKnife & & ! HasRestrictItem ( ITEM_KNIFE , ITEM_TYPE_EQUIPPED ) ) {
GiveNamedItemEx ( " weapon_knife " ) ;
2016-06-22 22:50:14 +03:00
}
2020-06-17 19:42:40 +03:00
const int iAmountOfBPAmmo = m_bIsVIP ? 1 : 2 ; // Give regular the player backpack ammo twice more than to VIP the player
// Give default secondary equipment
2016-06-22 22:50:14 +03:00
{
2020-06-17 19:42:40 +03:00
char * secondaryString = NULL ;
if ( m_iTeam = = CT )
secondaryString = ct_default_weapons_secondary . string ;
else if ( m_iTeam = = TERRORIST )
secondaryString = t_default_weapons_secondary . string ;
if ( secondaryString & & secondaryString [ 0 ] ! = ' \0 ' )
{
secondaryString = SharedParse ( secondaryString ) ;
while ( secondaryString )
{
WeaponInfoStruct * weaponInfo ;
WeaponIdType weaponId = AliasToWeaponID ( SharedGetToken ( ) ) ;
if ( weaponId ! = WEAPON_NONE )
weaponInfo = GetWeaponInfo ( weaponId ) ;
else
weaponInfo = GetWeaponInfo ( SharedGetToken ( ) ) ;
if ( weaponInfo ) {
const auto iItemID = GetItemIdByWeaponId ( weaponInfo - > id ) ;
if ( iItemID ! = ITEM_NONE & & ! HasRestrictItem ( iItemID , ITEM_TYPE_EQUIPPED ) & & IsSecondaryWeapon ( iItemID ) ) {
GiveWeapon ( weaponInfo - > gunClipSize * iAmountOfBPAmmo , weaponInfo - > entityName ) ;
}
}
secondaryString = SharedParse ( secondaryString ) ;
}
2016-06-22 22:50:14 +03:00
}
2020-06-17 19:42:40 +03:00
}
2016-06-22 22:50:14 +03:00
2020-06-17 19:42:40 +03:00
// Give default primary equipment
{
char * primaryString = NULL ;
if ( m_iTeam = = CT )
primaryString = ct_default_weapons_primary . string ;
else if ( m_iTeam = = TERRORIST )
primaryString = t_default_weapons_primary . string ;
if ( primaryString & & primaryString [ 0 ] ! = ' \0 ' )
{
primaryString = SharedParse ( primaryString ) ;
while ( primaryString )
{
WeaponInfoStruct * weaponInfo ;
WeaponIdType weaponId = AliasToWeaponID ( SharedGetToken ( ) ) ;
if ( weaponId ! = WEAPON_NONE )
weaponInfo = GetWeaponInfo ( weaponId ) ;
else
weaponInfo = GetWeaponInfo ( SharedGetToken ( ) ) ;
if ( weaponInfo ) {
const auto iItemID = GetItemIdByWeaponId ( weaponInfo - > id ) ;
if ( iItemID ! = ITEM_NONE & & ! HasRestrictItem ( iItemID , ITEM_TYPE_EQUIPPED ) & & IsPrimaryWeapon ( iItemID ) ) {
GiveWeapon ( weaponInfo - > gunClipSize * iAmountOfBPAmmo , weaponInfo - > entityName ) ;
}
}
primaryString = SharedParse ( primaryString ) ;
}
}
2016-06-22 22:50:14 +03:00
}
2020-06-17 19:42:40 +03:00
// Give the player grenades if he needs them
char * grenadeString = NULL ;
if ( m_iTeam = = CT )
grenadeString = ct_default_grenades . string ;
else if ( m_iTeam = = TERRORIST )
grenadeString = t_default_grenades . string ;
if ( grenadeString & & grenadeString [ 0 ] ! = ' \0 ' )
{
grenadeString = SharedParse ( grenadeString ) ;
while ( grenadeString )
{
WeaponInfoStruct * weaponInfo ;
WeaponIdType weaponId = AliasToWeaponID ( SharedGetToken ( ) ) ;
if ( weaponId ! = WEAPON_NONE )
weaponInfo = GetWeaponInfo ( weaponId ) ;
else
weaponInfo = GetWeaponInfo ( SharedGetToken ( ) ) ;
if ( weaponInfo ) {
const auto iItemID = GetItemIdByWeaponId ( weaponInfo - > id ) ;
if ( iItemID ! = ITEM_NONE & & ! HasRestrictItem ( iItemID , ITEM_TYPE_EQUIPPED ) & & IsGrenadeWeapon ( iItemID ) ) {
GiveNamedItemEx ( weaponInfo - > entityName ) ;
}
}
grenadeString = SharedParse ( grenadeString ) ;
}
2016-06-22 22:50:14 +03:00
}
2020-06-17 19:42:40 +03:00
2016-06-22 22:50:14 +03:00
# else
2015-09-30 03:49:22 +03:00
switch ( m_iTeam )
{
case CT :
GiveNamedItem ( " weapon_knife " ) ;
GiveNamedItem ( " weapon_usp " ) ;
2016-12-06 22:21:52 +03:00
GiveAmmo ( m_bIsVIP ? 12 : 24 , " 45acp " ) ;
2015-09-30 03:49:22 +03:00
break ;
case TERRORIST :
GiveNamedItem ( " weapon_knife " ) ;
GiveNamedItem ( " weapon_glock18 " ) ;
2016-12-06 22:21:52 +03:00
GiveAmmo ( 40 , " 9mm " ) ;
2015-09-30 03:49:22 +03:00
break ;
}
2016-06-22 22:50:14 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
2024-05-08 10:50:53 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , RemoveAllItems , ( BOOL removeSuit ) , removeSuit )
void EXT_FUNC CBasePlayer : : __API_HOOK ( RemoveAllItems ) ( BOOL removeSuit )
2015-09-30 03:49:22 +03:00
{
int i ;
2019-08-29 16:57:12 +03:00
# ifdef REGAMEDLL_FIXES
if ( m_pTank )
{
m_pTank - > Use ( this , this , USE_OFF , 0 ) ;
m_pTank = nullptr ;
}
2019-09-21 14:39:44 +03:00
# endif
2015-09-30 03:49:22 +03:00
if ( m_bHasDefuser )
{
2019-06-21 23:19:32 +03:00
RemoveDefuser ( ) ;
2015-09-30 03:49:22 +03:00
}
if ( m_bHasC4 )
{
m_bHasC4 = false ;
pev - > body = 0 ;
2023-11-26 07:24:29 +03:00
SetBombIcon ( FALSE ) ;
SetProgressBarTime ( 0 ) ;
2015-09-30 03:49:22 +03:00
}
RemoveShield ( ) ;
2016-12-06 22:21:52 +03:00
if ( m_pActiveItem )
2015-09-30 03:49:22 +03:00
{
ResetAutoaim ( ) ;
m_pActiveItem - > Holster ( ) ;
2017-10-13 03:04:37 +03:00
m_pActiveItem = nullptr ;
2015-09-30 03:49:22 +03:00
}
2017-10-13 03:04:37 +03:00
m_pLastItem = nullptr ;
for ( i = 0 ; i < MAX_ITEM_TYPES ; i + + )
2015-09-30 03:49:22 +03:00
{
m_pActiveItem = m_rgpPlayerItems [ i ] ;
2016-07-20 19:44:00 +03:00
while ( m_pActiveItem )
2015-09-30 03:49:22 +03:00
{
CBasePlayerItem * pPendingItem = m_pActiveItem - > m_pNext ;
m_pActiveItem - > Drop ( ) ;
m_pActiveItem = pPendingItem ;
}
2017-10-13 03:04:37 +03:00
m_rgpPlayerItems [ i ] = nullptr ;
2015-09-30 03:49:22 +03:00
}
2017-10-13 03:04:37 +03:00
m_pActiveItem = nullptr ;
2016-05-30 14:19:56 +03:00
m_bHasPrimary = false ;
2015-09-30 03:49:22 +03:00
pev - > viewmodel = 0 ;
pev - > weaponmodel = 0 ;
2020-05-27 04:33:10 +03:00
# ifdef REGAMEDLL_FIXES
// if (m_iFOV != DEFAULT_FOV)
{
pev - > fov = m_iFOV = m_iLastZoom = DEFAULT_FOV ;
m_bResumeZoom = false ;
}
# endif
2015-09-30 03:49:22 +03:00
if ( removeSuit )
pev - > weapons = 0 ;
else
pev - > weapons & = ~ WEAPON_ALLWEAPONS ;
2017-10-13 03:04:37 +03:00
for ( i = 0 ; i < MAX_AMMO_SLOTS ; i + + )
2015-09-30 03:49:22 +03:00
m_rgAmmo [ i ] = 0 ;
UpdateClientData ( ) ;
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_FIXES
m_iHideHUD | = HIDEHUD_WEAPONS ;
2019-10-09 13:18:42 +03:00
m_bHasNightVision = false ;
SendItemStatus ( ) ;
2020-05-27 04:33:10 +03:00
ResetMaxSpeed ( ) ;
2016-12-06 22:21:52 +03:00
# endif
2016-06-06 15:44:16 +03:00
// send Selected Weapon Message to our client
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgCurWeapon , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
}
void CBasePlayer : : SetBombIcon ( BOOL bFlash )
{
if ( m_bHasC4 )
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( bFlash ? STATUSICON_FLASH : STATUSICON_SHOW ) ;
WRITE_STRING ( " c4 " ) ;
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( 160 ) ;
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
}
else
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( STATUSICON_HIDE ) ;
WRITE_STRING ( " c4 " ) ;
MESSAGE_END ( ) ;
}
SetScoreboardAttributes ( ) ;
}
void CBasePlayer : : SetProgressBarTime ( int time )
{
if ( time )
{
m_progressStart = gpGlobals - > time ;
m_progressEnd = time + gpGlobals - > time ;
}
else
{
m_progressStart = 0 ;
m_progressEnd = 0 ;
}
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBarTime , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_SHORT ( time ) ;
MESSAGE_END ( ) ;
2017-11-22 20:27:55 +03:00
int playerIndex = entindex ( ) ;
CBaseEntity * pEntity = nullptr ;
2015-09-30 03:49:22 +03:00
2017-11-22 20:27:55 +03:00
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
if ( FNullEnt ( pEntity - > edict ( ) ) )
2015-09-30 03:49:22 +03:00
break ;
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
2015-09-30 03:49:22 +03:00
2018-02-08 12:37:02 +03:00
if ( pPlayer - > GetObserverMode ( ) = = OBS_IN_EYE & & pPlayer - > pev - > iuser2 = = playerIndex )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBarTime , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_SHORT ( time ) ;
MESSAGE_END ( ) ;
}
}
}
void CBasePlayer : : SetProgressBarTime2 ( int time , float timeElapsed )
{
if ( time )
{
m_progressStart = gpGlobals - > time - timeElapsed ;
m_progressEnd = time + gpGlobals - > time - timeElapsed ;
}
else
{
timeElapsed = 0 ;
m_progressStart = 0 ;
m_progressEnd = 0 ;
}
short iTimeElapsed = ( timeElapsed * 100.0 / ( m_progressEnd - m_progressStart ) ) ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBarTime2 , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_SHORT ( time ) ;
WRITE_SHORT ( iTimeElapsed ) ;
MESSAGE_END ( ) ;
2017-11-22 20:27:55 +03:00
int playerIndex = entindex ( ) ;
CBaseEntity * pEntity = nullptr ;
2015-09-30 03:49:22 +03:00
2017-11-22 20:27:55 +03:00
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
if ( FNullEnt ( pEntity - > edict ( ) ) )
2015-09-30 03:49:22 +03:00
break ;
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
2015-09-30 03:49:22 +03:00
2018-02-08 12:37:02 +03:00
if ( pPlayer - > GetObserverMode ( ) = = OBS_IN_EYE & & pPlayer - > pev - > iuser2 = = playerIndex )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBarTime2 , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_SHORT ( time ) ;
WRITE_SHORT ( iTimeElapsed ) ;
MESSAGE_END ( ) ;
}
}
}
2017-11-22 20:27:55 +03:00
void BuyZoneIcon_Set ( CBasePlayer * pPlayer )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( STATUSICON_SHOW ) ;
WRITE_STRING ( " buyzone " ) ;
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( 160 ) ;
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
}
2017-11-22 20:27:55 +03:00
void BuyZoneIcon_Clear ( CBasePlayer * pPlayer )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( STATUSICON_HIDE ) ;
WRITE_STRING ( " buyzone " ) ;
MESSAGE_END ( ) ;
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iMenu > = Menu_Buy )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iMenu < = Menu_BuyItem )
2015-09-30 03:49:22 +03:00
{
2019-10-09 13:18:42 +03:00
# ifdef REGAMEDLL_FIXES
// NOTE: is client-side bug
if ( pPlayer - > m_bVGUIMenus )
{
MESSAGE_BEGIN ( MSG_ONE , gmsgBuyClose , nullptr , pPlayer - > pev ) ;
MESSAGE_END ( ) ;
}
# endif
2017-11-22 20:27:55 +03:00
CLIENT_COMMAND ( ENT ( pPlayer - > pev ) , " slot10 \n " ) ;
2015-09-30 03:49:22 +03:00
}
2017-11-22 20:27:55 +03:00
else if ( pPlayer - > m_iMenu = = Menu_ClientBuy )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBuyClose , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
}
}
2017-11-22 20:27:55 +03:00
void BombTargetFlash_Set ( CBasePlayer * pPlayer )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_bHasC4 & & ! ( pPlayer - > m_flDisplayHistory & DHF_IN_TARGET_ZONE ) )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > m_flDisplayHistory | = DHF_IN_TARGET_ZONE ;
pPlayer - > HintMessage ( " #Hint_you_are_in_targetzone " ) ;
2015-09-30 03:49:22 +03:00
}
2017-11-22 20:27:55 +03:00
pPlayer - > SetBombIcon ( TRUE ) ;
2015-09-30 03:49:22 +03:00
}
2017-11-22 20:27:55 +03:00
void BombTargetFlash_Clear ( CBasePlayer * pPlayer )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > SetBombIcon ( FALSE ) ;
2015-09-30 03:49:22 +03:00
}
2017-11-22 20:27:55 +03:00
void RescueZoneIcon_Set ( CBasePlayer * pPlayer )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( STATUSICON_SHOW ) ;
WRITE_STRING ( " rescue " ) ;
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( 160 ) ;
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iTeam = = CT & & ! ( pPlayer - > m_flDisplayHistory & DHF_IN_RESCUE_ZONE ) )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > m_flDisplayHistory | = DHF_IN_RESCUE_ZONE ;
pPlayer - > HintMessage ( " #Hint_hostage_rescue_zone " ) ;
2015-09-30 03:49:22 +03:00
}
}
2017-11-22 20:27:55 +03:00
void RescueZoneIcon_Clear ( CBasePlayer * pPlayer )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( STATUSICON_HIDE ) ;
WRITE_STRING ( " rescue " ) ;
MESSAGE_END ( ) ;
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iMenu > = Menu_Buy )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iMenu < = Menu_BuyItem )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
CLIENT_COMMAND ( ENT ( pPlayer - > pev ) , " slot10 \n " ) ;
2015-09-30 03:49:22 +03:00
}
2017-11-22 20:27:55 +03:00
else if ( pPlayer - > m_iMenu = = Menu_ClientBuy )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBuyClose , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
}
}
2017-11-22 20:27:55 +03:00
void EscapeZoneIcon_Set ( CBasePlayer * pPlayer )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( STATUSICON_SHOW ) ;
WRITE_STRING ( " escape " ) ;
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( 160 ) ;
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iTeam = = CT )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
if ( ! ( pPlayer - > m_flDisplayHistory & DHF_IN_ESCAPE_ZONE ) )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > m_flDisplayHistory | = DHF_IN_ESCAPE_ZONE ;
pPlayer - > HintMessage ( " #Hint_terrorist_escape_zone " ) ;
2015-09-30 03:49:22 +03:00
}
}
}
2017-11-22 20:27:55 +03:00
void EscapeZoneIcon_Clear ( CBasePlayer * pPlayer )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( STATUSICON_HIDE ) ;
WRITE_STRING ( " escape " ) ;
MESSAGE_END ( ) ;
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iMenu > = Menu_Buy )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iMenu < = Menu_BuyItem )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
CLIENT_COMMAND ( pPlayer - > edict ( ) , " slot10 \n " ) ;
2015-09-30 03:49:22 +03:00
}
2017-11-22 20:27:55 +03:00
else if ( pPlayer - > m_iMenu = = Menu_ClientBuy )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBuyClose , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
}
}
2017-11-22 20:27:55 +03:00
void VIP_SafetyZoneIcon_Set ( CBasePlayer * pPlayer )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( STATUSICON_SHOW ) ;
WRITE_STRING ( " vipsafety " ) ;
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( 160 ) ;
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
2017-11-22 20:27:55 +03:00
if ( ! ( pPlayer - > m_flDisplayHistory & DHF_IN_VIPSAFETY_ZONE ) )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iTeam = = CT )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > m_flDisplayHistory | = DHF_IN_VIPSAFETY_ZONE ;
pPlayer - > HintMessage ( " #Hint_ct_vip_zone " , TRUE ) ;
2015-09-30 03:49:22 +03:00
}
2017-11-22 20:27:55 +03:00
else if ( pPlayer - > m_iTeam = = TERRORIST )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > m_flDisplayHistory | = DHF_IN_VIPSAFETY_ZONE ;
pPlayer - > HintMessage ( " #Hint_terrorist_vip_zone " , TRUE ) ;
2015-09-30 03:49:22 +03:00
}
}
}
2017-11-22 20:27:55 +03:00
void VIP_SafetyZoneIcon_Clear ( CBasePlayer * pPlayer )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( STATUSICON_HIDE ) ;
WRITE_STRING ( " vipsafety " ) ;
MESSAGE_END ( ) ;
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iMenu > = Menu_Buy )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iMenu < = Menu_BuyItem )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
CLIENT_COMMAND ( pPlayer - > edict ( ) , " slot10 \n " ) ;
2015-09-30 03:49:22 +03:00
}
2017-11-22 20:27:55 +03:00
else if ( pPlayer - > m_iMenu = = Menu_ClientBuy )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBuyClose , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
}
}
void CBasePlayer : : SendFOV ( int fov )
{
2017-11-22 20:27:55 +03:00
pev - > fov = real_t ( fov ) ;
2015-09-30 03:49:22 +03:00
m_iClientFOV = fov ;
m_iFOV = fov ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgSetFOV , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( fov ) ;
MESSAGE_END ( ) ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , Killed , ( entvars_t * pevAttacker , int iGib ) , pevAttacker , iGib )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( Killed ) ( entvars_t * pevAttacker , int iGib )
2015-09-30 03:49:22 +03:00
{
m_canSwitchObserverModes = false ;
if ( m_LastHitGroup = = HITGROUP_HEAD )
m_bHeadshotKilled = true ;
CBaseEntity * pAttackerEntity = CBaseEntity : : Instance ( pevAttacker ) ;
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-12-05 22:40:30 +03:00
{
TheBots - > OnEvent ( EVENT_PLAYER_DIED , this , pAttackerEntity ) ;
}
2016-02-23 02:13:52 +03:00
if ( CSGameRules ( ) - > IsCareer ( ) )
2015-09-30 03:49:22 +03:00
{
bool killerHasShield = false ;
bool wasBlind = false ;
2016-12-06 22:21:52 +03:00
if ( TheCareerTasks )
2015-09-30 03:49:22 +03:00
{
2015-12-05 22:40:30 +03:00
if ( ! IsBot ( ) )
{
2017-10-13 03:04:37 +03:00
TheCareerTasks - > HandleEvent ( EVENT_DIE , nullptr , this ) ;
2015-12-05 22:40:30 +03:00
}
TheCareerTasks - > HandleDeath ( m_iTeam , this ) ;
2023-07-10 15:44:31 +03:00
# ifdef REGAMEDLL_FIXES
if ( ! m_bKilledByBomb )
{
CBasePlayer * pAttacker = CBasePlayer : : Instance ( pevAttacker ) ;
if ( pAttacker /*safety*/ & & ! pAttacker - > IsBot ( ) & & pAttacker - > m_iTeam ! = m_iTeam )
{
if ( pAttacker - > HasShield ( ) )
killerHasShield = true ;
if ( IsBot ( ) & & IsBlind ( ) ) // dystopm: shouldn't be !IsBot() ?
wasBlind = true ;
2023-11-26 07:21:04 +03:00
TheCareerTasks - > HandleEnemyKill ( wasBlind , GetKillerWeaponName ( GetLastInflictor ( ) , pevAttacker ) , m_bHeadshotKilled , killerHasShield , pAttacker , this ) ; // last 2 param swapped to match function definition
2023-07-10 15:44:31 +03:00
}
}
# endif
2015-09-30 03:49:22 +03:00
}
2023-07-10 15:44:31 +03:00
# ifndef REGAMEDLL_FIXES
2015-09-30 03:49:22 +03:00
if ( ! m_bKilledByBomb )
{
2016-06-14 01:13:13 +03:00
CBasePlayer * pAttacker = CBasePlayer : : Instance ( pevAttacker ) ;
2015-09-30 03:49:22 +03:00
if ( pAttacker - > HasShield ( ) )
killerHasShield = true ;
2016-06-14 01:13:13 +03:00
if ( IsBot ( ) & & IsBlind ( ) )
2015-09-30 03:49:22 +03:00
{
wasBlind = true ;
}
2017-10-13 03:04:37 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
2015-09-30 03:49:22 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
2015-09-30 03:49:22 +03:00
if ( ! pPlayer )
continue ;
bool killedByHumanPlayer = ( ! pPlayer - > IsBot ( ) & & pPlayer - > pev = = pevAttacker & & pPlayer - > m_iTeam ! = m_iTeam ) ;
if ( killedByHumanPlayer )
{
2016-12-06 22:21:52 +03:00
if ( TheCareerTasks )
2015-12-05 22:40:30 +03:00
{
2023-11-26 07:21:04 +03:00
TheCareerTasks - > HandleEnemyKill ( wasBlind , GetKillerWeaponName ( GetLastInflictor ( ) , pevAttacker ) , m_bHeadshotKilled , killerHasShield , this , pPlayer ) ;
2015-12-05 22:40:30 +03:00
}
2015-09-30 03:49:22 +03:00
}
}
}
2023-07-10 15:44:31 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
if ( ! m_bKilledByBomb )
{
2023-11-26 07:21:04 +03:00
g_pGameRules - > PlayerKilled ( this , pevAttacker , GetLastInflictor ( ) ) ;
2015-09-30 03:49:22 +03:00
}
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgNVGToggle , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
m_bNightVisionOn = false ;
2017-10-13 03:04:37 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
2015-09-30 03:49:22 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * pObserver = UTIL_PlayerByIndex ( i ) ;
2015-09-30 03:49:22 +03:00
if ( ! pObserver )
continue ;
if ( pObserver - > IsObservingPlayer ( this ) )
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgNVGToggle , nullptr , pObserver - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
pObserver - > m_bNightVisionOn = false ;
}
2021-12-28 03:07:43 +03:00
# ifdef REGAMEDLL_FIXES
if ( pObserver - > m_hObserverTarget = = this )
pObserver - > m_flNextFollowTime = 0.0f ;
# endif
2015-09-30 03:49:22 +03:00
}
2016-07-17 23:31:56 +03:00
if ( m_pTank )
2015-09-30 03:49:22 +03:00
{
m_pTank - > Use ( this , this , USE_OFF , 0 ) ;
2017-10-13 03:04:37 +03:00
m_pTank = nullptr ;
2015-09-30 03:49:22 +03:00
}
2016-04-05 03:12:05 +03:00
# ifndef REGAMEDLL_FIXES
2015-09-30 03:49:22 +03:00
CSound * pSound = CSoundEnt : : SoundPointerForIndex ( CSoundEnt : : ClientSoundIndex ( edict ( ) ) ) ;
2016-12-06 22:21:52 +03:00
if ( pSound )
2015-09-30 03:49:22 +03:00
{
pSound - > Reset ( ) ;
}
2016-04-05 03:12:05 +03:00
# endif
2015-09-30 03:49:22 +03:00
SetAnimation ( PLAYER_DIE ) ;
2016-06-14 01:13:13 +03:00
if ( m_pActiveItem & & m_pActiveItem - > m_pPlayer )
2015-09-30 03:49:22 +03:00
{
switch ( m_pActiveItem - > m_iId )
{
case WEAPON_HEGRENADE :
{
2016-02-23 02:13:52 +03:00
CHEGrenade * pHEGrenade = static_cast < CHEGrenade * > ( m_pActiveItem ) ;
2017-10-19 20:12:02 +03:00
if ( ( pev - > button & IN_ATTACK ) & & m_rgAmmo [ pHEGrenade - > m_iPrimaryAmmoType ] )
2015-09-30 03:49:22 +03:00
{
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
ThrowGrenade ( pHEGrenade , ( pev - > origin + pev - > view_ofs ) , pev - > angles , 1.5 , pHEGrenade - > m_usCreateExplosion ) ;
2017-11-01 18:01:24 +03:00
# ifdef REGAMEDLL_FIXES
m_rgAmmo [ m_pActiveItem - > PrimaryAmmoIndex ( ) ] - - ;
2019-10-09 13:18:42 +03:00
pHEGrenade - > m_flStartThrow = 0 ;
2017-11-01 18:01:24 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
break ;
}
case WEAPON_FLASHBANG :
{
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
CFlashbang * pFlashbang = static_cast < CFlashbang * > ( m_pActiveItem ) ;
if ( ( pev - > button & IN_ATTACK ) & & m_rgAmmo [ pFlashbang - > m_iPrimaryAmmoType ] )
2015-09-30 03:49:22 +03:00
{
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
ThrowGrenade ( pFlashbang , ( pev - > origin + pev - > view_ofs ) , pev - > angles , 1.5 ) ;
2017-11-01 18:01:24 +03:00
# ifdef REGAMEDLL_FIXES
m_rgAmmo [ m_pActiveItem - > PrimaryAmmoIndex ( ) ] - - ;
2019-10-09 13:18:42 +03:00
pFlashbang - > m_flStartThrow = 0 ;
2017-11-01 18:01:24 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
break ;
}
case WEAPON_SMOKEGRENADE :
{
2016-02-23 02:13:52 +03:00
CSmokeGrenade * pSmoke = static_cast < CSmokeGrenade * > ( m_pActiveItem ) ;
2017-10-19 20:12:02 +03:00
if ( ( pev - > button & IN_ATTACK ) & & m_rgAmmo [ pSmoke - > m_iPrimaryAmmoType ] )
2015-09-30 03:49:22 +03:00
{
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
ThrowGrenade ( pSmoke , ( pev - > origin + pev - > view_ofs ) , pev - > angles , 1.5 , pSmoke - > m_usCreateSmoke ) ;
2017-11-01 18:01:24 +03:00
# ifdef REGAMEDLL_FIXES
m_rgAmmo [ m_pActiveItem - > PrimaryAmmoIndex ( ) ] - - ;
2019-10-09 13:18:42 +03:00
pSmoke - > m_flStartThrow = 0 ;
2017-11-01 18:01:24 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
break ;
}
default :
break ;
}
}
pev - > modelindex = m_modelIndexPlayer ;
pev - > deadflag = DEAD_DYING ;
pev - > movetype = MOVETYPE_TOSS ;
pev - > takedamage = DAMAGE_NO ;
2019-09-22 17:39:06 +03:00
pev - > gamestate = HITGROUP_SHIELD_DISABLED ;
2015-09-30 03:49:22 +03:00
m_bShieldDrawn = false ;
pev - > flags & = ~ FL_ONGROUND ;
2019-10-09 13:18:42 +03:00
# ifdef REGAMEDLL_FIXES
// FlashlightTurnOff()
pev - > effects & = ~ EF_DIMLIGHT ;
# endif
2020-01-15 19:49:45 +03:00
# ifndef REGAMEDLL_ADD
2015-09-30 03:49:22 +03:00
if ( fadetoblack . value = = 0.0 )
{
pev - > iuser1 = OBS_CHASE_FREE ;
pev - > iuser2 = ENTINDEX ( edict ( ) ) ;
pev - > iuser3 = ENTINDEX ( ENT ( pevAttacker ) ) ;
2016-12-06 22:21:52 +03:00
m_hObserverTarget = UTIL_PlayerByIndexSafe ( pev - > iuser3 ) ;
2015-09-30 03:49:22 +03:00
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgADStop , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
else
2017-11-01 18:01:24 +03:00
{
2015-09-30 03:49:22 +03:00
UTIL_ScreenFade ( this , Vector ( 0 , 0 , 0 ) , 3 , 3 , 255 , ( FFADE_OUT | FFADE_STAYOUT ) ) ;
2017-11-01 18:01:24 +03:00
}
2020-01-15 19:49:45 +03:00
# else
2023-07-16 15:55:58 +03:00
float flDyingDuration = GetSequenceDuration ( ) + CGameRules : : GetDyingTime ( ) ;
2020-01-15 19:49:45 +03:00
switch ( ( int ) fadetoblack . value )
{
default :
{
pev - > iuser1 = OBS_CHASE_FREE ;
pev - > iuser2 = ENTINDEX ( edict ( ) ) ;
pev - > iuser3 = ENTINDEX ( ENT ( pevAttacker ) ) ;
m_hObserverTarget = UTIL_PlayerByIndexSafe ( pev - > iuser3 ) ;
MESSAGE_BEGIN ( MSG_ONE , gmsgADStop , nullptr , pev ) ;
MESSAGE_END ( ) ;
break ;
}
2023-07-16 15:55:58 +03:00
case FADETOBLACK_STAY :
2020-01-15 19:49:45 +03:00
{
2023-07-16 15:55:58 +03:00
UTIL_ScreenFade ( this , Vector ( 0 , 0 , 0 ) , 0.8f , flDyingDuration , 255 , ( FFADE_OUT | FFADE_STAYOUT ) ) ;
2020-01-15 19:49:45 +03:00
break ;
}
2023-07-16 15:55:58 +03:00
case FADETOBLACK_AT_DYING :
2020-01-15 19:49:45 +03:00
{
pev - > iuser1 = OBS_CHASE_FREE ;
pev - > iuser2 = ENTINDEX ( edict ( ) ) ;
pev - > iuser3 = ENTINDEX ( ENT ( pevAttacker ) ) ;
m_hObserverTarget = UTIL_PlayerByIndexSafe ( pev - > iuser3 ) ;
MESSAGE_BEGIN ( MSG_ONE , gmsgADStop , nullptr , pev ) ;
MESSAGE_END ( ) ;
2023-07-16 15:55:58 +03:00
UTIL_ScreenFade ( this , Vector ( 0 , 0 , 0 ) , 0.8f , flDyingDuration , 255 , ( FFADE_OUT ) ) ;
2020-01-15 19:49:45 +03:00
break ;
}
}
# endif // REGAMEDLL_ADD
2015-09-30 03:49:22 +03:00
SetScoreboardAttributes ( ) ;
if ( m_iThrowDirection )
{
switch ( m_iThrowDirection )
{
case THROW_FORWARD :
{
UTIL_MakeVectors ( pev - > angles ) ;
pev - > velocity = gpGlobals - > v_forward * RANDOM_FLOAT ( 100 , 200 ) ;
pev - > velocity . z = RANDOM_FLOAT ( 50 , 100 ) ;
break ;
}
case THROW_BACKWARD :
{
UTIL_MakeVectors ( pev - > angles ) ;
pev - > velocity = gpGlobals - > v_forward * RANDOM_FLOAT ( - 100 , - 200 ) ;
pev - > velocity . z = RANDOM_FLOAT ( 50 , 100 ) ;
break ;
}
case THROW_HITVEL :
{
if ( FClassnameIs ( pevAttacker , " player " ) )
{
UTIL_MakeVectors ( pevAttacker - > angles ) ;
pev - > velocity = gpGlobals - > v_forward * RANDOM_FLOAT ( 200 , 300 ) ;
pev - > velocity . z = RANDOM_FLOAT ( 200 , 300 ) ;
}
break ;
}
case THROW_BOMB :
{
2016-02-23 02:13:52 +03:00
// TODO: fix test demo
pev - > velocity = m_vBlastVector * ( 1.0f / m_vBlastVector . Length ( ) ) * float ( 2300.0f - m_vBlastVector . Length ( ) ) * 0.25f ;
pev - > velocity . z = ( 2300.0f - m_vBlastVector . Length ( ) ) / 2.75f ;
2015-09-30 03:49:22 +03:00
break ;
}
case THROW_GRENADE :
{
pev - > velocity = m_vBlastVector * ( 1 / m_vBlastVector . Length ( ) ) * ( 500 - m_vBlastVector . Length ( ) ) ;
pev - > velocity . z = ( 350 - m_vBlastVector . Length ( ) ) * 1.5 ;
break ;
}
case THROW_HITVEL_MINUS_AIRVEL :
{
if ( FClassnameIs ( pevAttacker , " player " ) )
{
UTIL_MakeVectors ( pevAttacker - > angles ) ;
pev - > velocity = gpGlobals - > v_forward * RANDOM_FLOAT ( 200 , 300 ) ;
}
break ;
}
default :
break ;
}
pev - > angles . y = UTIL_VecToAngles ( - pev - > velocity ) . y ;
pev - > v_angle . y = pev - > angles . y ;
m_iThrowDirection = THROW_NONE ;
}
2017-10-13 03:04:37 +03:00
SetSuitUpdate ( nullptr , SUIT_SENTENCE , SUIT_REPEAT_OK ) ;
2015-09-30 03:49:22 +03:00
2023-09-05 06:52:44 +03:00
m_iClientHealth = 0 ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgHealth , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( m_iClientHealth ) ;
MESSAGE_END ( ) ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgCurWeapon , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( 0xFF ) ;
WRITE_BYTE ( 0xFF ) ;
MESSAGE_END ( ) ;
SendFOV ( 0 ) ;
2016-02-23 02:13:52 +03:00
CSGameRules ( ) - > CheckWinConditions ( ) ;
2015-09-30 03:49:22 +03:00
m_bNotKilled = false ;
if ( m_bHasC4 )
{
DropPlayerItem ( " weapon_c4 " ) ;
2019-10-09 13:18:42 +03:00
# ifndef REGAMEDLL_FIXES
// NOTE: It is already does reset inside DropPlayerItem
2015-09-30 03:49:22 +03:00
SetProgressBarTime ( 0 ) ;
2019-10-09 13:18:42 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
else if ( m_bHasDefuser )
{
2019-06-21 23:19:32 +03:00
RemoveDefuser ( ) ;
2017-11-13 01:20:08 +03:00
# ifdef REGAMEDLL_FIXES
2023-09-05 06:52:44 +03:00
SpawnDefuser ( pev - > origin , ENT ( pev ) ) ;
2017-11-13 01:20:08 +03:00
# else
2015-09-30 03:49:22 +03:00
GiveNamedItem ( " item_thighpack " ) ;
2017-11-13 01:20:08 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
2023-09-05 06:52:44 +03:00
# ifndef REGAMEDLL_FIXES
// NOTE: moved to RemoveDefuser
2023-09-28 12:18:15 +03:00
m_bIsDefusing = false ;
2023-09-05 06:52:44 +03:00
# endif
2015-09-30 03:49:22 +03:00
BuyZoneIcon_Clear ( this ) ;
2017-01-20 17:52:37 +03:00
# ifdef REGAMEDLL_ADD
2019-09-23 00:31:23 +03:00
CSPlayer ( ) - > OnKilled ( ) ;
2017-01-20 17:52:37 +03:00
# endif
2015-09-30 03:49:22 +03:00
SetThink ( & CBasePlayer : : PlayerDeathThink ) ;
2016-12-06 22:21:52 +03:00
pev - > nextthink = gpGlobals - > time + 0.1f ;
2015-09-30 03:49:22 +03:00
pev - > solid = SOLID_NOT ;
if ( m_bPunishedForTK )
{
m_bPunishedForTK = false ;
HintMessage ( " #Hint_cannot_play_because_tk " , TRUE , TRUE ) ;
}
2023-12-14 02:01:34 +03:00
if ( ShouldGibPlayer ( iGib ) )
2015-09-30 03:49:22 +03:00
{
2019-10-09 13:18:42 +03:00
# ifndef REGAMEDLL_FIXES
2015-09-30 03:49:22 +03:00
pev - > solid = SOLID_NOT ;
2019-10-09 13:18:42 +03:00
# endif
2015-09-30 03:49:22 +03:00
GibMonster ( ) ;
pev - > effects | = EF_NODRAW ;
2019-10-09 13:18:42 +03:00
# ifndef REGAMEDLL_FIXES
2016-02-23 02:13:52 +03:00
CSGameRules ( ) - > CheckWinConditions ( ) ;
2019-10-09 13:18:42 +03:00
# endif
2015-09-30 03:49:22 +03:00
return ;
}
DeathSound ( ) ;
pev - > angles . x = 0 ;
pev - > angles . z = 0 ;
if ( ! ( m_flDisplayHistory & DHF_SPEC_DUCK ) )
{
HintMessage ( " #Spec_Duck " , TRUE , TRUE ) ;
m_flDisplayHistory | = DHF_SPEC_DUCK ;
}
}
2016-02-04 03:18:26 +03:00
BOOL CBasePlayer : : IsBombGuy ( )
2015-09-30 03:49:22 +03:00
{
if ( ! g_pGameRules - > IsMultiplayer ( ) )
return FALSE ;
return m_bHasC4 ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , SetAnimation , ( PLAYER_ANIM playerAnim ) , playerAnim )
2016-04-07 23:20:45 +03:00
2016-12-06 22:21:52 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( SetAnimation ) ( PLAYER_ANIM playerAnim )
2015-09-30 03:49:22 +03:00
{
int animDesired ;
float speed ;
char szAnim [ 64 ] ;
int hopSeq ;
int leapSeq ;
if ( ! pev - > modelindex )
return ;
if ( ( playerAnim = = PLAYER_FLINCH | | playerAnim = = PLAYER_LARGE_FLINCH ) & & HasShield ( ) )
return ;
if ( playerAnim ! = PLAYER_FLINCH & & playerAnim ! = PLAYER_LARGE_FLINCH & & m_flFlinchTime > gpGlobals - > time & & pev - > health > 0.0f )
return ;
speed = pev - > velocity . Length2D ( ) ;
if ( pev - > flags & FL_FROZEN )
{
speed = 0 ;
playerAnim = PLAYER_IDLE ;
}
hopSeq = LookupActivity ( ACT_HOP ) ;
leapSeq = LookupActivity ( ACT_LEAP ) ;
switch ( playerAnim )
{
case PLAYER_JUMP :
{
if ( m_Activity = = ACT_SWIM | | m_Activity = = ACT_DIESIMPLE | | m_Activity = = ACT_HOVER )
m_IdealActivity = m_Activity ;
else
{
m_IdealActivity = ACT_HOP ;
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-12-05 22:40:30 +03:00
{
TheBots - > OnEvent ( EVENT_PLAYER_JUMPED , this ) ;
}
2015-09-30 03:49:22 +03:00
}
break ;
}
case PLAYER_SUPERJUMP :
{
if ( m_Activity = = ACT_SWIM | | m_Activity = = ACT_DIESIMPLE | | m_Activity = = ACT_HOVER )
m_IdealActivity = m_Activity ;
else
m_IdealActivity = ACT_LEAP ;
break ;
}
case PLAYER_DIE :
{
m_IdealActivity = ACT_DIESIMPLE ;
2017-01-20 17:52:37 +03:00
# ifndef REGAMEDLL_FIXES
2015-09-30 03:49:22 +03:00
DeathSound ( ) ;
2017-01-20 17:52:37 +03:00
# endif
2015-09-30 03:49:22 +03:00
break ;
}
case PLAYER_ATTACK1 :
{
if ( m_Activity = = ACT_SWIM | | m_Activity = = ACT_DIESIMPLE | | m_Activity = = ACT_HOVER )
m_IdealActivity = m_Activity ;
else
{
m_IdealActivity = ACT_RANGE_ATTACK1 ;
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-12-05 22:40:30 +03:00
{
TheBots - > OnEvent ( EVENT_WEAPON_FIRED , this ) ;
}
2015-09-30 03:49:22 +03:00
}
break ;
}
case PLAYER_ATTACK2 :
{
if ( m_Activity = = ACT_SWIM | | m_Activity = = ACT_DIESIMPLE | | m_Activity = = ACT_HOVER )
m_IdealActivity = m_Activity ;
else
{
m_IdealActivity = ACT_RANGE_ATTACK2 ;
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-12-05 22:40:30 +03:00
{
TheBots - > OnEvent ( EVENT_WEAPON_FIRED , this ) ;
}
2015-09-30 03:49:22 +03:00
}
break ;
}
case PLAYER_RELOAD :
{
if ( m_Activity = = ACT_SWIM | | m_Activity = = ACT_DIESIMPLE | | m_Activity = = ACT_HOVER )
m_IdealActivity = m_Activity ;
else
{
m_IdealActivity = ACT_RELOAD ;
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-12-05 22:40:30 +03:00
{
TheBots - > OnEvent ( EVENT_WEAPON_RELOADED , this ) ;
}
2015-09-30 03:49:22 +03:00
}
break ;
}
case PLAYER_IDLE :
case PLAYER_WALK :
{
if ( pev - > flags & FL_ONGROUND | | ( m_Activity ! = ACT_HOP & & m_Activity ! = ACT_LEAP ) )
{
if ( pev - > waterlevel < = 1 )
m_IdealActivity = ACT_WALK ;
else if ( speed = = 0.0f )
m_IdealActivity = ACT_HOVER ;
else
m_IdealActivity = ACT_SWIM ;
}
else
m_IdealActivity = m_Activity ;
break ;
}
case PLAYER_HOLDBOMB :
m_IdealActivity = ACT_HOLDBOMB ;
break ;
case PLAYER_FLINCH :
m_IdealActivity = ACT_FLINCH ;
break ;
case PLAYER_LARGE_FLINCH :
m_IdealActivity = ACT_LARGE_FLINCH ;
break ;
default :
break ;
}
switch ( m_IdealActivity )
{
case ACT_HOP :
case ACT_LEAP :
{
if ( m_Activity = = m_IdealActivity )
return ;
switch ( m_Activity )
{
case ACT_RANGE_ATTACK1 : Q_strcpy ( szAnim , " ref_shoot_ " ) ; break ;
case ACT_RANGE_ATTACK2 : Q_strcpy ( szAnim , " ref_shoot2_ " ) ; break ;
case ACT_RELOAD : Q_strcpy ( szAnim , " ref_reload_ " ) ; break ;
default : Q_strcpy ( szAnim , " ref_aim_ " ) ; break ;
}
Q_strcat ( szAnim , m_szAnimExtention ) ;
animDesired = LookupSequence ( szAnim ) ;
if ( animDesired = = - 1 )
animDesired = 0 ;
if ( pev - > sequence ! = animDesired | | ! m_fSequenceLoops )
pev - > frame = 0 ;
if ( ! m_fSequenceLoops )
pev - > effects | = EF_NOINTERP ;
if ( m_IdealActivity = = ACT_LEAP )
pev - > gaitsequence = LookupActivity ( ACT_LEAP ) ;
else
pev - > gaitsequence = LookupActivity ( ACT_HOP ) ;
m_Activity = m_IdealActivity ;
break ;
}
case ACT_RANGE_ATTACK1 :
{
m_flLastFired = gpGlobals - > time ;
if ( pev - > flags & FL_DUCKING )
Q_strcpy ( szAnim , " crouch_shoot_ " ) ;
else
Q_strcpy ( szAnim , " ref_shoot_ " ) ;
Q_strcat ( szAnim , m_szAnimExtention ) ;
animDesired = LookupSequence ( szAnim ) ;
if ( animDesired = = - 1 )
animDesired = 0 ;
pev - > sequence = animDesired ;
pev - > frame = 0 ;
ResetSequenceInfo ( ) ;
m_Activity = m_IdealActivity ;
break ;
}
case ACT_RANGE_ATTACK2 :
{
m_flLastFired = gpGlobals - > time ;
if ( pev - > flags & FL_DUCKING )
Q_strcpy ( szAnim , " crouch_shoot2_ " ) ;
else
Q_strcpy ( szAnim , " ref_shoot2_ " ) ;
Q_strcat ( szAnim , m_szAnimExtention ) ;
animDesired = LookupSequence ( szAnim ) ;
if ( animDesired = = - 1 )
animDesired = 0 ;
pev - > sequence = animDesired ;
pev - > frame = 0 ;
ResetSequenceInfo ( ) ;
m_Activity = m_IdealActivity ;
break ;
}
case ACT_RELOAD :
{
if ( pev - > flags & FL_DUCKING )
Q_strcpy ( szAnim , " crouch_reload_ " ) ;
else
Q_strcpy ( szAnim , " ref_reload_ " ) ;
Q_strcat ( szAnim , m_szAnimExtention ) ;
animDesired = LookupSequence ( szAnim ) ;
if ( animDesired = = - 1 )
animDesired = 0 ;
if ( pev - > sequence ! = animDesired | | ! m_fSequenceLoops )
pev - > frame = 0 ;
if ( ! m_fSequenceLoops )
pev - > effects | = EF_NOINTERP ;
m_Activity = m_IdealActivity ;
break ;
}
case ACT_HOLDBOMB :
{
if ( pev - > flags & FL_DUCKING )
Q_strcpy ( szAnim , " crouch_aim_ " ) ;
else
Q_strcpy ( szAnim , " ref_aim_ " ) ;
Q_strcat ( szAnim , m_szAnimExtention ) ;
animDesired = LookupSequence ( szAnim ) ;
if ( animDesired = = - 1 )
animDesired = 0 ;
m_Activity = m_IdealActivity ;
break ;
}
case ACT_WALK :
{
if ( ( m_Activity ! = ACT_RANGE_ATTACK1 | | m_fSequenceFinished )
& & ( m_Activity ! = ACT_RANGE_ATTACK2 | | m_fSequenceFinished )
& & ( m_Activity ! = ACT_FLINCH | | m_fSequenceFinished )
& & ( m_Activity ! = ACT_LARGE_FLINCH | | m_fSequenceFinished )
& & ( m_Activity ! = ACT_RELOAD | | m_fSequenceFinished ) )
{
if ( speed < = 135.0f | | m_flLastFired + 4.0 > = gpGlobals - > time )
{
if ( pev - > flags & FL_DUCKING )
Q_strcpy ( szAnim , " crouch_aim_ " ) ;
else
Q_strcpy ( szAnim , " ref_aim_ " ) ;
Q_strcat ( szAnim , m_szAnimExtention ) ;
animDesired = LookupSequence ( szAnim ) ;
if ( animDesired = = - 1 )
animDesired = 0 ;
m_Activity = ACT_WALK ;
}
else
{
Q_strcpy ( szAnim , " run_ " ) ;
Q_strcat ( szAnim , m_szAnimExtention ) ;
animDesired = LookupSequence ( szAnim ) ;
if ( animDesired = = - 1 )
{
if ( pev - > flags & FL_DUCKING )
Q_strcpy ( szAnim , " crouch_aim_ " ) ;
else
Q_strcpy ( szAnim , " ref_aim_ " ) ;
Q_strcat ( szAnim , m_szAnimExtention ) ;
animDesired = LookupSequence ( szAnim ) ;
if ( animDesired = = - 1 )
animDesired = 0 ;
m_Activity = ACT_RUN ;
pev - > gaitsequence = LookupActivity ( ACT_RUN ) ;
}
else
{
m_Activity = ACT_RUN ;
pev - > gaitsequence = animDesired ;
}
if ( m_Activity = = ACT_RUN )
{
2016-02-23 02:13:52 +03:00
// TODO: maybe away used variable 'speed'?
2015-09-30 03:49:22 +03:00
//if (speed > 150.0f)
if ( pev - > velocity . Length2D ( ) > 150.0f )
2015-12-05 22:40:30 +03:00
{
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-12-05 22:40:30 +03:00
{
TheBots - > OnEvent ( EVENT_PLAYER_FOOTSTEP , this ) ;
}
}
2015-09-30 03:49:22 +03:00
}
}
}
else
animDesired = pev - > sequence ;
if ( speed > 135.0f )
pev - > gaitsequence = LookupActivity ( ACT_RUN ) ;
else
pev - > gaitsequence = LookupActivity ( ACT_WALK ) ;
break ;
}
case ACT_FLINCH :
case ACT_LARGE_FLINCH :
{
m_Activity = m_IdealActivity ;
# ifndef REGAMEDLL_FIXES
// TODO: why? this condition was checked!
if ( ( playerAnim = = PLAYER_FLINCH | | playerAnim = = PLAYER_LARGE_FLINCH ) & & HasShield ( ) )
return ;
2016-02-23 02:13:52 +03:00
# endif
2015-09-30 03:49:22 +03:00
switch ( m_LastHitGroup )
{
case HITGROUP_GENERIC :
{
if ( RANDOM_LONG ( 0 , 1 ) )
animDesired = LookupSequence ( " head_flinch " ) ;
else
animDesired = LookupSequence ( " gut_flinch " ) ;
break ;
}
case HITGROUP_HEAD :
case HITGROUP_CHEST :
animDesired = LookupSequence ( " head_flinch " ) ;
break ;
case HITGROUP_SHIELD :
animDesired = 0 ;
break ;
default :
animDesired = LookupSequence ( " gut_flinch " ) ;
break ;
}
if ( animDesired = = - 1 )
animDesired = 0 ;
break ;
}
case ACT_DIESIMPLE :
{
if ( m_Activity = = m_IdealActivity )
return ;
m_Activity = m_IdealActivity ;
m_flDeathThrowTime = 0 ;
m_iThrowDirection = THROW_NONE ;
switch ( m_LastHitGroup )
{
case HITGROUP_GENERIC :
{
switch ( RANDOM_LONG ( 0 , 8 ) )
{
case 0 :
animDesired = LookupActivity ( ACT_DIE_HEADSHOT ) ;
m_iThrowDirection = THROW_BACKWARD ;
break ;
case 1 :
animDesired = LookupActivity ( ACT_DIE_GUTSHOT ) ;
break ;
case 2 :
animDesired = LookupActivity ( ACT_DIE_BACKSHOT ) ;
m_iThrowDirection = THROW_HITVEL ;
break ;
case 4 :
animDesired = LookupActivity ( ACT_DIEBACKWARD ) ;
m_iThrowDirection = THROW_HITVEL ;
break ;
case 5 :
animDesired = LookupActivity ( ACT_DIEFORWARD ) ;
m_iThrowDirection = THROW_FORWARD ;
break ;
case 6 :
animDesired = LookupActivity ( ACT_DIE_CHESTSHOT ) ;
break ;
case 7 :
animDesired = LookupActivity ( ACT_DIE_GUTSHOT ) ;
break ;
case 8 :
animDesired = LookupActivity ( ACT_DIE_HEADSHOT ) ;
break ;
default :
2020-02-06 00:31:59 +03:00
animDesired = LookupActivity ( ACT_DIESIMPLE ) ;
2015-09-30 03:49:22 +03:00
break ;
}
break ;
}
case HITGROUP_HEAD :
{
int random = RANDOM_LONG ( 0 , 8 ) ;
m_bHeadshotKilled = true ;
if ( m_bHighDamage )
2017-10-13 03:04:37 +03:00
random + + ;
2015-09-30 03:49:22 +03:00
switch ( random )
{
case 1 :
case 2 :
m_iThrowDirection = THROW_BACKWARD ;
break ;
case 3 :
case 4 :
2017-12-17 15:28:01 +03:00
# ifndef REGAMEDLL_FIXES
2015-09-30 03:49:22 +03:00
m_iThrowDirection = THROW_FORWARD ;
break ;
2017-12-17 15:28:01 +03:00
# endif
2015-09-30 03:49:22 +03:00
case 5 :
case 6 :
m_iThrowDirection = THROW_HITVEL ;
break ;
default :
m_iThrowDirection = THROW_NONE ;
break ;
}
animDesired = LookupActivity ( ACT_DIE_HEADSHOT ) ;
break ;
}
case HITGROUP_CHEST :
animDesired = LookupActivity ( ACT_DIE_CHESTSHOT ) ;
break ;
case HITGROUP_STOMACH :
animDesired = LookupActivity ( ACT_DIE_GUTSHOT ) ;
break ;
case HITGROUP_LEFTARM :
animDesired = LookupSequence ( " left " ) ;
break ;
case HITGROUP_RIGHTARM :
{
m_iThrowDirection = RANDOM_LONG ( 0 , 1 ) ? THROW_HITVEL : THROW_HITVEL_MINUS_AIRVEL ;
animDesired = LookupSequence ( " right " ) ;
break ;
}
default :
animDesired = LookupActivity ( ACT_DIESIMPLE ) ;
break ;
}
2020-02-06 00:31:59 +03:00
2015-09-30 03:49:22 +03:00
if ( pev - > flags & FL_DUCKING )
{
animDesired = LookupSequence ( " crouch_die " ) ;
m_iThrowDirection = THROW_BACKWARD ;
}
else if ( m_bKilledByBomb | | m_bKilledByGrenade )
{
UTIL_MakeVectors ( pev - > angles ) ;
if ( DotProduct ( gpGlobals - > v_forward , m_vBlastVector ) > 0.0f )
animDesired = LookupSequence ( " left " ) ;
else
{
if ( RANDOM_LONG ( 0 , 1 ) )
animDesired = LookupSequence ( " crouch_die " ) ;
else
animDesired = LookupActivity ( ACT_DIE_HEADSHOT ) ;
}
if ( m_bKilledByBomb )
m_iThrowDirection = THROW_BOMB ;
else if ( m_bKilledByGrenade )
m_iThrowDirection = THROW_GRENADE ;
}
if ( animDesired = = - 1 )
animDesired = 0 ;
if ( pev - > sequence ! = animDesired )
{
pev - > gaitsequence = 0 ;
pev - > sequence = animDesired ;
pev - > frame = 0.0f ;
ResetSequenceInfo ( ) ;
}
return ;
}
default :
{
if ( m_Activity = = m_IdealActivity )
return ;
m_Activity = m_IdealActivity ;
animDesired = LookupActivity ( m_IdealActivity ) ;
if ( pev - > sequence ! = animDesired )
{
pev - > gaitsequence = 0 ;
pev - > sequence = animDesired ;
pev - > frame = 0 ;
ResetSequenceInfo ( ) ;
}
return ;
}
}
if ( pev - > gaitsequence ! = hopSeq & & pev - > gaitsequence ! = leapSeq )
{
if ( pev - > flags & FL_DUCKING )
{
if ( speed ! = 0.0f )
pev - > gaitsequence = LookupActivity ( ACT_CROUCH ) ;
else
pev - > gaitsequence = LookupActivity ( ACT_CROUCHIDLE ) ;
}
else
{
if ( speed > 135.0f )
{
if ( m_flLastFired + 4.0f < gpGlobals - > time )
{
if ( m_Activity ! = ACT_FLINCH & & m_Activity ! = ACT_LARGE_FLINCH )
{
Q_strcpy ( szAnim , " run_ " ) ;
Q_strcat ( szAnim , m_szAnimExtention ) ;
animDesired = LookupSequence ( szAnim ) ;
if ( animDesired = = - 1 )
{
if ( pev - > flags & FL_DUCKING )
Q_strcpy ( szAnim , " crouch_aim_ " ) ;
else
Q_strcpy ( szAnim , " ref_aim_ " ) ;
Q_strcat ( szAnim , m_szAnimExtention ) ;
animDesired = LookupSequence ( szAnim ) ;
}
else
pev - > gaitsequence = animDesired ;
m_Activity = ACT_RUN ;
}
}
pev - > gaitsequence = LookupActivity ( ACT_RUN ) ;
}
else
{
if ( speed > 0.0f )
pev - > gaitsequence = LookupActivity ( ACT_WALK ) ;
else
pev - > gaitsequence = LookupActivity ( ACT_IDLE ) ;
}
}
}
if ( pev - > sequence ! = animDesired )
{
pev - > sequence = animDesired ;
pev - > frame = 0 ;
ResetSequenceInfo ( ) ;
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : WaterMove ( )
2015-09-30 03:49:22 +03:00
{
int air ;
if ( pev - > movetype = = MOVETYPE_NOCLIP | | pev - > movetype = = MOVETYPE_NONE )
return ;
2016-09-13 12:20:37 +03:00
# ifdef REGAMEDLL_FIXES
if ( ! IsAlive ( ) )
return ;
# else
2015-09-30 03:49:22 +03:00
if ( pev - > health < 0.0f )
return ;
2016-09-13 12:20:37 +03:00
# endif
2015-09-30 03:49:22 +03:00
// waterlevel 0 - not in water
// waterlevel 1 - feet in water
// waterlevel 2 - waist in water
// waterlevel 3 - head in water
if ( pev - > waterlevel ! = 3 )
{
// not underwater
// play 'up for air' sound
2024-01-31 13:40:47 +03:00
# ifdef REGAMEDLL_FIXES
if ( pev - > flags & FL_INWATER )
# endif
{
if ( pev - > air_finished < gpGlobals - > time )
EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/pl_wade1.wav " , VOL_NORM , ATTN_NORM ) ;
2015-09-30 03:49:22 +03:00
2024-01-31 13:40:47 +03:00
else if ( pev - > air_finished < gpGlobals - > time + 9 )
EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/pl_wade2.wav " , VOL_NORM , ATTN_NORM ) ;
}
2015-09-30 03:49:22 +03:00
pev - > air_finished = gpGlobals - > time + AIRTIME ;
pev - > dmg = 2 ;
// if we took drowning damage, give it back slowly
if ( m_idrowndmg > m_idrownrestored )
{
// set drowning damage bit. hack - dmg_drownrecover actually
// makes the time based damage code 'give back' health over time.
// make sure counter is cleared so we start count correctly.
// NOTE: this actually causes the count to continue restarting
// until all drowning damage is healed.
2017-10-19 20:12:02 +03:00
m_rgbTimeBasedDamage [ ITBD_DROWN_RECOVER ] = 0 ;
2015-09-30 03:49:22 +03:00
m_bitsDamageType | = DMG_DROWNRECOVER ;
m_bitsDamageType & = ~ DMG_DROWN ;
}
}
else
{
// fully under water
// stop restoring damage while underwater
2017-10-19 20:12:02 +03:00
m_rgbTimeBasedDamage [ ITBD_DROWN_RECOVER ] = 0 ;
2015-09-30 03:49:22 +03:00
m_bitsDamageType & = ~ DMG_DROWNRECOVER ;
// drown!
if ( gpGlobals - > time > pev - > air_finished )
{
if ( gpGlobals - > time > pev - > pain_finished )
{
// take drowning damage
pev - > dmg + = 1 ;
if ( pev - > dmg > 5 )
pev - > dmg = 5 ;
TakeDamage ( VARS ( eoNullEntity ) , VARS ( eoNullEntity ) , pev - > dmg , DMG_DROWN ) ;
2016-12-09 15:39:16 +03:00
# ifdef REGAMEDLL_FIXES
// NOTE: If we died after the damage of above and was followed respawn,
// so we should get out of code.
if ( ! ( m_bitsDamageType & DMG_DROWN ) )
return ;
# endif
2015-09-30 03:49:22 +03:00
pev - > pain_finished = gpGlobals - > time + 1 ;
// track drowning damage, give it back when
// player finally takes a breath
m_idrowndmg + = pev - > dmg ;
}
}
else
m_bitsDamageType & = ~ ( DMG_DROWNRECOVER | DMG_DROWN ) ;
}
if ( ! pev - > waterlevel )
{
if ( pev - > flags & FL_INWATER )
pev - > flags & = ~ FL_INWATER ;
return ;
}
// make bubbles
2016-02-23 02:13:52 +03:00
air = int ( pev - > air_finished - gpGlobals - > time ) ;
2015-09-30 03:49:22 +03:00
if ( ! RANDOM_LONG ( 0 , 0x1f ) & & RANDOM_LONG ( 0 , AIRTIME - 1 ) > = air )
{
switch ( RANDOM_LONG ( 0 , 3 ) )
{
case 0 : EMIT_SOUND ( ENT ( pev ) , CHAN_BODY , " player/pl_swim1.wav " , 0.8 , ATTN_NORM ) ; break ;
case 1 : EMIT_SOUND ( ENT ( pev ) , CHAN_BODY , " player/pl_swim2.wav " , 0.8 , ATTN_NORM ) ; break ;
case 2 : EMIT_SOUND ( ENT ( pev ) , CHAN_BODY , " player/pl_swim3.wav " , 0.8 , ATTN_NORM ) ; break ;
case 3 : EMIT_SOUND ( ENT ( pev ) , CHAN_BODY , " player/pl_swim4.wav " , 0.8 , ATTN_NORM ) ; break ;
}
}
if ( pev - > watertype = = CONTENT_LAVA ) // do damage
{
if ( pev - > dmgtime < gpGlobals - > time )
TakeDamage ( VARS ( eoNullEntity ) , VARS ( eoNullEntity ) , pev - > waterlevel * 10 , DMG_BURN ) ;
}
else if ( pev - > watertype = = CONTENT_SLIME ) // do damage
{
pev - > dmgtime = gpGlobals - > time + 1 ;
TakeDamage ( VARS ( eoNullEntity ) , VARS ( eoNullEntity ) , pev - > waterlevel * 4 , DMG_ACID ) ;
}
if ( ! ( pev - > flags & FL_INWATER ) )
{
pev - > flags | = FL_INWATER ;
pev - > dmgtime = 0 ;
}
}
2016-02-04 03:18:26 +03:00
BOOL CBasePlayer : : IsOnLadder ( )
2015-09-30 03:49:22 +03:00
{
return pev - > movetype = = MOVETYPE_FLY ;
}
NOXREF void CBasePlayer : : ThrowWeapon ( char * pszItemName )
{
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < MAX_WEAPON_SLOTS ; i + + )
2015-09-30 03:49:22 +03:00
{
CBasePlayerItem * pWeapon = m_rgpPlayerItems [ i ] ;
2016-12-06 22:21:52 +03:00
while ( pWeapon )
2015-09-30 03:49:22 +03:00
{
if ( ! Q_strcmp ( pszItemName , STRING ( pWeapon - > pev - > classname ) ) )
{
DropPlayerItem ( pszItemName ) ;
return ;
}
pWeapon = pWeapon - > m_pNext ;
}
}
}
2017-01-29 02:56:29 +03:00
LINK_ENTITY_TO_CLASS ( weapon_shield , CWShield , CCSShield )
2015-09-30 03:49:22 +03:00
2017-07-01 23:40:10 +03:00
void CWShield : : Spawn ( )
2015-09-30 03:49:22 +03:00
{
pev - > movetype = MOVETYPE_TOSS ;
pev - > solid = SOLID_TRIGGER ;
UTIL_SetSize ( pev , g_vecZero , g_vecZero ) ;
SET_MODEL ( ENT ( pev ) , " models/w_shield.mdl " ) ;
}
2017-07-01 23:40:10 +03:00
void CWShield : : Touch ( CBaseEntity * pOther )
2015-09-30 03:49:22 +03:00
{
if ( ! pOther - > IsPlayer ( ) )
return ;
CBasePlayer * pPlayer = ( CBasePlayer * ) pOther ;
if ( pPlayer - > pev - > deadflag ! = DEAD_NO )
return ;
2017-10-12 17:50:56 +03:00
if ( m_hEntToIgnoreTouchesFrom & & m_hEntToIgnoreTouchesFrom = = pPlayer )
2015-09-30 03:49:22 +03:00
{
if ( m_flTimeToIgnoreTouches > gpGlobals - > time )
return ;
2017-10-12 17:50:56 +03:00
m_hEntToIgnoreTouchesFrom = nullptr ;
2015-09-30 03:49:22 +03:00
}
if ( ! pPlayer - > m_bHasPrimary )
{
2017-10-19 20:12:02 +03:00
if ( pPlayer - > m_rgpPlayerItems [ PISTOL_SLOT ] & & pPlayer - > m_rgpPlayerItems [ PISTOL_SLOT ] - > m_iId = = WEAPON_ELITE )
2015-09-30 03:49:22 +03:00
return ;
if ( pPlayer - > m_pActiveItem )
{
if ( ! pPlayer - > m_pActiveItem - > CanHolster ( ) )
return ;
}
if ( ! pPlayer - > m_bIsVIP )
{
2016-06-20 22:32:02 +03:00
# ifdef REGAMEDLL_ADD
if ( pPlayer - > HasRestrictItem ( ITEM_SHIELDGUN , ITEM_TYPE_TOUCHED ) )
return ;
# endif
2015-09-30 03:49:22 +03:00
pPlayer - > GiveShield ( ) ;
EMIT_SOUND ( edict ( ) , CHAN_ITEM , " items/gunpickup2.wav " , VOL_NORM , ATTN_NORM ) ;
UTIL_Remove ( this ) ;
pev - > nextthink = gpGlobals - > time + 0.1 ;
}
}
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , GiveShield , ( bool bDeploy ) , bDeploy )
2016-04-07 23:20:45 +03:00
2016-12-06 22:21:52 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( GiveShield ) ( bool bDeploy )
2015-09-30 03:49:22 +03:00
{
m_bOwnsShield = true ;
m_bHasPrimary = true ;
2019-09-22 17:39:06 +03:00
# ifdef REGAMEDLL_FIXES
pev - > gamestate = HITGROUP_SHIELD_ENABLED ;
# endif
2016-12-06 22:21:52 +03:00
if ( m_pActiveItem )
2015-09-30 03:49:22 +03:00
{
2016-02-23 02:13:52 +03:00
CBasePlayerWeapon * pWeapon = static_cast < CBasePlayerWeapon * > ( m_pActiveItem ) ;
2015-09-30 03:49:22 +03:00
if ( bDeploy )
{
2017-10-19 20:12:02 +03:00
if ( m_rgAmmo [ pWeapon - > m_iPrimaryAmmoType ] > 0 )
2015-09-30 03:49:22 +03:00
pWeapon - > Holster ( ) ;
if ( ! pWeapon - > Deploy ( ) )
pWeapon - > RetireWeapon ( ) ;
}
}
2019-09-22 17:39:06 +03:00
# ifndef REGAMEDLL_FIXES
// NOTE: Moved above, because CC4::Deploy can reset hitbox of shield
pev - > gamestate = HITGROUP_SHIELD_ENABLED ;
# endif
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : RemoveShield ( )
2015-09-30 03:49:22 +03:00
{
if ( HasShield ( ) )
{
m_bOwnsShield = false ;
m_bHasPrimary = false ;
m_bShieldDrawn = false ;
2019-09-22 17:39:06 +03:00
pev - > gamestate = HITGROUP_SHIELD_DISABLED ;
2015-09-30 03:49:22 +03:00
UpdateShieldCrosshair ( true ) ;
}
}
2017-10-12 17:50:56 +03:00
LINK_HOOK_CLASS_CHAIN ( CBaseEntity * , CBasePlayer , DropShield , ( bool bDeploy ) , bDeploy )
2016-12-06 22:21:52 +03:00
2017-10-12 17:50:56 +03:00
CBaseEntity * EXT_FUNC CBasePlayer : : __API_HOOK ( DropShield ) ( bool bDeploy )
2015-09-30 03:49:22 +03:00
{
if ( ! HasShield ( ) )
2017-10-12 17:50:56 +03:00
return nullptr ;
2015-09-30 03:49:22 +03:00
2016-12-06 22:21:52 +03:00
if ( m_pActiveItem & & ! m_pActiveItem - > CanHolster ( ) )
2017-10-12 17:50:56 +03:00
return nullptr ;
2015-09-30 03:49:22 +03:00
2016-02-23 02:13:52 +03:00
CBasePlayerWeapon * pWeapon = static_cast < CBasePlayerWeapon * > ( m_pActiveItem ) ;
2015-09-30 03:49:22 +03:00
2016-12-06 22:21:52 +03:00
if ( pWeapon )
2016-02-23 02:13:52 +03:00
{
2015-09-30 03:49:22 +03:00
if ( pWeapon - > m_iId = = WEAPON_HEGRENADE | | pWeapon - > m_iId = = WEAPON_FLASHBANG | | pWeapon - > m_iId = = WEAPON_SMOKEGRENADE )
{
2017-10-19 20:12:02 +03:00
if ( m_rgAmmo [ pWeapon - > m_iPrimaryAmmoType ] < = 0 )
2015-09-30 03:49:22 +03:00
g_pGameRules - > GetNextBestWeapon ( this , pWeapon ) ;
}
}
2016-12-06 22:21:52 +03:00
if ( m_pActiveItem )
2015-09-30 03:49:22 +03:00
{
2016-02-23 02:13:52 +03:00
if ( m_pActiveItem - > m_flStartThrow ! = 0.0f )
2015-09-30 03:49:22 +03:00
m_pActiveItem - > Holster ( ) ;
}
if ( IsReloading ( ) )
{
pWeapon - > m_fInReload = FALSE ;
m_flNextAttack = 0 ;
}
2016-12-06 22:21:52 +03:00
if ( m_pActiveItem & & IsProtectedByShield ( ) )
2015-09-30 03:49:22 +03:00
( ( CBasePlayerWeapon * ) m_pActiveItem ) - > SecondaryAttack ( ) ;
m_bShieldDrawn = false ;
RemoveShield ( ) ;
2016-12-06 22:21:52 +03:00
if ( m_pActiveItem & & bDeploy )
2015-09-30 03:49:22 +03:00
m_pActiveItem - > Deploy ( ) ;
UTIL_MakeVectors ( pev - > angles ) ;
CWShield * pShield = ( CWShield * ) CBaseEntity : : Create ( " weapon_shield " , pev - > origin + gpGlobals - > v_forward * 10 , pev - > angles , edict ( ) ) ;
pShield - > pev - > angles . x = 0 ;
pShield - > pev - > angles . z = 0 ;
pShield - > pev - > velocity = gpGlobals - > v_forward * 400 ;
pShield - > SetThink ( & CBaseEntity : : SUB_Remove ) ;
2017-11-13 01:20:08 +03:00
pShield - > pev - > nextthink = gpGlobals - > time + CGameRules : : GetItemKillDelay ( ) ;
2015-09-30 03:49:22 +03:00
pShield - > SetCantBePickedUpByUser ( this , 2.0 ) ;
2017-10-12 17:50:56 +03:00
return pShield ;
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
bool CBasePlayer : : HasShield ( )
2015-09-30 03:49:22 +03:00
{
return m_bOwnsShield ;
}
2016-02-04 03:18:26 +03:00
NOXREF void CBasePlayer : : ThrowPrimary ( )
2015-09-30 03:49:22 +03:00
{
ThrowWeapon ( " weapon_m249 " ) ;
ThrowWeapon ( " weapon_g3sg1 " ) ;
ThrowWeapon ( " weapon_sg550 " ) ;
ThrowWeapon ( " weapon_awp " ) ;
ThrowWeapon ( " weapon_mp5navy " ) ;
ThrowWeapon ( " weapon_tmp " ) ;
ThrowWeapon ( " weapon_p90 " ) ;
ThrowWeapon ( " weapon_ump45 " ) ;
ThrowWeapon ( " weapon_m4a1 " ) ;
ThrowWeapon ( " weapon_m3 " ) ;
ThrowWeapon ( " weapon_sg552 " ) ;
ThrowWeapon ( " weapon_scout " ) ;
ThrowWeapon ( " weapon_galil " ) ;
ThrowWeapon ( " weapon_famas " ) ;
DropShield ( ) ;
}
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
LINK_HOOK_CLASS_CHAIN ( CGrenade * , CBasePlayer , ThrowGrenade , ( CBasePlayerWeapon * pWeapon , Vector vecSrc , Vector vecThrow , float time , unsigned short usEvent ) , pWeapon , vecSrc , vecThrow , time , usEvent )
CGrenade * CBasePlayer : : __API_HOOK ( ThrowGrenade ) ( CBasePlayerWeapon * pWeapon , VectorRef vecSrc , VectorRef vecThrow , float time , unsigned short usEvent )
{
switch ( pWeapon - > m_iId )
{
case WEAPON_HEGRENADE : return CGrenade : : ShootTimed2 ( pev , vecSrc , vecThrow , time , m_iTeam , usEvent ) ;
case WEAPON_FLASHBANG : return CGrenade : : ShootTimed ( pev , vecSrc , vecThrow , time ) ;
case WEAPON_SMOKEGRENADE : return CGrenade : : ShootSmokeGrenade ( pev , vecSrc , vecThrow , time , usEvent ) ;
}
return nullptr ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , AddAccount , ( int amount , RewardType type , bool bTrackChange ) , amount , type , bTrackChange )
2016-04-07 23:20:45 +03:00
2016-10-07 15:19:51 +03:00
# ifdef REGAMEDLL_ADD
2016-12-06 22:21:52 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( AddAccount ) ( int amount , RewardType type , bool bTrackChange )
2016-10-07 15:19:51 +03:00
{
bool bSendMoney = true ;
switch ( type )
{
case RT_INTO_GAME :
case RT_PLAYER_JOIN :
bSendMoney = false ;
case RT_PLAYER_RESET :
case RT_PLAYER_SPEC_JOIN :
m_iAccount = 0 ;
break ;
}
m_iAccount + = amount ;
if ( bSendMoney )
{
2019-04-23 15:54:51 +03:00
m_iAccount = clamp < int > ( m_iAccount , 0 , maxmoney . value ) ;
2016-10-07 15:19:51 +03:00
// Send money update to HUD
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgMoney , nullptr , pev ) ;
2016-10-07 15:19:51 +03:00
WRITE_LONG ( m_iAccount ) ;
WRITE_BYTE ( bTrackChange ) ;
MESSAGE_END ( ) ;
}
}
# else
2016-12-06 22:21:52 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( AddAccount ) ( int amount , RewardType type , bool bTrackChange )
2015-09-30 03:49:22 +03:00
{
m_iAccount + = amount ;
2016-06-08 00:41:07 +03:00
if ( m_iAccount > 16000 )
2015-09-30 03:49:22 +03:00
m_iAccount = 16000 ;
2015-12-29 01:54:08 +03:00
2016-06-08 00:41:07 +03:00
else if ( m_iAccount < 0 )
2015-12-29 01:54:08 +03:00
m_iAccount = 0 ;
2015-09-30 03:49:22 +03:00
// Send money update to HUD
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgMoney , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_LONG ( m_iAccount ) ;
WRITE_BYTE ( bTrackChange ) ;
MESSAGE_END ( ) ;
}
2016-10-07 15:19:51 +03:00
# endif
2015-09-30 03:49:22 +03:00
2016-02-04 03:18:26 +03:00
void CBasePlayer : : ResetMenu ( )
2015-09-30 03:49:22 +03:00
{
2017-01-20 17:52:37 +03:00
# ifdef REGAMEDLL_FIXES
m_iMenu = Menu_OFF ;
# endif
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgShowMenu , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_SHORT ( 0 ) ;
WRITE_CHAR ( 0 ) ;
WRITE_BYTE ( 0 ) ;
WRITE_STRING ( " " ) ;
MESSAGE_END ( ) ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : SyncRoundTimer ( )
2015-09-30 03:49:22 +03:00
{
2016-12-06 22:21:52 +03:00
float tmRemaining = 0 ;
BOOL bFreezePeriod = g_pGameRules - > IsFreezePeriod ( ) ;
2015-09-30 03:49:22 +03:00
2016-12-06 22:21:52 +03:00
if ( g_pGameRules - > IsMultiplayer ( ) )
{
2016-12-10 21:27:53 +03:00
tmRemaining = CSGameRules ( ) - > GetRoundRemainingTimeReal ( ) ;
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_FIXES
// hide timer HUD because it is useless.
if ( tmRemaining < = 0.0f & & CSGameRules ( ) - > m_iRoundTime < = 0 ) {
m_iHideHUD | = HIDEHUD_TIMER ;
return ;
}
if ( m_iHideHUD & HIDEHUD_TIMER )
{
m_iHideHUD & = ~ HIDEHUD_TIMER ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgShowTimer , nullptr , pev ) ;
2016-12-06 22:21:52 +03:00
MESSAGE_END ( ) ;
}
# endif
}
2015-09-30 03:49:22 +03:00
if ( tmRemaining < 0 )
tmRemaining = 0 ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgRoundTime , nullptr , pev ) ;
2016-02-23 02:13:52 +03:00
WRITE_SHORT ( int ( tmRemaining ) ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
2016-12-06 22:21:52 +03:00
if ( ! g_pGameRules - > IsMultiplayer ( ) )
2015-09-30 03:49:22 +03:00
return ;
2018-02-08 12:37:02 +03:00
if ( bFreezePeriod & & TheTutor & & GetObserverMode ( ) = = OBS_NONE )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBlinkAcct , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( MONEY_BLINK_AMOUNT ) ;
MESSAGE_END ( ) ;
}
2016-12-06 22:21:52 +03:00
if ( TheCareerTasks & & CSGameRules ( ) - > IsCareer ( ) )
2015-09-30 03:49:22 +03:00
{
int remaining = 0 ;
bool shouldCountDown = false ;
int fadeOutDelay = 0 ;
if ( tmRemaining ! = 0.0f )
{
2016-10-05 18:27:50 +03:00
remaining = TheCareerTasks - > GetTaskTime ( ) - ( gpGlobals - > time - CSGameRules ( ) - > m_fRoundStartTime ) ;
2015-09-30 03:49:22 +03:00
}
if ( remaining < 0 )
remaining = 0 ;
2016-12-06 22:21:52 +03:00
if ( bFreezePeriod )
2015-09-30 03:49:22 +03:00
remaining = - 1 ;
if ( TheCareerTasks - > GetFinishedTaskTime ( ) )
remaining = - TheCareerTasks - > GetFinishedTaskTime ( ) ;
2016-12-06 22:21:52 +03:00
if ( ! bFreezePeriod & & ! TheCareerTasks - > GetFinishedTaskTime ( ) )
2015-09-30 03:49:22 +03:00
{
shouldCountDown = true ;
}
2016-12-06 22:21:52 +03:00
if ( ! bFreezePeriod )
2015-09-30 03:49:22 +03:00
{
if ( TheCareerTasks - > GetFinishedTaskTime ( ) | | ( TheCareerTasks - > GetTaskTime ( ) < = TheCareerTasks - > GetRoundElapsedTime ( ) ) )
{
fadeOutDelay = 3 ;
}
}
2016-02-23 02:13:52 +03:00
if ( ! TheCareerTasks - > GetFinishedTaskTime ( ) | | TheCareerTasks - > GetFinishedTaskRound ( ) = = CSGameRules ( ) - > m_iTotalRoundsPlayed )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgTaskTime , nullptr , pev ) ;
WRITE_SHORT ( remaining ) ; // remaining of time, -1 the timer is disappears
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( shouldCountDown ) ; // timer counts down
2017-10-13 03:04:37 +03:00
WRITE_BYTE ( fadeOutDelay ) ; // fade in time, hide HUD timer after the expiration time
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : RemoveLevelText ( )
2015-09-30 03:49:22 +03:00
{
ResetMenu ( ) ;
}
void ShowMenu2 ( CBasePlayer * pPlayer , int bitsValidSlots , int nDisplayTime , int fNeedMore , char * pszText )
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgShowMenu , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_SHORT ( bitsValidSlots ) ;
WRITE_CHAR ( nDisplayTime ) ;
WRITE_BYTE ( fNeedMore ) ;
WRITE_STRING ( pszText ) ;
MESSAGE_END ( ) ;
}
2015-12-05 22:40:30 +03:00
void CBasePlayer : : MenuPrint ( const char * msg )
2015-09-30 03:49:22 +03:00
{
const char * msg_portion = msg ;
char sbuf [ MAX_BUFFER_MENU_BRIEFING + 1 ] ;
while ( Q_strlen ( msg_portion ) > = MAX_BUFFER_MENU_BRIEFING )
{
Q_strncpy ( sbuf , msg_portion , MAX_BUFFER_MENU_BRIEFING ) ;
2017-10-19 20:12:02 +03:00
sbuf [ MAX_BUFFER_MENU_BRIEFING ] = ' \0 ' ;
2015-09-30 03:49:22 +03:00
msg_portion + = MAX_BUFFER_MENU_BRIEFING ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgShowMenu , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_SHORT ( 0xFFFF ) ;
WRITE_CHAR ( - 1 ) ;
WRITE_BYTE ( 1 ) ; // multipart
WRITE_STRING ( sbuf ) ;
MESSAGE_END ( ) ;
}
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgShowMenu , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_SHORT ( 0xFFFF ) ;
WRITE_CHAR ( - 1 ) ;
WRITE_BYTE ( 0 ) ; // multipart
WRITE_STRING ( msg_portion ) ;
MESSAGE_END ( ) ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , MakeVIP )
2016-12-06 22:21:52 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( MakeVIP ) ( )
2015-09-30 03:49:22 +03:00
{
pev - > body = 0 ;
m_iModelName = MODEL_VIP ;
2016-05-30 14:19:56 +03:00
SetClientUserInfoModel ( GET_INFO_BUFFER ( edict ( ) ) , " vip " ) ;
2015-09-30 03:49:22 +03:00
UTIL_LogPrintf ( " \" %s<%i><%s><CT> \" triggered \" Became_VIP \" \n " , STRING ( pev - > netname ) , GETPLAYERUSERID ( edict ( ) ) , GETPLAYERAUTHID ( edict ( ) ) ) ;
m_iTeam = CT ;
m_bIsVIP = true ;
m_bNotKilled = false ;
2016-02-23 02:13:52 +03:00
CSGameRules ( ) - > m_pVIP = this ;
CSGameRules ( ) - > m_iConsecutiveVIP = 1 ;
2015-09-30 03:49:22 +03:00
}
2021-08-29 07:12:25 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , JoiningThink )
void EXT_FUNC CBasePlayer : : __API_HOOK ( JoiningThink ) ( )
2015-09-30 03:49:22 +03:00
{
switch ( m_iJoiningState )
{
case JOINED :
{
return ;
}
case SHOWLTEXT :
{
ResetMenu ( ) ;
m_iJoiningState = SHOWTEAMSELECT ;
2023-09-05 06:52:44 +03:00
# ifndef REGAMEDLL_FIXES
// NOTE: client already clears StatusIcon on join
2023-09-28 12:18:15 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( STATUSICON_HIDE ) ;
WRITE_STRING ( " defuser " ) ;
MESSAGE_END ( ) ;
2023-09-05 06:52:44 +03:00
m_bHasDefuser = false ; // set in ClientPutInServer
# endif
2015-09-30 03:49:22 +03:00
m_fLastMovement = gpGlobals - > time ;
m_bMissionBriefing = false ;
2023-09-05 06:52:44 +03:00
SendItemStatus ( ) ; // NOTE: must be on UpdateClientData
2015-09-30 03:49:22 +03:00
break ;
}
case READINGLTEXT :
{
if ( m_afButtonPressed & ( IN_ATTACK | IN_ATTACK2 | IN_JUMP ) )
{
m_afButtonPressed & = ~ ( IN_ATTACK | IN_ATTACK2 | IN_JUMP ) ;
RemoveLevelText ( ) ;
m_iJoiningState = SHOWTEAMSELECT ;
}
break ;
}
case GETINTOGAME :
{
2016-12-06 22:21:52 +03:00
if ( GetIntoGame ( ) ) {
return ;
2015-09-30 03:49:22 +03:00
}
2016-12-06 22:21:52 +03:00
break ;
2015-09-30 03:49:22 +03:00
}
}
2023-11-26 07:25:08 +03:00
if ( m_pIntroCamera & & gpGlobals - > time > = m_fIntroCamTime
2024-01-12 05:16:20 +03:00
# ifdef REGAMEDLL_FIXES
2023-11-26 07:25:08 +03:00
& & m_fIntroCamTime > 0.0 // update only if cameras are available
# endif
)
2015-09-30 03:49:22 +03:00
{
2016-12-06 22:21:52 +03:00
// find the next another camera
2015-09-30 03:49:22 +03:00
m_pIntroCamera = UTIL_FindEntityByClassname ( m_pIntroCamera , " trigger_camera " ) ;
2016-12-06 22:21:52 +03:00
// could not find, go back to the start
2015-09-30 03:49:22 +03:00
if ( ! m_pIntroCamera )
{
2017-10-13 03:04:37 +03:00
m_pIntroCamera = UTIL_FindEntityByClassname ( nullptr , " trigger_camera " ) ;
2015-09-30 03:49:22 +03:00
}
2017-10-13 03:04:37 +03:00
CBaseEntity * Target = UTIL_FindEntityByTargetname ( nullptr , STRING ( m_pIntroCamera - > pev - > target ) ) ;
2016-12-06 22:21:52 +03:00
if ( Target )
2015-09-30 03:49:22 +03:00
{
2016-12-06 22:21:52 +03:00
Vector vecAngles = UTIL_VecToAngles ( ( Target - > pev - > origin - m_pIntroCamera - > pev - > origin ) . Normalize ( ) ) ;
2015-09-30 03:49:22 +03:00
2016-12-06 22:21:52 +03:00
vecAngles . x = - vecAngles . x ;
2015-09-30 03:49:22 +03:00
UTIL_SetOrigin ( pev , m_pIntroCamera - > pev - > origin ) ;
2016-12-06 22:21:52 +03:00
pev - > angles = vecAngles ;
2015-09-30 03:49:22 +03:00
pev - > v_angle = pev - > angles ;
pev - > velocity = g_vecZero ;
pev - > punchangle = g_vecZero ;
pev - > fixangle = 1 ;
pev - > view_ofs = g_vecZero ;
m_fIntroCamTime = gpGlobals - > time + 6 ;
}
else
2017-10-13 03:04:37 +03:00
m_pIntroCamera = nullptr ;
2015-09-30 03:49:22 +03:00
}
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , Disappear )
2016-12-06 22:21:52 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( Disappear ) ( )
2015-09-30 03:49:22 +03:00
{
2016-12-06 22:21:52 +03:00
if ( m_pTank )
2015-09-30 03:49:22 +03:00
{
m_pTank - > Use ( this , this , USE_OFF , 0 ) ;
2017-10-13 03:04:37 +03:00
m_pTank = nullptr ;
2015-09-30 03:49:22 +03:00
}
2016-04-05 03:12:05 +03:00
# ifndef REGAMEDLL_FIXES
2015-09-30 03:49:22 +03:00
CSound * pSound = CSoundEnt : : SoundPointerForIndex ( CSoundEnt : : ClientSoundIndex ( edict ( ) ) ) ;
if ( pSound )
{
pSound - > Reset ( ) ;
}
2016-04-05 03:12:05 +03:00
# endif
2015-09-30 03:49:22 +03:00
m_fSequenceFinished = TRUE ;
pev - > modelindex = m_modelIndexPlayer ;
pev - > view_ofs = Vector ( 0 , 0 , - 8 ) ;
pev - > deadflag = DEAD_DYING ;
pev - > solid = SOLID_NOT ;
pev - > flags & = ~ FL_ONGROUND ;
2019-10-09 13:18:42 +03:00
# ifdef REGAMEDLL_FIXES
// FlashlightTurnOff()
pev - > effects & = ~ EF_DIMLIGHT ;
# endif
2017-10-13 03:04:37 +03:00
SetSuitUpdate ( nullptr , SUIT_SENTENCE , SUIT_REPEAT_OK ) ;
2015-09-30 03:49:22 +03:00
m_iClientHealth = 0 ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgHealth , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( m_iClientHealth ) ;
MESSAGE_END ( ) ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgCurWeapon , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( 0xFF ) ;
WRITE_BYTE ( 0xFF ) ;
MESSAGE_END ( ) ;
SendFOV ( 0 ) ;
2016-02-23 02:13:52 +03:00
CSGameRules ( ) - > CheckWinConditions ( ) ;
2015-09-30 03:49:22 +03:00
m_bNotKilled = false ;
if ( m_bHasC4 )
{
DropPlayerItem ( " weapon_c4 " ) ;
2019-10-09 13:18:42 +03:00
# ifndef REGAMEDLL_FIXES
// NOTE: It is already does reset inside DropPlayerItem
2015-09-30 03:49:22 +03:00
SetProgressBarTime ( 0 ) ;
2019-10-09 13:18:42 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
else if ( m_bHasDefuser )
{
2019-06-21 23:19:32 +03:00
RemoveDefuser ( ) ;
2023-09-05 06:52:44 +03:00
# ifdef REGAMEDLL_FIXES
SpawnDefuser ( pev - > origin , ENT ( pev ) ) ;
# else
2015-09-30 03:49:22 +03:00
GiveNamedItem ( " item_thighpack " ) ;
2019-10-09 13:18:42 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
BuyZoneIcon_Clear ( this ) ;
SetThink ( & CBasePlayer : : PlayerDeathThink ) ;
pev - > nextthink = gpGlobals - > time + 0.1f ;
pev - > angles . x = 0 ;
pev - > angles . z = 0 ;
}
2023-11-08 17:18:01 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , PlayerDeathThink )
void EXT_FUNC CBasePlayer : : __API_HOOK ( PlayerDeathThink ) ( )
2015-09-30 03:49:22 +03:00
{
if ( m_iJoiningState ! = JOINED )
return ;
2016-02-04 03:18:26 +03:00
// If the anim is done playing, go to the next state (waiting for a keypress to
2015-11-06 17:58:48 +03:00
// either respawn the guy or put him into observer mode).
2015-09-30 03:49:22 +03:00
if ( pev - > flags & FL_ONGROUND )
{
float flForward = pev - > velocity . Length ( ) - 20 ;
if ( flForward < = 0 )
pev - > velocity = g_vecZero ;
else
pev - > velocity = flForward * pev - > velocity . Normalize ( ) ;
}
if ( HasWeapons ( ) )
{
// we drop the guns here because weapons that have an area effect and can kill their user
// will sometimes crash coming back from CBasePlayer::Killed() if they kill their owner because the
// player class sometimes is freed. It's safer to manipulate the weapons once we know
// we aren't calling into any of their code anymore through the player pointer.
PackDeadPlayerItems ( ) ;
}
2019-04-23 15:54:51 +03:00
2019-02-26 00:13:23 +03:00
# ifdef REGAMEDLL_FIXES
// Clear inclination came from client view
pev - > angles . x = 0 ;
# endif
2019-04-23 15:54:51 +03:00
2015-09-30 03:49:22 +03:00
if ( pev - > modelindex & & ! m_fSequenceFinished & & pev - > deadflag = = DEAD_DYING )
{
StudioFrameAdvance ( ) ;
return ;
}
// once we're done animating our death and we're on the ground, we want to set movetype to None so our dead body won't do collisions and stuff anymore
// this prevents a bug where the dead body would go to a player's head if he walked over it while the dead player was clicking their button to respawn
if ( pev - > movetype ! = MOVETYPE_NONE & & ( pev - > flags & FL_ONGROUND ) )
pev - > movetype = MOVETYPE_NONE ;
if ( pev - > deadflag = = DEAD_DYING )
{
2015-11-06 17:58:48 +03:00
// Used for a timer.
2015-09-30 03:49:22 +03:00
m_fDeadTime = gpGlobals - > time ;
pev - > deadflag = DEAD_DEAD ;
}
StopAnimation ( ) ;
pev - > effects | = EF_NOINTERP ;
BOOL fAnyButtonDown = ( pev - > button & ~ IN_SCORE ) ;
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_FIXES
// do not make a corpse if the player goes to respawn.
2017-05-04 18:39:34 +03:00
if ( pev - > deadflag ! = DEAD_RESPAWNABLE )
2016-12-06 22:21:52 +03:00
# endif
2015-09-30 03:49:22 +03:00
{
2016-12-06 22:21:52 +03:00
// if the player has been dead for one second longer than allowed by forcerespawn,
// forcerespawn isn't on. Send the player off to an intermission camera until they choose to respawn.
2023-07-12 20:43:37 +03:00
if ( g_pGameRules - > IsMultiplayer ( ) & & HasTimePassedSinceDeath ( CGameRules : : GetDyingTime ( ) ) & & ! ( m_afPhysicsFlags & PFLAG_OBSERVER ) )
2015-09-30 03:49:22 +03:00
{
2017-01-20 17:52:37 +03:00
// Send message to everybody to spawn a corpse.
SpawnClientSideCorpse ( ) ;
2015-11-06 17:58:48 +03:00
2017-01-20 17:52:37 +03:00
// go to dead camera.
StartDeathCam ( ) ;
2015-09-30 03:49:22 +03:00
}
}
// wait for all buttons released
if ( pev - > deadflag = = DEAD_DEAD & & m_iTeam ! = UNASSIGNED & & m_iTeam ! = SPECTATOR )
{
if ( fAnyButtonDown )
return ;
if ( g_pGameRules - > FPlayerCanRespawn ( this ) )
{
2017-05-04 18:39:34 +03:00
# ifdef REGAMEDLL_ADD
if ( forcerespawn . value < = 0 | | ( m_iTeam ! = CT & & m_iTeam ! = TERRORIST ) )
# endif
{
pev - > deadflag = DEAD_RESPAWNABLE ;
2015-09-30 03:49:22 +03:00
2017-05-24 19:07:37 +03:00
if ( CSGameRules ( ) - > IsMultiplayer ( ) )
CSGameRules ( ) - > CheckWinConditions ( ) ;
}
2015-09-30 03:49:22 +03:00
}
2016-02-23 02:13:52 +03:00
pev - > nextthink = gpGlobals - > time + 0.1f ;
2016-12-06 22:21:52 +03:00
return ;
2015-09-30 03:49:22 +03:00
}
2016-12-06 22:21:52 +03:00
2017-05-04 18:39:34 +03:00
# ifdef REGAMEDLL_ADD
if ( forcerespawn . value < = 0 )
# endif
2015-09-30 03:49:22 +03:00
{
2017-05-04 18:39:34 +03:00
if ( pev - > deadflag = = DEAD_RESPAWNABLE )
{
# ifdef REGAMEDLL_FIXES
2018-02-08 12:37:02 +03:00
if ( GetObserverMode ( ) ! = OBS_NONE & & ( m_iTeam = = UNASSIGNED | | m_iTeam = = SPECTATOR ) )
2017-05-04 18:39:34 +03:00
return ;
// Player cannot respawn while in the Choose Appearance menu
if ( m_iMenu = = Menu_ChooseAppearance | | m_iJoiningState = = SHOWTEAMSELECT )
return ;
# endif
// don't copy a corpse if we're in deathcam.
respawn ( pev , FALSE ) ;
pev - > button = 0 ;
pev - > nextthink = - 1 ;
}
2015-09-30 03:49:22 +03:00
}
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , RoundRespawn )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( RoundRespawn ) ( )
2015-09-30 03:49:22 +03:00
{
m_canSwitchObserverModes = true ;
// teamkill punishment..
2016-12-06 22:21:52 +03:00
if ( m_bJustKilledTeammate & & tkpunish . value )
2015-09-30 03:49:22 +03:00
{
2016-12-06 22:21:52 +03:00
m_bPunishedForTK = true ;
2015-09-30 03:49:22 +03:00
m_bJustKilledTeammate = false ;
2016-12-06 22:21:52 +03:00
2015-09-30 03:49:22 +03:00
# ifndef REGAMEDLL_FIXES
// TODO: wtf?
CLIENT_COMMAND ( edict ( ) , " kill \n " ) ;
2016-02-23 02:13:52 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
2016-12-06 22:21:52 +03:00
2015-09-30 03:49:22 +03:00
if ( m_iMenu ! = Menu_ChooseAppearance )
{
respawn ( pev ) ;
pev - > button = 0 ;
pev - > nextthink = - 1 ;
}
2017-01-20 17:52:37 +03:00
if ( m_pActiveItem & & m_pActiveItem - > iItemSlot ( ) = = GRENADE_SLOT )
SwitchWeapon ( m_pActiveItem ) ;
2015-09-30 03:49:22 +03:00
m_lastLocation [ 0 ] = ' \0 ' ;
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_FIXES
if ( m_bPunishedForTK & & pev - > health > 0 )
2022-12-17 19:45:04 +03:00
Kill ( ) ;
2016-12-06 22:21:52 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
2017-06-25 16:21:38 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , StartDeathCam )
2015-11-06 17:58:48 +03:00
// StartDeathCam - find an intermission spot and send the
// player off into observer mode
2017-06-25 16:21:38 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( StartDeathCam ) ( )
2015-09-30 03:49:22 +03:00
{
2017-06-27 21:30:34 +03:00
# ifdef REGAMEDLL_FIXES
2017-01-20 17:52:37 +03:00
m_canSwitchObserverModes = true ;
# endif
2015-09-30 03:49:22 +03:00
if ( pev - > view_ofs = = g_vecZero )
{
// don't accept subsequent attempts to StartDeathCam()
return ;
}
StartObserver ( pev - > origin , pev - > angles ) ;
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-09-30 03:49:22 +03:00
{
TheBots - > OnEvent ( EVENT_DEATH_CAMERA_START , this ) ;
}
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , StartObserver , ( Vector & vecPosition , Vector & vecViewAngle ) , vecPosition , vecViewAngle )
2016-12-06 22:21:52 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( StartObserver ) ( Vector & vecPosition , Vector & vecViewAngle )
2015-09-30 03:49:22 +03:00
{
// clear any clientside entities attached to this player
MESSAGE_BEGIN ( MSG_PAS , SVC_TEMPENTITY , pev - > origin ) ;
WRITE_BYTE ( TE_KILLPLAYERATTACHMENTS ) ;
WRITE_BYTE ( entindex ( ) ) ;
MESSAGE_END ( ) ;
// Holster weapon immediately, to allow it to cleanup
2016-12-06 22:21:52 +03:00
if ( m_pActiveItem )
2015-09-30 03:49:22 +03:00
m_pActiveItem - > Holster ( ) ;
2016-12-06 22:21:52 +03:00
if ( m_pTank )
2015-09-30 03:49:22 +03:00
{
2016-12-06 22:21:52 +03:00
m_pTank - > Use ( this , this , USE_OFF , 0 ) ;
2017-10-13 03:04:37 +03:00
m_pTank = nullptr ;
2015-09-30 03:49:22 +03:00
}
// clear out the suit message cache so we don't keep chattering
2017-10-13 03:04:37 +03:00
SetSuitUpdate ( nullptr , SUIT_SENTENCE , SUIT_REPEAT_OK ) ;
2015-09-30 03:49:22 +03:00
// Tell Ammo Hud that the player is dead
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgCurWeapon , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( 0xFF ) ;
WRITE_BYTE ( 0xFF ) ;
MESSAGE_END ( ) ;
// reset FOV
SendFOV ( 0 ) ;
// Setup flags
m_iHideHUD = ( HIDEHUD_WEAPONS | HIDEHUD_HEALTH ) ;
m_afPhysicsFlags | = PFLAG_OBSERVER ;
pev - > effects = EF_NODRAW ;
2016-12-06 22:21:52 +03:00
2015-11-06 17:58:48 +03:00
// set position and viewangle
2015-09-30 03:49:22 +03:00
pev - > view_ofs = g_vecZero ;
pev - > angles = pev - > v_angle = vecViewAngle ;
pev - > fixangle = 1 ;
pev - > solid = SOLID_NOT ;
pev - > takedamage = DAMAGE_NO ;
pev - > movetype = MOVETYPE_NONE ;
// Move them to the new position
UTIL_SetOrigin ( pev , vecPosition ) ;
m_afPhysicsFlags & = ~ PFLAG_DUCKING ;
pev - > flags & = ~ FL_DUCKING ;
pev - > health = 1 ;
m_iObserverC4State = 0 ;
m_bObserverHasDefuser = false ;
m_iObserverWeapon = 0 ;
2016-12-06 22:21:52 +03:00
// Find a player to watch
2015-09-30 03:49:22 +03:00
m_flNextObserverInput = 0 ;
pev - > iuser1 = OBS_NONE ;
static int iFirstTime = 1 ;
2016-12-06 22:21:52 +03:00
if ( iFirstTime ! = 0 & & CSGameRules ( ) & & CSGameRules ( ) - > IsCareer ( ) & & ! IsBot ( ) )
2015-09-30 03:49:22 +03:00
{
Observer_SetMode ( OBS_CHASE_LOCKED ) ;
CLIENT_COMMAND ( edict ( ) , " spec_autodirector_internal 1 \n " ) ;
iFirstTime = 0 ;
}
else
Observer_SetMode ( m_iObserverLastMode ) ;
ResetMaxSpeed ( ) ;
// Tell all clients this player is now a spectator
MESSAGE_BEGIN ( MSG_ALL , gmsgSpectator ) ;
WRITE_BYTE ( entindex ( ) ) ;
WRITE_BYTE ( 1 ) ;
MESSAGE_END ( ) ;
}
2017-11-22 20:27:55 +03:00
bool CanSeeUseable ( CBasePlayer * me , CBaseEntity * pEntity )
2015-09-30 03:49:22 +03:00
{
TraceResult result ;
Vector eye = me - > pev - > origin + me - > pev - > view_ofs ;
2017-11-22 20:27:55 +03:00
if ( FClassnameIs ( pEntity - > pev , " hostage_entity " ) )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
Vector chest = pEntity - > pev - > origin + Vector ( 0 , 0 , HalfHumanHeight ) ;
Vector head = pEntity - > pev - > origin + Vector ( 0 , 0 , HumanHeight * 0.9 ) ;
Vector knees = pEntity - > pev - > origin + Vector ( 0 , 0 , StepHeight ) ;
2015-09-30 03:49:22 +03:00
UTIL_TraceLine ( eye , chest , ignore_monsters , ignore_glass , me - > edict ( ) , & result ) ;
if ( result . flFraction < 1.0f )
{
2017-11-22 20:27:55 +03:00
UTIL_TraceLine ( eye , head , ignore_monsters , ignore_glass , pEntity - > edict ( ) , & result ) ;
2015-09-30 03:49:22 +03:00
if ( result . flFraction < 1.0f )
{
2017-11-22 20:27:55 +03:00
UTIL_TraceLine ( eye , knees , ignore_monsters , ignore_glass , pEntity - > edict ( ) , & result ) ;
2015-09-30 03:49:22 +03:00
if ( result . flFraction < 1.0f )
{
return false ;
}
}
}
}
return true ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : PlayerUse ( )
2015-09-30 03:49:22 +03:00
{
// Was use pressed or released?
if ( ! ( ( pev - > button | m_afButtonPressed | m_afButtonReleased ) & IN_USE ) )
return ;
// Hit Use on a train?
if ( m_afButtonPressed & IN_USE )
{
2016-12-06 22:21:52 +03:00
if ( m_pTank )
2015-09-30 03:49:22 +03:00
{
// Stop controlling the tank
// TODO: Send HUD Update
m_pTank - > Use ( this , this , USE_OFF , 0 ) ;
2017-10-13 03:04:37 +03:00
m_pTank = nullptr ;
2015-09-30 03:49:22 +03:00
return ;
}
if ( m_afPhysicsFlags & PFLAG_ONTRAIN )
{
m_iTrain = ( TRAIN_NEW | TRAIN_OFF ) ;
m_afPhysicsFlags & = ~ PFLAG_ONTRAIN ;
CBaseEntity * pTrain = Instance ( pev - > groundentity ) ;
if ( pTrain & & pTrain - > Classify ( ) = = CLASS_VEHICLE )
{
2022-12-06 22:11:25 +03:00
# ifdef REGAMEDLL_ADD
2023-09-05 06:52:30 +03:00
if ( legacy_vehicle_block . value = = 0 )
return ;
2022-12-06 22:11:25 +03:00
# endif
2023-09-05 06:52:30 +03:00
( ( CFuncVehicle * ) pTrain ) - > m_pDriver = nullptr ;
2015-09-30 03:49:22 +03:00
}
return ;
}
else
{
// Start controlling the train!
CBaseEntity * pTrain = Instance ( pev - > groundentity ) ;
if ( pTrain & & ! ( pev - > button & IN_JUMP ) & & ( pev - > flags & FL_ONGROUND ) & & ( pTrain - > ObjectCaps ( ) & FCAP_DIRECTIONAL_USE ) & & pTrain - > OnControls ( pev ) )
{
m_afPhysicsFlags | = PFLAG_ONTRAIN ;
m_iTrain = TrainSpeed ( pTrain - > pev - > speed , pTrain - > pev - > impulse ) ;
m_iTrain | = TRAIN_NEW ;
if ( pTrain - > Classify ( ) = = CLASS_VEHICLE )
{
EMIT_SOUND ( ENT ( pev ) , CHAN_ITEM , " plats/vehicle_ignition.wav " , 0.8 , ATTN_NORM ) ;
( ( CFuncVehicle * ) pTrain ) - > m_pDriver = this ;
}
else
EMIT_SOUND ( ENT ( pev ) , CHAN_ITEM , " plats/train_use1.wav " , 0.8 , ATTN_NORM ) ;
return ;
}
}
}
2019-10-09 13:18:42 +03:00
bool useNewHostages = ! TheNavAreaList . empty ( ) & & AreImprovAllowed ( ) ;
2017-10-13 03:04:37 +03:00
CBaseEntity * pObject = nullptr ;
CBaseEntity * pClosest = nullptr ;
2015-09-30 03:49:22 +03:00
Vector vecLOS ;
float flMaxDot = VIEW_FIELD_NARROW ;
float flDot ;
// so we know which way we are facing
UTIL_MakeVectors ( pev - > v_angle ) ;
if ( useNewHostages )
{
TraceResult result ;
const float useHostageRange = 1000.0f ;
Vector vecStart = pev - > origin + pev - > view_ofs ;
Vector vecEnd = vecStart + gpGlobals - > v_forward * useHostageRange ;
UTIL_TraceLine ( vecStart , vecEnd , dont_ignore_monsters , edict ( ) , & result ) ;
if ( result . flFraction < 1.0f )
{
CBaseEntity * hit = Instance ( result . pHit ) ;
2016-12-06 22:21:52 +03:00
if ( hit & & FClassnameIs ( hit - > pev , " hostage_entity " ) & & CanSeeUseable ( this , hit ) )
2015-09-30 03:49:22 +03:00
pClosest = hit ;
}
if ( ! pClosest )
{
2016-12-06 22:21:52 +03:00
while ( ( pObject = UTIL_FindEntityInSphere ( pObject , pev - > origin , useHostageRange ) ) )
2015-09-30 03:49:22 +03:00
{
if ( ! FClassnameIs ( pObject - > pev , " hostage_entity " ) )
continue ;
vecLOS = VecBModelOrigin ( pObject - > pev ) - vecStart ;
vecLOS . NormalizeInPlace ( ) ;
flDot = DotProduct ( vecLOS , gpGlobals - > v_forward ) ;
if ( flDot > flMaxDot & & CanSeeUseable ( this , pObject ) )
{
pClosest = pObject ;
flMaxDot = flDot ;
}
}
}
}
if ( ! pClosest )
{
2017-10-12 17:50:56 +03:00
while ( ( pObject = UTIL_FindEntityInSphere ( pObject , pev - > origin , MAX_PLAYER_USE_RADIUS ) ) )
2015-09-30 03:49:22 +03:00
{
if ( pObject - > ObjectCaps ( ) & ( FCAP_IMPULSE_USE | FCAP_CONTINUOUS_USE | FCAP_ONOFF_USE ) )
{
2016-02-04 03:18:26 +03:00
// TODO: PERFORMANCE- should this check be done on a per case basis AFTER we've determined that
2015-09-30 03:49:22 +03:00
// this object is actually usable? This dot is being done for every object within PLAYER_SEARCH_RADIUS
// when player hits the use key. How many objects can be in that area, anyway? (sjb)
vecLOS = ( VecBModelOrigin ( pObject - > pev ) - ( pev - > origin + pev - > view_ofs ) ) ;
vecLOS . NormalizeInPlace ( ) ;
flDot = DotProduct ( vecLOS , gpGlobals - > v_forward ) ;
// only if the item is in front of the user
if ( flDot > flMaxDot )
{
flMaxDot = flDot ;
pClosest = pObject ;
}
}
}
}
pObject = pClosest ;
// Found an object
2016-12-06 22:21:52 +03:00
if ( pObject )
2015-09-30 03:49:22 +03:00
{
if ( ! useNewHostages | | CanSeeUseable ( this , pObject ) )
{
2016-02-04 03:18:26 +03:00
// TODO: traceline here to prevent +USEing buttons through walls
2015-09-30 03:49:22 +03:00
int caps = pObject - > ObjectCaps ( ) ;
if ( m_afButtonPressed & IN_USE )
EMIT_SOUND ( ENT ( pev ) , CHAN_ITEM , " common/wpn_select.wav " , 0.4 , ATTN_NORM ) ;
if ( ( ( pev - > button & IN_USE ) & & ( caps & FCAP_CONTINUOUS_USE ) )
| | ( ( m_afButtonPressed & IN_USE ) & & ( caps & ( FCAP_IMPULSE_USE | FCAP_ONOFF_USE ) ) ) )
{
if ( caps & FCAP_CONTINUOUS_USE )
m_afPhysicsFlags | = PFLAG_USING ;
pObject - > Use ( this , this , USE_SET , 1 ) ;
}
// UNDONE: Send different USE codes for ON/OFF. Cache last ONOFF_USE object to send 'off' if you turn away
// BUGBUG This is an "off" use
else if ( ( m_afButtonReleased & IN_USE ) & & ( pObject - > ObjectCaps ( ) & FCAP_ONOFF_USE ) )
{
pObject - > Use ( this , this , USE_SET , 0 ) ;
}
}
}
2019-08-29 16:34:22 +03:00
else if ( m_afButtonPressed & IN_USE )
2015-09-30 03:49:22 +03:00
{
2019-08-29 16:34:22 +03:00
UseEmpty ( ) ;
2015-09-30 03:49:22 +03:00
}
}
2019-08-29 16:34:22 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , UseEmpty )
void EXT_FUNC CBasePlayer : : __API_HOOK ( UseEmpty ) ( )
{
EMIT_SOUND ( ENT ( pev ) , CHAN_ITEM , " common/wpn_denyselect.wav " , 0.4 , ATTN_NORM ) ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : HostageUsed ( )
2015-09-30 03:49:22 +03:00
{
if ( m_flDisplayHistory & DHF_HOSTAGE_USED )
return ;
if ( m_iTeam = = TERRORIST )
HintMessage ( " #Hint_use_hostage_to_stop_him " ) ;
else if ( m_iTeam = = CT )
HintMessage ( " #Hint_lead_hostage_to_rescue_point " ) ;
m_flDisplayHistory | = DHF_HOSTAGE_USED ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , Jump )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( Jump ) ( )
2015-09-30 03:49:22 +03:00
{
if ( pev - > flags & FL_WATERJUMP )
return ;
if ( pev - > waterlevel > = 2 )
{
return ;
}
// jump velocity is sqrt( height * gravity * 2)
// If this isn't the first frame pressing the jump button, break out.
if ( ! ( m_afButtonPressed & IN_JUMP ) )
{
// don't pogo stick
return ;
}
2017-10-13 03:04:37 +03:00
if ( ! ( pev - > flags & FL_ONGROUND ) | | ! pev - > groundentity )
2015-09-30 03:49:22 +03:00
return ;
// many features in this function use v_forward, so makevectors now.
UTIL_MakeVectors ( pev - > angles ) ;
SetAnimation ( PLAYER_JUMP ) ;
if ( ( pev - > flags & FL_DUCKING ) | | ( m_afPhysicsFlags & PFLAG_DUCKING ) )
{
if ( m_fLongJump & & ( pev - > button & IN_DUCK ) & & ( gpGlobals - > time - m_flDuckTime < 1.0f ) & & pev - > velocity . Length ( ) > 50 )
{
SetAnimation ( PLAYER_SUPERJUMP ) ;
}
}
// If you're standing on a conveyor, add it's velocity to yours (for momentum)
entvars_t * pevGround = VARS ( pev - > groundentity ) ;
if ( pevGround )
{
if ( pevGround - > flags & FL_CONVEYOR )
{
pev - > velocity = pev - > velocity + pev - > basevelocity ;
}
if ( FClassnameIs ( pevGround , " func_tracktrain " )
| | FClassnameIs ( pevGround , " func_train " )
| | FClassnameIs ( pevGround , " func_vehicle " ) )
{
pev - > velocity = pevGround - > velocity + pev - > velocity ;
}
}
}
// This is a glorious hack to find free space when you've crouched into some solid space
// Our crouching collisions do not work correctly for some reason and this is easier
// than fixing the problem :(
NOXREF void FixPlayerCrouchStuck ( edict_t * pPlayer )
{
TraceResult trace ;
// Move up as many as 18 pixels if the player is stuck.
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < 18 ; i + + )
2015-09-30 03:49:22 +03:00
{
UTIL_TraceHull ( pPlayer - > v . origin , pPlayer - > v . origin , dont_ignore_monsters , head_hull , pPlayer , & trace ) ;
if ( trace . fStartSolid )
2015-11-06 17:58:48 +03:00
pPlayer - > v . origin . z + + ;
2015-09-30 03:49:22 +03:00
else
break ;
}
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , Duck )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( Duck ) ( )
2015-09-30 03:49:22 +03:00
{
if ( pev - > button & IN_DUCK )
SetAnimation ( PLAYER_WALK ) ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CHAIN2 ( int , CBasePlayer , ObjectCaps )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
int EXT_FUNC CBasePlayer : : __API_HOOK ( ObjectCaps ) ( )
2016-04-05 03:12:05 +03:00
{
return ( CBaseMonster : : ObjectCaps ( ) & ~ FCAP_ACROSS_TRANSITION ) ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CHAIN2 ( int , CBasePlayer , Classify )
2016-04-05 03:12:05 +03:00
2015-11-06 17:58:48 +03:00
// ID's player as such.
2017-07-01 23:40:10 +03:00
int EXT_FUNC CBasePlayer : : __API_HOOK ( Classify ) ( )
2015-09-30 03:49:22 +03:00
{
return CLASS_PLAYER ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , AddPoints , ( int score , BOOL bAllowNegativeScore ) , score , bAllowNegativeScore )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( AddPoints ) ( int score , BOOL bAllowNegativeScore )
2015-09-30 03:49:22 +03:00
{
2015-11-06 17:58:48 +03:00
// Positive score always adds
2015-09-30 03:49:22 +03:00
if ( score < 0 & & ! bAllowNegativeScore )
{
2015-11-06 17:58:48 +03:00
// Can't go more negative
2015-09-30 03:49:22 +03:00
if ( pev - > frags < 0 )
return ;
if ( - score > pev - > frags )
2015-11-06 17:58:48 +03:00
{
// Sum will be 0
2015-09-30 03:49:22 +03:00
score = - pev - > frags ;
2015-11-06 17:58:48 +03:00
}
2015-09-30 03:49:22 +03:00
}
pev - > frags + = score ;
2016-10-07 15:19:51 +03:00
# ifdef REGAMEDLL_FIXES
MESSAGE_BEGIN ( MSG_ALL , gmsgScoreInfo ) ;
# else
2015-09-30 03:49:22 +03:00
MESSAGE_BEGIN ( MSG_BROADCAST , gmsgScoreInfo ) ;
2016-10-07 15:19:51 +03:00
# endif
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( ENTINDEX ( edict ( ) ) ) ;
2016-02-23 02:13:52 +03:00
WRITE_SHORT ( int ( pev - > frags ) ) ;
2015-09-30 03:49:22 +03:00
WRITE_SHORT ( m_iDeaths ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( m_iTeam ) ;
MESSAGE_END ( ) ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , AddPointsToTeam , ( int score , BOOL bAllowNegativeScore ) , score , bAllowNegativeScore )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( AddPointsToTeam ) ( int score , BOOL bAllowNegativeScore )
2015-09-30 03:49:22 +03:00
{
int index = entindex ( ) ;
2017-10-13 03:04:37 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
2015-09-30 03:49:22 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
2015-09-30 03:49:22 +03:00
2016-12-06 22:21:52 +03:00
if ( pPlayer & & i ! = index )
2015-09-30 03:49:22 +03:00
{
if ( g_pGameRules - > PlayerRelationship ( this , pPlayer ) = = GR_TEAMMATE )
2015-11-06 17:58:48 +03:00
{
2015-09-30 03:49:22 +03:00
pPlayer - > AddPoints ( score , bAllowNegativeScore ) ;
2015-11-06 17:58:48 +03:00
}
2015-09-30 03:49:22 +03:00
}
}
}
bool CBasePlayer : : CanPlayerBuy ( bool display )
{
2016-02-23 02:13:52 +03:00
if ( ! g_pGameRules - > IsMultiplayer ( ) )
2015-09-30 03:49:22 +03:00
{
return CHalfLifeTraining : : PlayerCanBuy ( this ) ;
}
// is the player alive?
if ( pev - > deadflag ! = DEAD_NO )
{
return false ;
}
// is the player in a buy zone?
if ( ! ( m_signals . GetState ( ) & SIGNAL_BUY ) )
{
return false ;
}
2016-10-07 15:19:51 +03:00
# ifdef REGAMEDLL_ADD
2016-12-06 22:21:52 +03:00
if ( buytime . value ! = - 1.0f )
2016-10-07 15:19:51 +03:00
# endif
2015-09-30 03:49:22 +03:00
{
2016-12-06 22:21:52 +03:00
int buyTime = int ( buytime . value * 60.0f ) ;
if ( buyTime < MIN_BUY_TIME )
2015-09-30 03:49:22 +03:00
{
2016-12-06 22:21:52 +03:00
buyTime = MIN_BUY_TIME ;
CVAR_SET_FLOAT ( " mp_buytime " , ( MIN_BUY_TIME / 60.0f ) ) ;
2015-09-30 03:49:22 +03:00
}
2016-12-06 22:21:52 +03:00
if ( gpGlobals - > time - CSGameRules ( ) - > m_fRoundStartTime > buyTime )
{
if ( display )
{
ClientPrint ( pev , HUD_PRINTCENTER , " #Cant_buy " , UTIL_dtos1 ( buyTime ) ) ;
}
return false ;
}
2015-09-30 03:49:22 +03:00
}
if ( m_bIsVIP )
{
if ( display )
{
ClientPrint ( pev , HUD_PRINTCENTER , " #VIP_cant_buy " ) ;
}
return false ;
}
2016-02-23 02:13:52 +03:00
if ( CSGameRules ( ) - > m_bCTCantBuy & & m_iTeam = = CT )
2015-09-30 03:49:22 +03:00
{
if ( display )
{
ClientPrint ( pev , HUD_PRINTCENTER , " #CT_cant_buy " ) ;
}
return false ;
}
2016-02-23 02:13:52 +03:00
if ( CSGameRules ( ) - > m_bTCantBuy & & m_iTeam = = TERRORIST )
2015-09-30 03:49:22 +03:00
{
if ( display )
{
ClientPrint ( pev , HUD_PRINTCENTER , " #Terrorist_cant_buy " ) ;
}
return false ;
}
return true ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , PreThink )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( PreThink ) ( )
2015-09-30 03:49:22 +03:00
{
// These buttons have changed this frame
int buttonsChanged = ( m_afButtonLast ^ pev - > button ) ;
2016-08-02 12:03:01 +03:00
// this means the player has pressed or released a key
2015-09-30 03:49:22 +03:00
if ( buttonsChanged )
2016-01-06 15:50:26 +03:00
{
2015-09-30 03:49:22 +03:00
m_fLastMovement = gpGlobals - > time ;
2016-01-06 15:50:26 +03:00
}
2015-09-30 03:49:22 +03:00
// Debounced button codes for pressed/released
// UNDONE: Do we need auto-repeat?
2019-08-13 16:11:27 +03:00
m_afButtonPressed = ( buttonsChanged & pev - > button ) ; // The changed ones still down are "pressed"
2015-09-30 03:49:22 +03:00
m_afButtonReleased = ( buttonsChanged & ( ~ pev - > button ) ) ; // The ones not down are "released"
// Hint messages should be updated even if the game is over
m_hintMessageQueue . Update ( this ) ;
g_pGameRules - > PlayerThink ( this ) ;
2016-12-06 22:21:52 +03:00
if ( g_pGameRules - > IsGameOver ( ) )
2015-09-30 03:49:22 +03:00
{
// intermission or finale
return ;
}
if ( m_iJoiningState ! = JOINED )
JoiningThink ( ) ;
// Mission Briefing text, remove it when the player hits an important button
if ( m_bMissionBriefing )
{
if ( m_afButtonPressed & ( IN_ATTACK | IN_ATTACK2 ) )
{
m_afButtonPressed & = ~ ( IN_ATTACK | IN_ATTACK2 ) ;
RemoveLevelText ( ) ;
m_bMissionBriefing = false ;
}
}
// is this still used?
UTIL_MakeVectors ( pev - > v_angle ) ;
ItemPreFrame ( ) ;
WaterMove ( ) ;
if ( pev - > flags & FL_ONGROUND )
{
// Slow down the player based on the velocity modifier
if ( m_flVelocityModifier < 1.0f )
{
2017-11-22 20:27:55 +03:00
real_t modvel = m_flVelocityModifier + 0.01 ;
2015-09-30 03:49:22 +03:00
m_flVelocityModifier = modvel ;
pev - > velocity = pev - > velocity * modvel ;
}
if ( m_flVelocityModifier > 1.0f )
m_flVelocityModifier = 1 ;
}
2019-07-08 21:17:20 +03:00
if (
# ifdef REGAMEDLL_FIXES
IsAlive ( ) & &
# endif
2020-02-06 00:31:59 +03:00
( m_flIdleCheckTime < = ( double ) gpGlobals - > time | | m_flIdleCheckTime = = 0.0f ) )
2015-09-30 03:49:22 +03:00
{
// check every 5 seconds
m_flIdleCheckTime = gpGlobals - > time + 5.0 ;
2019-06-07 21:07:12 +03:00
# ifdef REGAMEDLL_ADD
if ( CSPlayer ( ) - > CheckActivityInGame ( ) )
{
m_fLastMovement = gpGlobals - > time ;
}
# endif
2017-11-22 20:27:55 +03:00
real_t flLastMove = gpGlobals - > time - m_fLastMovement ;
2015-09-30 03:49:22 +03:00
//check if this player has been inactive for 2 rounds straight
2019-11-02 11:48:23 +03:00
if ( ! IsBot ( ) & & flLastMove > CSGameRules ( ) - > m_fMaxIdlePeriod )
2015-09-30 03:49:22 +03:00
{
2019-11-02 11:48:23 +03:00
DropIdlePlayer ( " Player idle " ) ;
2020-01-15 18:10:32 +03:00
2019-11-02 11:48:23 +03:00
m_fLastMovement = gpGlobals - > time ;
2015-09-30 03:49:22 +03:00
}
2019-06-07 21:07:12 +03:00
# ifdef REGAMEDLL_ADD
if ( afk_bomb_drop_time . value > 0.0 & & IsBombGuy ( ) )
{
if ( flLastMove > afk_bomb_drop_time . value & & ! CSGameRules ( ) - > IsFreezePeriod ( ) )
{
DropPlayerItem ( " weapon_c4 " ) ;
}
}
# endif
2015-09-30 03:49:22 +03:00
}
2016-12-06 22:21:52 +03:00
if ( g_pGameRules & & g_pGameRules - > FAllowFlashlight ( ) )
2015-09-30 03:49:22 +03:00
m_iHideHUD & = ~ HIDEHUD_FLASHLIGHT ;
else
m_iHideHUD | = HIDEHUD_FLASHLIGHT ;
// JOHN: checks if new client data (for HUD and view control) needs to be sent to the client
UpdateClientData ( ) ;
CheckTimeBasedDamage ( ) ;
CheckSuitUpdate ( ) ;
// So the correct flags get sent to client asap.
if ( m_afPhysicsFlags & PFLAG_ONTRAIN )
pev - > flags | = FL_ONTRAIN ;
else
pev - > flags & = ~ FL_ONTRAIN ;
2017-01-20 17:52:37 +03:00
# ifdef REGAMEDLL_ADD
PlayerRespawnThink ( ) ;
# endif
2015-09-30 03:49:22 +03:00
// Observer Button Handling
2018-02-08 12:37:02 +03:00
if ( GetObserverMode ( ) ! = OBS_NONE & & ( m_afPhysicsFlags & PFLAG_OBSERVER ) )
2015-09-30 03:49:22 +03:00
{
2017-01-20 17:52:37 +03:00
Observer_Think ( ) ;
2015-09-30 03:49:22 +03:00
return ;
}
if ( pev - > deadflag > = DEAD_DYING & & pev - > deadflag ! = DEAD_RESPAWNABLE )
{
PlayerDeathThink ( ) ;
return ;
}
// new code to determine if a player is on a train or not
CBaseEntity * pGroundEntity = Instance ( pev - > groundentity ) ;
if ( pGroundEntity & & pGroundEntity - > Classify ( ) = = CLASS_VEHICLE )
{
pev - > iuser4 = 1 ;
}
else
{
pev - > iuser4 = 0 ;
}
// Train speed control
if ( m_afPhysicsFlags & PFLAG_ONTRAIN )
{
CBaseEntity * pTrain = Instance ( pev - > groundentity ) ;
float vel ;
if ( ! pTrain )
{
TraceResult trainTrace ;
// Maybe this is on the other side of a level transition
UTIL_TraceLine ( pev - > origin , pev - > origin + Vector ( 0 , 0 , - 38 ) , ignore_monsters , ENT ( pev ) , & trainTrace ) ;
// HACKHACK - Just look for the func_tracktrain classname
if ( trainTrace . flFraction ! = 1.0f & & trainTrace . pHit )
pTrain = Instance ( trainTrace . pHit ) ;
if ( ! pTrain | | ! ( pTrain - > ObjectCaps ( ) & FCAP_DIRECTIONAL_USE ) | | ! pTrain - > OnControls ( pev ) )
{
m_afPhysicsFlags & = ~ PFLAG_ONTRAIN ;
m_iTrain = ( TRAIN_NEW | TRAIN_OFF ) ;
2023-09-05 06:52:30 +03:00
2023-09-28 12:18:15 +03:00
# ifdef REGAMEDLL_FIXES
2023-09-05 06:52:30 +03:00
if ( pTrain & & pTrain - > Classify ( ) = = CLASS_VEHICLE ) // ensure func_vehicle's m_pDriver assignation
# endif
{
2022-12-06 22:11:25 +03:00
# ifdef REGAMEDLL_ADD
2023-09-05 06:52:30 +03:00
if ( legacy_vehicle_block . value = = 0 )
return ;
2022-12-06 22:11:25 +03:00
# endif
2023-09-05 06:52:30 +03:00
( ( CFuncVehicle * ) pTrain ) - > m_pDriver = nullptr ;
}
2015-09-30 03:49:22 +03:00
return ;
}
}
else if ( ! ( pev - > flags & FL_ONGROUND ) | | ( pTrain - > pev - > spawnflags & SF_TRACKTRAIN_NOCONTROL ) )
{
// Turn off the train if you jump, strafe, or the train controls go dead
m_afPhysicsFlags & = ~ PFLAG_ONTRAIN ;
m_iTrain = ( TRAIN_NEW | TRAIN_OFF ) ;
2023-09-05 06:52:30 +03:00
2023-09-28 12:18:15 +03:00
# ifdef REGAMEDLL_FIXES
2023-09-05 06:52:30 +03:00
if ( pTrain - > Classify ( ) = = CLASS_VEHICLE ) // ensure func_vehicle's m_pDriver assignation
# endif
{
2022-12-06 22:11:25 +03:00
# ifdef REGAMEDLL_ADD
2023-09-05 06:52:30 +03:00
if ( legacy_vehicle_block . value = = 0 )
return ;
2022-12-06 22:11:25 +03:00
# endif
2023-09-05 06:52:30 +03:00
( ( CFuncVehicle * ) pTrain ) - > m_pDriver = nullptr ;
}
2015-09-30 03:49:22 +03:00
return ;
}
pev - > velocity = g_vecZero ;
vel = 0 ;
if ( pTrain - > Classify ( ) = = CLASS_VEHICLE )
{
if ( pev - > button & IN_FORWARD )
{
vel = 1 ;
pTrain - > Use ( this , this , USE_SET , vel ) ;
}
if ( pev - > button & IN_BACK )
{
vel = - 1 ;
pTrain - > Use ( this , this , USE_SET , vel ) ;
}
if ( pev - > button & IN_MOVELEFT )
{
vel = 20 ;
pTrain - > Use ( this , this , USE_SET , vel ) ;
}
if ( pev - > button & IN_MOVERIGHT )
{
vel = 30 ;
pTrain - > Use ( this , this , USE_SET , vel ) ;
}
}
else
{
if ( m_afButtonPressed & IN_FORWARD )
{
vel = 1 ;
pTrain - > Use ( this , this , USE_SET , vel ) ;
}
else if ( m_afButtonPressed & IN_BACK )
{
vel = - 1 ;
pTrain - > Use ( this , this , USE_SET , vel ) ;
}
}
if ( vel )
{
m_iTrain = TrainSpeed ( pTrain - > pev - > speed , pTrain - > pev - > impulse ) ;
m_iTrain | = ( TRAIN_ACTIVE | TRAIN_NEW ) ;
}
}
else if ( m_iTrain & TRAIN_ACTIVE )
{
// turn off train
m_iTrain = TRAIN_NEW ;
}
if ( pev - > button & IN_JUMP )
{
// If on a ladder, jump off the ladder
// else Jump
Jump ( ) ;
}
// If trying to duck, already ducked, or in the process of ducking
if ( ( pev - > button & IN_DUCK ) | | ( pev - > flags & FL_DUCKING ) | | ( m_afPhysicsFlags & PFLAG_DUCKING ) )
{
Duck ( ) ;
}
if ( ! ( pev - > flags & FL_ONGROUND ) )
{
m_flFallVelocity = - pev - > velocity . z ;
}
2016-02-04 03:18:26 +03:00
// TODO: (HACKHACK) Can't be hit by traceline when not animating?
2015-09-30 03:49:22 +03:00
//StudioFrameAdvance();
// Clear out ladder pointer
2017-10-13 03:04:37 +03:00
m_hEnemy = nullptr ;
2015-09-30 03:49:22 +03:00
if ( m_afPhysicsFlags & PFLAG_ONBARNACLE )
{
pev - > velocity = g_vecZero ;
}
if ( ! ( m_flDisplayHistory & DHF_ROUND_STARTED ) & & CanPlayerBuy ( false ) )
{
HintMessage ( " #Hint_press_buy_to_purchase " , FALSE ) ;
m_flDisplayHistory | = DHF_ROUND_STARTED ;
}
UpdateLocation ( ) ;
2018-02-18 14:31:24 +03:00
# ifdef REGAMEDLL_ADD
2019-08-13 16:11:27 +03:00
auto protectStateCurrent = CSPlayer ( ) - > GetProtectionState ( ) ;
2021-05-22 14:04:43 +03:00
if ( protectStateCurrent = = CCSPlayer : : ProtectionSt_Expired | |
( protectStateCurrent = = CCSPlayer : : ProtectionSt_Active & &
( ( respawn_immunity_force_unset . value = = 1 & & ( m_afButtonPressed & IN_ACTIVE ) ) | | ( respawn_immunity_force_unset . value = = 2 & & ( m_afButtonPressed & ( IN_ATTACK | IN_ATTACK2 ) ) ) ) ) )
2018-02-18 14:31:24 +03:00
{
RemoveSpawnProtection ( ) ;
}
# endif
2015-09-30 03:49:22 +03:00
}
2023-09-05 06:43:40 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , CheckTimeBasedDamage )
2015-09-30 03:49:22 +03:00
// If player is taking time based damage, continue doing damage to player -
// this simulates the effect of being poisoned, gassed, dosed with radiation etc -
// anything that continues to do damage even after the initial contact stops.
// Update all time based damage counters, and shut off any that are done.
// The m_bitsDamageType bit MUST be set if any damage is to be taken.
// This routine will detect the initial on value of the m_bitsDamageType
// and init the appropriate counter. Only processes damage every second.
2023-09-05 06:43:40 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( CheckTimeBasedDamage ) ( )
2015-09-30 03:49:22 +03:00
{
int i ;
2016-07-20 19:44:00 +03:00
byte bDuration = 0 ;
2015-09-30 03:49:22 +03:00
if ( ! ( m_bitsDamageType & DMG_TIMEBASED ) )
return ;
2015-11-06 17:58:48 +03:00
// only check for time based damage approx. every 2 seconds
2017-11-07 17:27:54 +03:00
# ifdef REGAMEDLL_FIXES
if ( Q_abs ( gpGlobals - > time - m_tbdPrev ) < 2.0f )
# else
2016-02-23 02:13:52 +03:00
if ( Q_abs ( int64 ( gpGlobals - > time - m_tbdPrev ) ) < 2.0f )
2017-11-07 17:27:54 +03:00
# endif
2015-09-30 03:49:22 +03:00
return ;
m_tbdPrev = gpGlobals - > time ;
2017-10-13 03:04:37 +03:00
for ( i = 0 ; i < ITBD_END ; i + + )
2015-09-30 03:49:22 +03:00
{
2015-11-06 17:58:48 +03:00
// make sure bit is set for damage type
2015-09-30 03:49:22 +03:00
if ( m_bitsDamageType & ( DMG_PARALYZE < < i ) )
{
switch ( i )
{
2022-12-16 12:13:42 +03:00
case ITBD_PARALYZE :
2015-09-30 03:49:22 +03:00
// UNDONE - flag movement as half-speed
bDuration = PARALYZE_DURATION ;
break ;
2017-10-12 17:50:56 +03:00
case ITBD_NERVE_GAS :
2015-09-30 03:49:22 +03:00
bDuration = NERVEGAS_DURATION ;
break ;
2017-10-12 17:50:56 +03:00
case ITBD_POISON :
2015-09-30 03:49:22 +03:00
{
TakeDamage ( pev , pev , POISON_DAMAGE , DMG_GENERIC ) ;
bDuration = POISON_DURATION ;
break ;
}
2017-10-12 17:50:56 +03:00
case ITBD_DROWN_RECOVER :
2015-09-30 03:49:22 +03:00
{
2015-11-06 17:58:48 +03:00
// NOTE: this hack is actually used to RESTORE health
// after the player has been drowning and finally takes a breath
2015-09-30 03:49:22 +03:00
if ( m_idrowndmg > m_idrownrestored )
{
int idif = Q_min ( m_idrowndmg - m_idrownrestored , 10 ) ;
2015-11-06 17:58:48 +03:00
2015-09-30 03:49:22 +03:00
TakeHealth ( idif , DMG_GENERIC ) ;
m_idrownrestored + = idif ;
}
2015-11-06 17:58:48 +03:00
// get up to 5*10 = 50 points back
2015-09-30 03:49:22 +03:00
bDuration = 4 ;
break ;
}
2017-10-12 17:50:56 +03:00
case ITBD_RADIATION :
2015-09-30 03:49:22 +03:00
bDuration = RADIATION_DURATION ;
break ;
2017-10-12 17:50:56 +03:00
case ITBD_ACID :
2015-09-30 03:49:22 +03:00
bDuration = ACID_DURATION ;
break ;
2017-10-12 17:50:56 +03:00
case ITBD_SLOW_BURN :
2015-09-30 03:49:22 +03:00
bDuration = SLOWBURN_DURATION ;
break ;
2017-10-12 17:50:56 +03:00
case ITBD_SLOW_FREEZE :
2015-09-30 03:49:22 +03:00
bDuration = SLOWFREEZE_DURATION ;
break ;
default :
bDuration = 0 ;
break ;
}
if ( m_rgbTimeBasedDamage [ i ] )
{
// use up an antitoxin on poison or nervegas after a few seconds of damage
2017-10-12 17:50:56 +03:00
if ( ( i = = ITBD_NERVE_GAS & & m_rgbTimeBasedDamage [ i ] < NERVEGAS_DURATION ) | | ( i = = ITBD_POISON & & m_rgbTimeBasedDamage [ i ] < POISON_DURATION ) )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
if ( m_rgItems [ ITEM_ID_ANTIDOTE ] )
2015-09-30 03:49:22 +03:00
{
m_rgbTimeBasedDamage [ i ] = 0 ;
2017-10-13 03:04:37 +03:00
m_rgItems [ ITEM_ID_ANTIDOTE ] - - ;
2017-10-12 17:50:56 +03:00
SetSuitUpdate ( " !HEV_HEAL4 " , SUIT_SENTENCE , SUIT_REPEAT_OK ) ;
2015-09-30 03:49:22 +03:00
}
}
// decrement damage duration, detect when done.
if ( ! m_rgbTimeBasedDamage [ i ] | | - - m_rgbTimeBasedDamage [ i ] = = 0 )
{
m_rgbTimeBasedDamage [ i ] = 0 ;
// if we're done, clear damage bits
m_bitsDamageType & = ~ ( DMG_PARALYZE < < i ) ;
}
}
else
// first time taking this damage type - init damage duration
m_rgbTimeBasedDamage [ i ] = bDuration ;
}
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : UpdateGeigerCounter ( )
2015-09-30 03:49:22 +03:00
{
2016-07-20 19:44:00 +03:00
byte range ;
2015-11-06 17:58:48 +03:00
// delay per update ie: don't flood net with these msgs
2015-09-30 03:49:22 +03:00
if ( gpGlobals - > time < m_flgeigerDelay )
return ;
m_flgeigerDelay = gpGlobals - > time + 0.25 ;
2015-11-06 17:58:48 +03:00
// send range to radition source to client
2016-02-23 02:13:52 +03:00
range = byte ( m_flgeigerRange / 4.0 ) ; //* 0.25); // TODO: ACHECK!
2015-09-30 03:49:22 +03:00
if ( range ! = m_igeigerRangePrev )
{
m_igeigerRangePrev = range ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgGeigerRange , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( range ) ;
MESSAGE_END ( ) ;
}
2015-11-06 17:58:48 +03:00
// reset counter and semaphore
2015-09-30 03:49:22 +03:00
if ( ! RANDOM_LONG ( 0 , 3 ) )
2015-11-06 17:58:48 +03:00
{
2015-09-30 03:49:22 +03:00
m_flgeigerRange = 1000.0 ;
2015-11-06 17:58:48 +03:00
}
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : CheckSuitUpdate ( )
2015-09-30 03:49:22 +03:00
{
int i ;
int isentence = 0 ;
int isearch = m_iSuitPlayNext ;
// Ignore suit updates if no suit
if ( ! ( pev - > weapons & ( 1 < < WEAPON_SUIT ) ) )
return ;
// if in range of radiation source, ping geiger counter
UpdateGeigerCounter ( ) ;
if ( g_pGameRules - > IsMultiplayer ( ) )
{
// don't bother updating HEV voice in multiplayer.
return ;
}
if ( gpGlobals - > time > = m_flSuitUpdate & & m_flSuitUpdate > 0 )
{
// play a sentence off of the end of the queue
2017-10-13 03:04:37 +03:00
for ( i = 0 ; i < MAX_SUIT_NOREPEAT ; i + + )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
if ( ( isentence = m_rgSuitPlayList [ isearch ] ) )
2015-09-30 03:49:22 +03:00
break ;
2017-10-12 17:50:56 +03:00
if ( + + isearch = = MAX_SUIT_NOREPEAT )
2015-09-30 03:49:22 +03:00
isearch = 0 ;
}
if ( isentence )
{
2017-10-19 20:12:02 +03:00
m_rgSuitPlayList [ isearch ] = 0 ;
2015-09-30 03:49:22 +03:00
if ( isentence > 0 )
{
// play sentence number
2017-10-12 17:50:56 +03:00
char sentence [ MAX_SENTENCE_NAME + 1 ] ;
2015-09-30 03:49:22 +03:00
Q_strcpy ( sentence , " ! " ) ;
Q_strcat ( sentence , gszallsentencenames [ isentence ] ) ;
EMIT_SOUND_SUIT ( ENT ( pev ) , sentence ) ;
}
else
{
// play sentence group
EMIT_GROUPID_SUIT ( ENT ( pev ) , - isentence ) ;
}
2017-10-12 17:50:56 +03:00
m_flSuitUpdate = gpGlobals - > time + SUIT_UPDATE_TIME ;
2015-09-30 03:49:22 +03:00
}
else
// queue is empty, don't check
m_flSuitUpdate = 0 ;
}
}
2017-10-12 17:50:56 +03:00
// add sentence to suit playlist queue. if group is true, then
2015-11-06 17:58:48 +03:00
// name is a sentence group (HEV_AA), otherwise name is a specific
// sentence name ie: !HEV_AA0. If iNoRepeat is specified in
// seconds, then we won't repeat playback of this word or sentence
// for at least that number of seconds.
2017-10-12 17:50:56 +03:00
void CBasePlayer : : SetSuitUpdate ( char * name , bool group , int iNoRepeatTime )
2015-09-30 03:49:22 +03:00
{
;
}
2016-02-23 02:13:52 +03:00
void CBasePlayer : : CheckPowerups ( )
2015-09-30 03:49:22 +03:00
{
2015-11-06 17:58:48 +03:00
if ( pev - > health < = 0.0f )
return ;
// don't use eyes
pev - > modelindex = m_modelIndexPlayer ;
2015-09-30 03:49:22 +03:00
}
void CBasePlayer : : SetNewPlayerModel ( const char * modelName )
{
SET_MODEL ( edict ( ) , modelName ) ;
m_modelIndexPlayer = pev - > modelindex ;
2017-01-29 02:56:29 +03:00
# ifdef REGAMEDLL_FIXES
ResetSequenceInfo ( ) ;
# endif
2015-09-30 03:49:22 +03:00
}
// UpdatePlayerSound - updates the position of the player's
// reserved sound slot in the sound list.
2016-02-04 03:18:26 +03:00
void CBasePlayer : : UpdatePlayerSound ( )
2015-09-30 03:49:22 +03:00
{
int iBodyVolume ;
int iVolume ;
2016-04-05 03:12:05 +03:00
CSound * pSound = CSoundEnt : : SoundPointerForIndex ( CSoundEnt : : ClientSoundIndex ( edict ( ) ) ) ;
2015-09-30 03:49:22 +03:00
if ( ! pSound )
{
ALERT ( at_console , " Client lost reserved sound! \n " ) ;
return ;
}
pSound - > m_iType = bits_SOUND_NONE ;
// now calculate the best target volume for the sound. If the player's weapon
// is louder than his body/movement, use the weapon volume, else, use the body volume.
2015-11-06 17:58:48 +03:00
// now figure out how loud the player's movement is.
2015-09-30 03:49:22 +03:00
if ( pev - > flags & FL_ONGROUND )
{
iBodyVolume = pev - > velocity . Length ( ) ;
// clamp the noise that can be made by the body, in case a push trigger,
// weapon recoil, or anything shoves the player abnormally fast.
2015-11-06 17:58:48 +03:00
// NOTE: 512 units is a pretty large radius for a sound made by the player's body.
// then again, I think some materials are pretty loud.
2019-10-09 13:18:42 +03:00
if ( iBodyVolume > 512 )
2015-09-30 03:49:22 +03:00
{
iBodyVolume = 512 ;
}
}
else
{
iBodyVolume = 0 ;
}
if ( pev - > button & IN_JUMP )
{
2015-11-06 17:58:48 +03:00
// Jumping is a little louder.
2015-09-30 03:49:22 +03:00
iBodyVolume + = 100 ;
}
// convert player move speed and actions into sound audible by monsters.
if ( m_iWeaponVolume > iBodyVolume )
{
m_iTargetVolume = m_iWeaponVolume ;
// OR in the bits for COMBAT sound if the weapon is being louder than the player.
pSound - > m_iType | = bits_SOUND_COMBAT ;
}
else
{
m_iTargetVolume = iBodyVolume ;
}
// decay weapon volume over time so bits_SOUND_COMBAT stays set for a while
m_iWeaponVolume - = 250 * gpGlobals - > frametime ;
// if target volume is greater than the player sound's current volume, we paste the new volume in
// immediately. If target is less than the current volume, current volume is not set immediately to the
// lower volume, rather works itself towards target volume over time. This gives monsters a much better chance
// to hear a sound, especially if they don't listen every frame.
iVolume = pSound - > m_iVolume ;
if ( m_iTargetVolume > iVolume )
{
iVolume = m_iTargetVolume ;
}
else if ( iVolume > m_iTargetVolume )
{
iVolume - = 250 * gpGlobals - > frametime ;
if ( iVolume < m_iTargetVolume )
iVolume = 0 ;
}
if ( m_fNoPlayerSound )
{
// debugging flag, lets players move around and shoot without monsters hearing.
iVolume = 0 ;
}
if ( gpGlobals - > time > m_flStopExtraSoundTime )
{
// since the extra sound that a weapon emits only lasts for one client frame, we keep that sound around for a server frame or two
// after actual emission to make sure it gets heard.
m_iExtraSoundTypes = 0 ;
}
2016-12-06 22:21:52 +03:00
if ( pSound )
2015-09-30 03:49:22 +03:00
{
pSound - > m_vecOrigin = pev - > origin ;
pSound - > m_iVolume = iVolume ;
pSound - > m_iType | = ( bits_SOUND_PLAYER | m_iExtraSoundTypes ) ;
}
// keep track of virtual muzzle flash
m_iWeaponFlash - = 256 * gpGlobals - > frametime ;
if ( m_iWeaponFlash < 0 )
m_iWeaponFlash = 0 ;
UTIL_MakeVectors ( pev - > angles ) ;
gpGlobals - > v_forward . z = 0 ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , PostThink )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( PostThink ) ( )
2015-09-30 03:49:22 +03:00
{
// intermission or finale
2016-12-06 22:21:52 +03:00
if ( g_pGameRules - > IsGameOver ( ) )
2015-09-30 03:49:22 +03:00
goto pt_end ;
if ( ! IsAlive ( ) )
goto pt_end ;
// Handle Tank controlling
2016-12-06 22:21:52 +03:00
if ( m_pTank )
2015-09-30 03:49:22 +03:00
{
// if they've moved too far from the gun, or selected a weapon, unuse the gun
if ( m_pTank - > OnControls ( pev ) & & ! pev - > weaponmodel )
{
// try fire the gun
m_pTank - > Use ( this , this , USE_SET , 2 ) ;
}
else
{
// they've moved off the platform
m_pTank - > Use ( this , this , USE_OFF , 0 ) ;
2017-10-13 03:04:37 +03:00
m_pTank = nullptr ;
2015-09-30 03:49:22 +03:00
}
}
// do weapon stuff
ItemPostFrame ( ) ;
// check to see if player landed hard enough to make a sound
// falling farther than half of the maximum safe distance, but not as far a max safe distance will
// play a bootscrape sound, and no damage will be inflicted. Fallling a distance shorter than half
// of maximum safe distance will make no sound. Falling farther than max safe distance will play a
// fallpain sound, and damage will be inflicted based on how far the player fell
if ( ( pev - > flags & FL_ONGROUND ) & & pev - > health > 0.0f & & m_flFallVelocity > = PLAYER_FALL_PUNCH_THRESHHOLD )
{
if ( pev - > watertype ! = CONTENT_WATER )
{
// after this point, we start doing damage
2017-10-12 17:50:56 +03:00
if ( m_flFallVelocity > MAX_PLAYER_SAFE_FALL_SPEED )
2015-09-30 03:49:22 +03:00
{
float flFallDamage = g_pGameRules - > FlPlayerFallDamage ( this ) ;
2016-12-10 21:27:53 +03:00
// splat
2015-09-30 03:49:22 +03:00
if ( flFallDamage > pev - > health )
{
2016-12-10 21:27:53 +03:00
// NOTE: play on item channel because we play footstep landing on body channel
2015-09-30 03:49:22 +03:00
EMIT_SOUND ( ENT ( pev ) , CHAN_ITEM , " common/bodysplat.wav " , VOL_NORM , ATTN_NORM ) ;
}
2017-11-01 18:01:24 +03:00
2017-06-30 14:22:33 +03:00
# ifdef REGAMEDLL_FIXES
if ( flFallDamage > = 1.0f )
# else
2015-09-30 03:49:22 +03:00
if ( flFallDamage > 0 )
2017-06-30 14:22:33 +03:00
# endif
2015-09-30 03:49:22 +03:00
{
m_LastHitGroup = HITGROUP_GENERIC ;
2023-09-28 12:18:15 +03:00
// FIXED: The player falling to the ground,
// the damage caused by the fall is initiated by himself (and not by the world)
entvars_t * pevAttacker =
# ifdef REGAMEDLL_FIXES
pev ;
# else
VARS ( eoNullEntity ) ;
# endif
TakeDamage ( pevAttacker , pevAttacker , flFallDamage , DMG_FALL ) ;
2015-09-30 03:49:22 +03:00
pev - > punchangle . x = 0 ;
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-12-05 22:40:30 +03:00
{
TheBots - > OnEvent ( EVENT_PLAYER_LANDED_FROM_HEIGHT , this ) ;
}
2015-09-30 03:49:22 +03:00
}
}
}
if ( IsAlive ( ) )
{
SetAnimation ( PLAYER_WALK ) ;
}
}
if ( pev - > flags & FL_ONGROUND )
{
2016-04-05 03:12:05 +03:00
# ifndef REGAMEDLL_FIXES
2015-09-30 03:49:22 +03:00
if ( m_flFallVelocity > 64.0f & & ! g_pGameRules - > IsMultiplayer ( ) )
{
CSoundEnt : : InsertSound ( bits_SOUND_PLAYER , pev - > origin , m_flFallVelocity , 0.2 ) ;
}
2016-04-05 03:12:05 +03:00
# endif
2015-09-30 03:49:22 +03:00
m_flFallVelocity = 0 ;
}
// select the proper animation for the player character
if ( IsAlive ( ) )
{
if ( pev - > velocity . x | | pev - > velocity . y )
{
if ( ( ( pev - > velocity . x | | pev - > velocity . y ) & & ( pev - > flags & FL_ONGROUND ) ) | | pev - > waterlevel > 1 )
SetAnimation ( PLAYER_WALK ) ;
}
else if ( pev - > gaitsequence ! = ACT_FLY )
SetAnimation ( PLAYER_IDLE ) ;
}
StudioFrameAdvance ( ) ;
2016-02-23 02:13:52 +03:00
CheckPowerups ( ) ;
2016-03-17 20:44:52 +03:00
2017-01-20 17:52:37 +03:00
# ifdef REGAMEDLL_ADD
if ( m_flTimeStepSound ) {
pev - > flTimeStepSound = int ( m_flTimeStepSound ) ;
}
# endif
2016-12-10 21:27:53 +03:00
// NOTE: this is useless for CS 1.6 - s1lent
2016-03-17 20:44:52 +03:00
# ifndef REGAMEDLL_FIXES
2015-09-30 03:49:22 +03:00
UpdatePlayerSound ( ) ;
2016-03-17 20:44:52 +03:00
# endif
2015-09-30 03:49:22 +03:00
pt_end :
# ifdef CLIENT_WEAPONS
// Decay timers on weapons
// go through all of the weapons and make a list of the ones to pack
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < MAX_ITEM_TYPES ; i + + )
2015-09-30 03:49:22 +03:00
{
if ( m_rgpPlayerItems [ i ] )
{
CBasePlayerItem * pPlayerItem = m_rgpPlayerItems [ i ] ;
2016-12-06 22:21:52 +03:00
while ( pPlayerItem )
2015-09-30 03:49:22 +03:00
{
CBasePlayerWeapon * gun = ( CBasePlayerWeapon * ) pPlayerItem - > GetWeaponPtr ( ) ;
if ( gun & & gun - > UseDecrement ( ) )
{
gun - > m_flNextPrimaryAttack = Q_max ( gun - > m_flNextPrimaryAttack - gpGlobals - > frametime , - 1.0f ) ;
gun - > m_flNextSecondaryAttack = Q_max ( gun - > m_flNextSecondaryAttack - gpGlobals - > frametime , - 0.001f ) ;
if ( gun - > m_flTimeWeaponIdle ! = 1000.0f )
{
gun - > m_flTimeWeaponIdle = Q_max ( gun - > m_flTimeWeaponIdle - gpGlobals - > frametime , - 0.001f ) ;
}
}
pPlayerItem = pPlayerItem - > m_pNext ;
}
}
}
m_flNextAttack - = gpGlobals - > frametime ;
if ( m_flNextAttack < - 0.001 )
m_flNextAttack = - 0.001 ;
# endif // CLIENT_WEAPONS
// Track button info so we can detect 'pressed' and 'released' buttons next frame
m_afButtonLast = pev - > button ;
m_iGaitsequence = pev - > gaitsequence ;
StudioProcessGait ( ) ;
}
2015-11-06 17:58:48 +03:00
// checks if the spot is clear of players
2015-09-30 03:49:22 +03:00
BOOL IsSpawnPointValid ( CBaseEntity * pPlayer , CBaseEntity * pSpot )
{
if ( ! pSpot - > IsTriggered ( pPlayer ) )
return FALSE ;
2019-09-22 17:49:52 +03:00
# ifdef REGAMEDLL_ADD
if ( ! kill_filled_spawn . value )
return TRUE ;
# endif
2017-10-13 03:04:37 +03:00
CBaseEntity * pEntity = nullptr ;
while ( ( pEntity = UTIL_FindEntityInSphere ( pEntity , pSpot - > pev - > origin , MAX_PLAYER_USE_RADIUS ) ) )
2015-09-30 03:49:22 +03:00
{
2015-11-06 17:58:48 +03:00
// if ent is a client, don't spawn on 'em
2017-10-13 03:04:37 +03:00
if ( pEntity - > IsPlayer ( ) & & pEntity ! = pPlayer )
2015-09-30 03:49:22 +03:00
return FALSE ;
}
return TRUE ;
}
2015-11-06 17:58:48 +03:00
bool CBasePlayer : : SelectSpawnSpot ( const char * pEntClassName , CBaseEntity * & pSpot )
{
2017-10-13 03:04:37 +03:00
edict_t * pPlayer = edict ( ) ;
2015-11-06 17:58:48 +03:00
// Find the next spawn spot.
pSpot = UTIL_FindEntityByClassname ( pSpot , pEntClassName ) ;
// skip over the null point
if ( FNullEnt ( pSpot ) )
{
pSpot = UTIL_FindEntityByClassname ( pSpot , pEntClassName ) ;
}
CBaseEntity * pFirstSpot = pSpot ;
do
{
2016-12-06 22:21:52 +03:00
if ( pSpot )
2015-11-06 17:58:48 +03:00
{
// check if pSpot is valid
if ( IsSpawnPointValid ( this , pSpot ) )
{
if ( pSpot - > pev - > origin = = Vector ( 0 , 0 , 0 ) )
{
pSpot = UTIL_FindEntityByClassname ( pSpot , pEntClassName ) ;
continue ;
}
// if so, go to pSpot
return true ;
}
}
// increment pSpot
pSpot = UTIL_FindEntityByClassname ( pSpot , pEntClassName ) ;
}
// loop if we're not back to the start
while ( pSpot ! = pFirstSpot ) ;
// we haven't found a place to spawn yet, so kill any guy at the first spawn point and spawn there
if ( ! FNullEnt ( pSpot ) )
{
2018-10-26 20:11:23 +03:00
# ifdef REGAMEDLL_ADD
if ( kill_filled_spawn . value ! = 0.0 )
# endif
2015-11-06 17:58:48 +03:00
{
2018-10-26 20:11:23 +03:00
CBaseEntity * pEntity = nullptr ;
while ( ( pEntity = UTIL_FindEntityInSphere ( pEntity , pSpot - > pev - > origin , MAX_PLAYER_USE_RADIUS ) ) )
{
// if ent is a client, kill em (unless they are ourselves)
if ( pEntity - > IsPlayer ( ) & & pEntity - > edict ( ) ! = pPlayer )
{
pEntity - > TakeDamage ( VARS ( eoNullEntity ) , VARS ( eoNullEntity ) , 200 , DMG_GENERIC ) ;
}
}
2015-11-06 17:58:48 +03:00
}
// if so, go to pSpot
return true ;
}
return false ;
}
2017-10-12 17:50:56 +03:00
CBaseEntity * g_pLastSpawn ;
CBaseEntity * g_pLastCTSpawn ;
CBaseEntity * g_pLastTerroristSpawn ;
2023-09-05 06:43:40 +03:00
LINK_HOOK_CLASS_CHAIN2 ( edict_t * , CBasePlayer , EntSelectSpawnPoint )
edict_t * EXT_FUNC CBasePlayer : : __API_HOOK ( EntSelectSpawnPoint ) ( )
2015-09-30 03:49:22 +03:00
{
CBaseEntity * pSpot ;
// choose a info_player_deathmatch point
if ( g_pGameRules - > IsCoOp ( ) )
{
pSpot = UTIL_FindEntityByClassname ( g_pLastSpawn , " info_player_coop " ) ;
if ( ! FNullEnt ( pSpot ) )
goto ReturnSpot ;
pSpot = UTIL_FindEntityByClassname ( g_pLastSpawn , " info_player_start " ) ;
if ( ! FNullEnt ( pSpot ) )
goto ReturnSpot ;
}
2015-11-06 17:58:48 +03:00
// VIP spawn point
2016-06-02 01:08:22 +03:00
else if ( g_pGameRules - > IsDeathmatch ( ) & & m_bIsVIP )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
pSpot = UTIL_FindEntityByClassname ( nullptr , " info_vip_start " ) ;
2015-09-30 03:49:22 +03:00
// skip over the null point
if ( ! FNullEnt ( pSpot ) )
{
goto ReturnSpot ;
}
goto CTSpawn ;
}
2015-11-06 17:58:48 +03:00
// the counter-terrorist spawns at "info_player_start"
2016-06-02 01:08:22 +03:00
else if ( g_pGameRules - > IsDeathmatch ( ) & & m_iTeam = = CT )
2015-09-30 03:49:22 +03:00
{
CTSpawn :
2015-11-06 17:58:48 +03:00
pSpot = g_pLastCTSpawn ;
2015-09-30 03:49:22 +03:00
2016-06-02 01:08:22 +03:00
if ( SelectSpawnSpot ( " info_player_start " , pSpot ) )
2015-09-30 03:49:22 +03:00
{
goto ReturnSpot ;
}
}
// The terrorist spawn points
2016-06-02 01:08:22 +03:00
else if ( g_pGameRules - > IsDeathmatch ( ) & & m_iTeam = = TERRORIST )
2015-09-30 03:49:22 +03:00
{
2015-11-06 17:58:48 +03:00
pSpot = g_pLastTerroristSpawn ;
2015-09-30 03:49:22 +03:00
2016-06-02 01:08:22 +03:00
if ( SelectSpawnSpot ( " info_player_deathmatch " , pSpot ) )
2015-09-30 03:49:22 +03:00
{
goto ReturnSpot ;
}
}
// If startspot is set, (re)spawn there.
if ( FStringNull ( gpGlobals - > startspot ) | | ! Q_strlen ( STRING ( gpGlobals - > startspot ) ) )
{
2017-10-13 03:04:37 +03:00
pSpot = UTIL_FindEntityByClassname ( nullptr , " info_player_deathmatch " ) ;
2015-09-30 03:49:22 +03:00
if ( ! FNullEnt ( pSpot ) )
goto ReturnSpot ;
}
else
{
2017-10-13 03:04:37 +03:00
pSpot = UTIL_FindEntityByTargetname ( nullptr , STRING ( gpGlobals - > startspot ) ) ;
2015-09-30 03:49:22 +03:00
if ( ! FNullEnt ( pSpot ) )
goto ReturnSpot ;
}
ReturnSpot :
if ( FNullEnt ( pSpot ) )
{
2016-02-29 19:00:29 +03:00
ALERT ( at_error , " PutClientInServer: no info_player_start on level \n " ) ;
2015-09-30 03:49:22 +03:00
return INDEXENT ( 0 ) ;
}
2016-06-02 01:08:22 +03:00
if ( m_iTeam = = TERRORIST )
2015-09-30 03:49:22 +03:00
g_pLastTerroristSpawn = pSpot ;
else
g_pLastCTSpawn = pSpot ;
return pSpot - > edict ( ) ;
}
2016-06-02 01:08:22 +03:00
void CBasePlayer : : SetScoreAttrib ( CBasePlayer * dest )
2015-09-30 03:49:22 +03:00
{
2021-10-28 14:30:21 +03:00
int state = SCORE_STATUS_NONE ;
2016-06-02 01:08:22 +03:00
if ( pev - > deadflag ! = DEAD_NO )
2015-09-30 03:49:22 +03:00
state | = SCORE_STATUS_DEAD ;
2016-06-02 01:08:22 +03:00
if ( m_bHasC4 )
2015-09-30 03:49:22 +03:00
state | = SCORE_STATUS_BOMB ;
2016-06-02 01:08:22 +03:00
if ( m_bIsVIP )
2015-09-30 03:49:22 +03:00
state | = SCORE_STATUS_VIP ;
2019-06-04 17:41:30 +03:00
# ifdef BUILD_LATEST
2020-01-15 18:10:32 +03:00
# ifdef REGAMEDLL_FIXES
if ( scoreboard_showdefkit . value )
# endif
{
if ( m_bHasDefuser )
state | = SCORE_STATUS_DEFKIT ;
}
# endif
# ifdef REGAMEDLL_FIXES
// TODO: Remove these fixes when they are implemented on the client side
if ( state & ( SCORE_STATUS_BOMB | SCORE_STATUS_DEFKIT ) & & GetForceCamera ( dest ) ! = CAMERA_MODE_SPEC_ANYONE )
{
if ( CSGameRules ( ) - > PlayerRelationship ( this , dest ) ! = GR_TEAMMATE )
state & = ~ ( SCORE_STATUS_BOMB | SCORE_STATUS_DEFKIT ) ;
}
2019-06-04 17:41:30 +03:00
# endif
2015-09-30 03:49:22 +03:00
if ( gmsgScoreAttrib )
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgScoreAttrib , nullptr , dest - > pev ) ;
2016-06-02 01:08:22 +03:00
WRITE_BYTE ( entindex ( ) ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( state ) ;
MESSAGE_END ( ) ;
}
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , Spawn )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( Spawn ) ( )
2015-09-30 03:49:22 +03:00
{
int i ;
2016-09-25 21:05:55 +03:00
# ifdef REGAMEDLL_FIXES
// Do not allow to do spawn, if player chooses a team or appearance.
if ( m_bJustConnected & & m_iJoiningState = = PICKINGTEAM ) {
return ;
}
# endif
2015-09-30 03:49:22 +03:00
m_iGaitsequence = 0 ;
m_flGaitframe = 0 ;
m_flGaityaw = 0 ;
m_flGaitMovement = 0 ;
m_prevgaitorigin = Vector ( 0 , 0 , 0 ) ;
m_progressStart = 0 ;
m_progressEnd = 0 ;
MAKE_STRING_CLASS ( " player " , pev ) ;
pev - > health = 100 ;
if ( ! m_bNotKilled )
{
pev - > armorvalue = 0 ;
2016-05-17 21:01:46 +03:00
m_iKevlar = ARMOR_NONE ;
2015-09-30 03:49:22 +03:00
}
pev - > maxspeed = 1000 ;
pev - > takedamage = DAMAGE_AIM ;
pev - > solid = SOLID_SLIDEBOX ;
pev - > movetype = MOVETYPE_WALK ;
pev - > max_health = pev - > health ;
pev - > flags & = FL_PROXY ;
pev - > flags | = FL_CLIENT ;
2016-12-09 15:39:16 +03:00
pev - > air_finished = gpGlobals - > time + AIRTIME ;
2015-09-30 03:49:22 +03:00
pev - > dmg = 2 ;
pev - > effects = 0 ;
pev - > deadflag = DEAD_NO ;
pev - > dmg_take = 0 ;
pev - > dmg_save = 0 ;
2016-09-13 12:20:37 +03:00
# ifdef REGAMEDLL_FIXES
pev - > watertype = CONTENTS_EMPTY ;
pev - > waterlevel = 0 ;
2019-10-09 13:18:42 +03:00
pev - > basevelocity = g_vecZero ; // pushed by trigger_push
2016-09-13 12:20:37 +03:00
# endif
2015-09-30 03:49:22 +03:00
m_bitsHUDDamage = - 1 ;
m_bitsDamageType = 0 ;
m_afPhysicsFlags = 0 ;
m_fLongJump = FALSE ;
m_iClientFOV = 0 ;
2017-10-13 03:04:37 +03:00
m_pentCurBombTarget = nullptr ;
2015-09-30 03:49:22 +03:00
if ( m_bOwnsShield )
2019-09-22 17:39:06 +03:00
pev - > gamestate = HITGROUP_SHIELD_ENABLED ;
2015-09-30 03:49:22 +03:00
else
2019-09-22 17:39:06 +03:00
pev - > gamestate = HITGROUP_SHIELD_DISABLED ;
2015-09-30 03:49:22 +03:00
ResetStamina ( ) ;
pev - > friction = 1 ;
pev - > gravity = 1 ;
SET_PHYSICS_KEY_VALUE ( edict ( ) , " slj " , " 0 " ) ;
SET_PHYSICS_KEY_VALUE ( edict ( ) , " hl " , " 1 " ) ;
m_hintMessageQueue . Reset ( ) ;
m_flVelocityModifier = 1 ;
m_iLastZoom = DEFAULT_FOV ;
m_flLastTalk = 0 ;
m_flIdleCheckTime = 0 ;
m_flRadioTime = 0 ;
2019-07-30 15:30:34 +03:00
# ifdef REGAMEDLL_ADD
m_iRadioMessages = int ( radio_maxinround . value ) ;
# else
2015-09-30 03:49:22 +03:00
m_iRadioMessages = 60 ;
2019-07-30 15:30:34 +03:00
# endif
2015-09-30 03:49:22 +03:00
m_bHasC4 = false ;
m_bKilledByBomb = false ;
m_bKilledByGrenade = false ;
m_flDisplayHistory & = ~ DHM_ROUND_CLEAR ;
m_tmHandleSignals = 0 ;
m_fCamSwitch = 0 ;
m_iChaseTarget = 1 ;
m_bEscaped = false ;
m_tmNextRadarUpdate = gpGlobals - > time ;
2019-06-04 17:41:30 +03:00
# ifdef BUILD_LATEST
m_tmNextAccountHealthUpdate = gpGlobals - > time ;
# endif
2015-09-30 03:49:22 +03:00
m_vLastOrigin = Vector ( 0 , 0 , 0 ) ;
m_iCurrentKickVote = 0 ;
m_flNextVoteTime = 0 ;
m_bJustKilledTeammate = false ;
SET_VIEW ( ENT ( pev ) , ENT ( pev ) ) ;
2017-10-13 03:04:37 +03:00
m_hObserverTarget = nullptr ;
2015-11-06 17:58:48 +03:00
pev - > iuser1 =
pev - > iuser2 =
pev - > iuser3 = 0 ;
2015-09-30 03:49:22 +03:00
m_flLastFired = - 15 ;
m_bHeadshotKilled = false ;
m_bReceivesNoMoneyNextRound = false ;
m_bShieldDrawn = false ;
m_blindUntilTime = 0 ;
m_blindStartTime = 0 ;
m_blindHoldTime = 0 ;
m_blindFadeTime = 0 ;
m_blindAlpha = 0 ;
m_canSwitchObserverModes = true ;
m_lastLocation [ 0 ] = ' \0 ' ;
m_bitsDamageType & = ~ ( DMG_DROWN | DMG_DROWNRECOVER ) ;
2017-10-19 20:12:02 +03:00
m_rgbTimeBasedDamage [ ITBD_DROWN_RECOVER ] = 0 ;
2015-09-30 03:49:22 +03:00
m_idrowndmg = 0 ;
m_idrownrestored = 0 ;
2019-09-23 00:31:23 +03:00
# ifdef REGAMEDLL_ADD
CSPlayer ( ) - > OnSpawn ( ) ;
# endif
2015-09-30 03:49:22 +03:00
if ( m_iObserverC4State )
{
m_iObserverC4State = 0 ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( STATUSICON_HIDE ) ;
WRITE_STRING ( " c4 " ) ;
MESSAGE_END ( ) ;
}
if ( m_bObserverHasDefuser )
{
m_bObserverHasDefuser = false ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( STATUSICON_HIDE ) ;
WRITE_STRING ( " defuser " ) ;
MESSAGE_END ( ) ;
}
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , SVC_ROOMTYPE , nullptr , pev ) ;
2016-02-23 02:13:52 +03:00
WRITE_SHORT ( int ( CVAR_GET_FLOAT ( " room_type " ) ) ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
if ( g_pGameRules - > IsFreezePeriod ( ) )
m_bCanShoot = false ;
else
m_bCanShoot = true ;
m_iNumSpawns + + ;
InitStatusBar ( ) ;
2017-10-13 03:04:37 +03:00
for ( i = 0 ; i < MAX_RECENT_PATH ; i + + )
m_vRecentPath [ i ] = Vector ( 0 , 0 , 0 ) ;
2015-09-30 03:49:22 +03:00
2016-12-06 22:21:52 +03:00
if ( m_pActiveItem & & ! pev - > viewmodel )
2015-09-30 03:49:22 +03:00
{
switch ( m_pActiveItem - > m_iId )
{
case WEAPON_AWP :
pev - > viewmodel = MAKE_STRING ( " models/v_awp.mdl " ) ;
break ;
case WEAPON_G3SG1 :
pev - > viewmodel = MAKE_STRING ( " models/v_g3sg1.mdl " ) ;
break ;
case WEAPON_SCOUT :
pev - > viewmodel = MAKE_STRING ( " models/v_scout.mdl " ) ;
break ;
case WEAPON_SG550 :
pev - > viewmodel = MAKE_STRING ( " models/v_sg550.mdl " ) ;
break ;
}
}
m_iFOV = DEFAULT_FOV ;
m_flNextDecalTime = 0 ;
m_flTimeStepSound = 0 ;
m_iStepLeft = 0 ;
m_flFieldOfView = 0.5 ;
m_bloodColor = BLOOD_COLOR_RED ;
m_flNextAttack = 0 ;
m_flgeigerDelay = gpGlobals - > time + 2 ;
StartSneaking ( ) ;
m_iFlashBattery = 99 ;
m_flFlashLightTime = 1 ;
2016-06-03 18:32:33 +03:00
# ifdef REGAMEDLL_ADD
2016-06-08 00:41:07 +03:00
ReloadWeapons ( ) ;
2016-06-03 18:32:33 +03:00
# endif
2023-09-05 06:52:44 +03:00
pev - > body = m_bHasDefuser ? 1 : 0 ;
2015-09-30 03:49:22 +03:00
if ( m_bMissionBriefing )
{
RemoveLevelText ( ) ;
m_bMissionBriefing = false ;
}
m_flFallVelocity = 0 ;
if ( ! g_skipCareerInitialSpawn )
{
g_pGameRules - > GetPlayerSpawnSpot ( this ) ;
}
if ( ! pev - > modelindex )
{
2015-11-06 17:58:48 +03:00
// get rid of the dependency on m_modelIndexPlayer.
2015-09-30 03:49:22 +03:00
SET_MODEL ( ENT ( pev ) , " models/player.mdl " ) ;
m_modelIndexPlayer = pev - > modelindex ;
}
pev - > sequence = LookupActivity ( ACT_IDLE ) ;
if ( pev - > flags & FL_DUCKING )
UTIL_SetSize ( pev , VEC_DUCK_HULL_MIN , VEC_DUCK_HULL_MAX ) ;
else
UTIL_SetSize ( pev , VEC_HULL_MIN , VEC_HULL_MAX ) ;
2015-11-06 17:58:48 +03:00
// Override what CBasePlayer set for the view offset.
2015-09-30 03:49:22 +03:00
pev - > view_ofs = VEC_VIEW ;
Precache ( ) ;
m_HackedGunPos = Vector ( 0 , 32 , 0 ) ;
if ( m_iPlayerSound = = SOUNDLIST_EMPTY )
{
ALERT ( at_console , " Couldn't alloc player sound slot! \n " ) ;
}
2016-12-06 22:21:52 +03:00
m_iHideHUD & = ~ ( HIDEHUD_WEAPONS | HIDEHUD_HEALTH | HIDEHUD_TIMER | HIDEHUD_MONEY | HIDEHUD_CROSSHAIR ) ;
2015-09-30 03:49:22 +03:00
m_fNoPlayerSound = FALSE ;
2017-10-13 03:04:37 +03:00
m_pLastItem = nullptr ;
2015-09-30 03:49:22 +03:00
m_fWeapon = FALSE ;
2017-10-13 03:04:37 +03:00
m_pClientActiveItem = nullptr ;
2015-09-30 03:49:22 +03:00
m_iClientBattery = - 1 ;
m_fInitHUD = TRUE ;
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_FIXES
m_iClientHideHUD = - 1 ;
# endif
2015-09-30 03:49:22 +03:00
if ( ! m_bNotKilled )
{
2016-12-06 22:21:52 +03:00
# ifndef REGAMEDLL_FIXES
2015-09-30 03:49:22 +03:00
m_iClientHideHUD = - 1 ;
2016-12-06 22:21:52 +03:00
# endif
2015-09-30 03:49:22 +03:00
2017-10-13 03:04:37 +03:00
for ( i = 0 ; i < MAX_AMMO_SLOTS ; i + + )
2015-09-30 03:49:22 +03:00
m_rgAmmo [ i ] = 0 ;
m_bHasPrimary = false ;
m_bHasNightVision = false ;
2019-10-09 13:18:42 +03:00
# ifdef REGAMEDLL_FIXES
m_iHideHUD | = HIDEHUD_WEAPONS ;
# endif
2016-06-02 01:08:22 +03:00
SendItemStatus ( ) ;
2015-09-30 03:49:22 +03:00
}
else
{
2017-10-13 03:04:37 +03:00
for ( i = 0 ; i < MAX_AMMO_SLOTS ; i + + )
2015-09-30 03:49:22 +03:00
m_rgAmmoLast [ i ] = - 1 ;
}
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgNVGToggle , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
m_bNightVisionOn = false ;
2017-10-13 03:04:37 +03:00
for ( i = 1 ; i < = gpGlobals - > maxClients ; i + + )
2015-09-30 03:49:22 +03:00
{
2016-05-31 17:04:51 +03:00
CBasePlayer * pObserver = UTIL_PlayerByIndex ( i ) ;
2015-09-30 03:49:22 +03:00
if ( pObserver & & pObserver - > IsObservingPlayer ( this ) )
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgNVGToggle , nullptr , pObserver - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
pObserver - > m_bNightVisionOn = false ;
}
}
m_lastx = m_lasty = 0 ;
g_pGameRules - > PlayerSpawn ( this ) ;
m_bNotKilled = true ;
m_bIsDefusing = false ;
// Get rid of the progress bar...
SetProgressBarTime ( 0 ) ;
ResetMaxSpeed ( ) ;
UTIL_SetOrigin ( pev , pev - > origin ) ;
if ( m_bIsVIP )
{
2016-05-17 21:01:46 +03:00
m_iKevlar = ARMOR_VESTHELM ;
2015-09-30 03:49:22 +03:00
pev - > armorvalue = 200 ;
HintMessage ( " #Hint_you_are_the_vip " , TRUE , TRUE ) ;
}
SetScoreboardAttributes ( ) ;
MESSAGE_BEGIN ( MSG_ALL , gmsgTeamInfo ) ;
2015-12-18 19:32:50 +03:00
WRITE_BYTE ( entindex ( ) ) ;
2016-05-04 00:53:03 +03:00
WRITE_STRING ( GetTeamName ( m_iTeam ) ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
UpdateLocation ( true ) ;
MESSAGE_BEGIN ( MSG_ALL , gmsgScoreInfo ) ;
WRITE_BYTE ( ENTINDEX ( edict ( ) ) ) ;
2016-02-23 02:13:52 +03:00
WRITE_SHORT ( int ( pev - > frags ) ) ;
2015-09-30 03:49:22 +03:00
WRITE_SHORT ( m_iDeaths ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( m_iTeam ) ;
MESSAGE_END ( ) ;
if ( m_bHasChangedName )
{
char * infobuffer = GET_INFO_BUFFER ( edict ( ) ) ;
if ( ! FStrEq ( m_szNewName , GET_KEY_VALUE ( infobuffer , " name " ) ) )
{
SET_CLIENT_KEY_VALUE ( entindex ( ) , infobuffer , " name " , m_szNewName ) ;
}
m_bHasChangedName = false ;
m_szNewName [ 0 ] = ' \0 ' ;
}
UTIL_ScreenFade ( this , Vector ( 0 , 0 , 0 ) , 0.001 ) ;
SyncRoundTimer ( ) ;
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-09-30 03:49:22 +03:00
{
TheBots - > OnEvent ( EVENT_PLAYER_SPAWNED , this ) ;
}
m_allowAutoFollowTime = false ;
2017-10-13 03:04:37 +03:00
for ( i = 0 ; i < COMMANDS_TO_TRACK ; i + + )
2015-09-30 03:49:22 +03:00
m_flLastCommandTime [ i ] = - 1 ;
2016-06-02 01:08:22 +03:00
# ifdef REGAMEDLL_FIXES
2016-06-03 18:32:33 +03:00
// everything that comes after this, this spawn of the player a the game.
if ( m_bJustConnected )
return ;
2016-06-02 01:08:22 +03:00
2016-06-03 18:32:33 +03:00
FireTargets ( " game_playerspawn " , this , this , USE_TOGGLE , 0 ) ;
# endif
2015-09-30 03:49:22 +03:00
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , Precache )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( Precache ) ( )
2015-09-30 03:49:22 +03:00
{
// SOUNDS / MODELS ARE PRECACHED in ClientPrecache() (game specific)
// because they need to precache before any clients have connected
// init geiger counter vars during spawn and each time
// we cross a level transition
m_flgeigerRange = 1000 ;
m_igeigerRangePrev = 1000 ;
m_bitsDamageType = 0 ;
m_bitsHUDDamage = - 1 ;
m_iClientBattery = - 1 ;
m_iTrain = TRAIN_NEW ;
// Make sure any necessary user messages have been registered
LinkUserMessages ( ) ;
// won't update for 1/2 a second
m_iUpdateTime = 5 ;
if ( gInitHUD )
m_fInitHUD = TRUE ;
}
2017-07-01 23:40:10 +03:00
int CBasePlayer : : Save ( CSave & save )
2015-09-30 03:49:22 +03:00
{
if ( ! CBaseMonster : : Save ( save ) )
return 0 ;
2017-10-19 20:12:02 +03:00
return save . WriteFields ( " PLAYER " , this , m_playerSaveData , ARRAYSIZE ( m_playerSaveData ) ) ;
2015-09-30 03:49:22 +03:00
}
void CBasePlayer : : SetScoreboardAttributes ( CBasePlayer * destination )
{
2016-12-06 22:21:52 +03:00
if ( destination )
2015-09-30 03:49:22 +03:00
{
2016-06-02 01:08:22 +03:00
SetScoreAttrib ( destination ) ;
2015-09-30 03:49:22 +03:00
return ;
}
2017-10-13 03:04:37 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
2015-09-30 03:49:22 +03:00
2017-11-22 20:27:55 +03:00
if ( pPlayer & & ! FNullEnt ( pPlayer - > edict ( ) ) )
SetScoreboardAttributes ( pPlayer ) ;
2015-09-30 03:49:22 +03:00
}
}
2015-11-06 17:58:48 +03:00
// Marks everything as new so the player will resend this to the hud.
2016-02-04 03:18:26 +03:00
NOXREF void CBasePlayer : : RenewItems ( )
2015-09-30 03:49:22 +03:00
{
;
}
2017-07-01 23:40:10 +03:00
int CBasePlayer : : Restore ( CRestore & restore )
2015-09-30 03:49:22 +03:00
{
if ( ! CBaseMonster : : Restore ( restore ) )
return 0 ;
2017-10-19 20:12:02 +03:00
int status = restore . ReadFields ( " PLAYER " , this , m_playerSaveData , ARRAYSIZE ( m_playerSaveData ) ) ;
2015-09-30 03:49:22 +03:00
SAVERESTOREDATA * pSaveData = ( SAVERESTOREDATA * ) gpGlobals - > pSaveData ;
2015-11-06 17:58:48 +03:00
// landmark isn't present.
2015-09-30 03:49:22 +03:00
if ( ! pSaveData - > fUseLandmark )
{
ALERT ( at_console , " No Landmark:%s \n " , pSaveData - > szLandmarkName ) ;
2015-11-06 17:58:48 +03:00
// default to normal spawn
2016-06-02 01:08:22 +03:00
edict_t * pentSpawnSpot = EntSelectSpawnPoint ( ) ;
2015-09-30 03:49:22 +03:00
2016-02-23 02:13:52 +03:00
pev - > origin = pentSpawnSpot - > v . origin + Vector ( 0 , 0 , 1 ) ;
pev - > angles = pentSpawnSpot - > v . angles ;
2015-09-30 03:49:22 +03:00
}
2015-11-06 17:58:48 +03:00
// Clear out roll
2015-09-30 03:49:22 +03:00
pev - > v_angle . z = 0 ;
pev - > angles = pev - > v_angle ;
2015-11-06 17:58:48 +03:00
// turn this way immediately
2015-09-30 03:49:22 +03:00
pev - > fixangle = 1 ;
2015-11-06 17:58:48 +03:00
// Copied from spawn() for now
2015-09-30 03:49:22 +03:00
m_bloodColor = BLOOD_COLOR_RED ;
m_modelIndexPlayer = pev - > modelindex ;
if ( pev - > flags & FL_DUCKING )
UTIL_SetSize ( pev , VEC_DUCK_HULL_MIN , VEC_DUCK_HULL_MAX ) ;
else
UTIL_SetSize ( pev , VEC_HULL_MIN , VEC_HULL_MAX ) ;
2019-06-04 17:41:30 +03:00
# ifdef BUILD_LATEST_FIXES
TabulateAmmo ( ) ;
# endif
2015-09-30 03:49:22 +03:00
m_flDisplayHistory & = ~ DHM_CONNECT_CLEAR ;
SetScoreboardAttributes ( ) ;
return status ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : Reset ( )
2015-09-30 03:49:22 +03:00
{
pev - > frags = 0 ;
m_iDeaths = 0 ;
2016-10-07 15:19:51 +03:00
# ifndef REGAMEDLL_ADD
2015-09-30 03:49:22 +03:00
m_iAccount = 0 ;
2016-10-07 15:19:51 +03:00
# endif
2015-09-30 03:49:22 +03:00
2016-06-02 01:08:22 +03:00
# ifndef REGAMEDLL_FIXES
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgMoney , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_LONG ( m_iAccount ) ;
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
2016-06-02 01:08:22 +03:00
# endif
2015-09-30 03:49:22 +03:00
m_bNotKilled = false ;
2019-10-09 13:18:42 +03:00
# ifdef REGAMEDLL_FIXES
// RemoveShield() included
RemoveAllItems ( TRUE ) ;
# else
2015-09-30 03:49:22 +03:00
RemoveShield ( ) ;
2019-10-09 13:18:42 +03:00
# endif
2015-09-30 03:49:22 +03:00
CheckStartMoney ( ) ;
2016-05-25 16:56:48 +03:00
AddAccount ( startmoney . value , RT_PLAYER_RESET ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_BEGIN ( MSG_ALL , gmsgScoreInfo ) ;
WRITE_BYTE ( ENTINDEX ( edict ( ) ) ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( m_iTeam ) ;
MESSAGE_END ( ) ;
2019-09-22 17:49:52 +03:00
# ifdef REGAMEDLL_ADD
if ( CSPlayer ( ) - > GetProtectionState ( ) = = CCSPlayer : : ProtectionSt_Active ) {
RemoveSpawnProtection ( ) ;
}
2023-09-28 12:18:15 +03:00
CSPlayer ( ) - > ResetAllStats ( ) ;
2019-09-22 17:49:52 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
NOXREF void CBasePlayer : : SelectNextItem ( int iItem )
{
2017-10-12 17:50:56 +03:00
CBasePlayerItem * pItem = m_rgpPlayerItems [ iItem ] ;
2015-09-30 03:49:22 +03:00
if ( ! pItem )
{
return ;
}
2019-08-13 22:59:17 +03:00
# ifdef REGAMEDLL_FIXES
if ( m_pActiveItem & & ! m_pActiveItem - > CanHolster ( ) )
return ;
# endif
2015-09-30 03:49:22 +03:00
if ( pItem = = m_pActiveItem )
{
pItem = m_pActiveItem - > m_pNext ;
if ( ! pItem )
{
return ;
}
CBasePlayerItem * pLast = pItem ;
2016-12-06 22:21:52 +03:00
while ( pLast - > m_pNext )
2015-09-30 03:49:22 +03:00
pLast = pLast - > m_pNext ;
pLast - > m_pNext = m_pActiveItem ;
2017-10-13 03:04:37 +03:00
m_pActiveItem - > m_pNext = nullptr ;
2017-10-12 17:50:56 +03:00
m_rgpPlayerItems [ iItem ] = pItem ;
2015-09-30 03:49:22 +03:00
}
ResetAutoaim ( ) ;
2016-12-06 22:21:52 +03:00
if ( m_pActiveItem )
2015-09-30 03:49:22 +03:00
{
m_pActiveItem - > Holster ( ) ;
}
if ( HasShield ( ) )
{
CBasePlayerWeapon * pWeapon = ( CBasePlayerWeapon * ) m_pActiveItem ;
pWeapon - > m_iWeaponState & = ~ WPNSTATE_SHIELD_DRAWN ;
m_bShieldDrawn = false ;
}
m_pLastItem = m_pActiveItem ;
m_pActiveItem = pItem ;
2017-10-12 17:50:56 +03:00
UpdateShieldCrosshair ( true ) ;
2015-09-30 03:49:22 +03:00
2017-10-12 17:50:56 +03:00
m_pActiveItem - > Deploy ( ) ;
m_pActiveItem - > UpdateItemInfo ( ) ;
2015-09-30 03:49:22 +03:00
2017-10-12 17:50:56 +03:00
ResetMaxSpeed ( ) ;
2015-09-30 03:49:22 +03:00
}
void CBasePlayer : : SelectItem ( const char * pstr )
{
if ( ! pstr )
{
return ;
}
2019-08-13 22:59:17 +03:00
# ifdef REGAMEDLL_FIXES
if ( m_pActiveItem & & ! m_pActiveItem - > CanHolster ( ) )
return ;
# endif
2016-12-06 22:21:52 +03:00
auto pItem = GetItemByName ( pstr ) ;
2015-09-30 03:49:22 +03:00
if ( ! pItem | | pItem = = m_pActiveItem )
return ;
2019-10-27 17:17:12 +03:00
# ifdef REGAMEDLL_FIXES
if ( ! pItem - > CanDeploy ( ) )
return ;
# endif
2015-09-30 03:49:22 +03:00
ResetAutoaim ( ) ;
// FIX, this needs to queue them up and delay
2016-12-06 22:21:52 +03:00
if ( m_pActiveItem )
2015-09-30 03:49:22 +03:00
{
m_pActiveItem - > Holster ( ) ;
}
m_pLastItem = m_pActiveItem ;
m_pActiveItem = pItem ;
2017-10-12 17:50:56 +03:00
CBasePlayerWeapon * pWeapon = ( CBasePlayerWeapon * ) m_pActiveItem ;
pWeapon - > m_iWeaponState & = ~ WPNSTATE_SHIELD_DRAWN ;
2015-09-30 03:49:22 +03:00
2017-10-12 17:50:56 +03:00
m_bShieldDrawn = false ;
UpdateShieldCrosshair ( true ) ;
2015-09-30 03:49:22 +03:00
2017-10-12 17:50:56 +03:00
m_pActiveItem - > Deploy ( ) ;
m_pActiveItem - > UpdateItemInfo ( ) ;
2015-09-30 03:49:22 +03:00
2017-10-12 17:50:56 +03:00
ResetMaxSpeed ( ) ;
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : SelectLastItem ( )
2015-09-30 03:49:22 +03:00
{
if ( m_pActiveItem & & ! m_pActiveItem - > CanHolster ( ) )
return ;
if ( ! m_pLastItem | | m_pLastItem = = m_pActiveItem )
{
2017-10-13 03:04:37 +03:00
for ( int i = PRIMARY_WEAPON_SLOT ; i < = KNIFE_SLOT ; i + + )
2015-09-30 03:49:22 +03:00
{
CBasePlayerItem * pItem = m_rgpPlayerItems [ i ] ;
2016-07-14 17:12:17 +03:00
if ( pItem & & pItem ! = m_pActiveItem )
2015-09-30 03:49:22 +03:00
{
m_pLastItem = pItem ;
break ;
}
}
}
if ( ! m_pLastItem | | m_pLastItem = = m_pActiveItem )
return ;
2019-10-27 17:17:12 +03:00
# ifdef REGAMEDLL_FIXES
if ( ! m_pLastItem - > CanDeploy ( ) )
return ;
# endif
2015-09-30 03:49:22 +03:00
ResetAutoaim ( ) ;
if ( m_pActiveItem )
2017-10-12 17:50:56 +03:00
{
2015-09-30 03:49:22 +03:00
m_pActiveItem - > Holster ( ) ;
2017-10-12 17:50:56 +03:00
}
2015-09-30 03:49:22 +03:00
if ( HasShield ( ) )
{
2016-07-14 17:12:17 +03:00
CBasePlayerWeapon * pWeapon = static_cast < CBasePlayerWeapon * > ( m_pActiveItem ) ;
if ( pWeapon )
2015-09-30 03:49:22 +03:00
pWeapon - > m_iWeaponState & = ~ WPNSTATE_SHIELD_DRAWN ;
m_bShieldDrawn = false ;
}
2016-07-14 17:12:17 +03:00
SWAP ( m_pActiveItem , m_pLastItem ) ;
2015-09-30 03:49:22 +03:00
m_pActiveItem - > Deploy ( ) ;
m_pActiveItem - > UpdateItemInfo ( ) ;
UpdateShieldCrosshair ( true ) ;
ResetMaxSpeed ( ) ;
}
// HasWeapons - do I have any weapons at all?
2016-07-14 17:12:17 +03:00
bool CBasePlayer : : HasWeapons ( )
2015-09-30 03:49:22 +03:00
{
2016-07-14 17:12:17 +03:00
for ( auto item : m_rgpPlayerItems )
2015-09-30 03:49:22 +03:00
{
2016-07-14 17:12:17 +03:00
if ( item )
return true ;
2015-09-30 03:49:22 +03:00
}
2015-11-06 17:58:48 +03:00
2016-07-14 17:12:17 +03:00
return false ;
2015-09-30 03:49:22 +03:00
}
NOXREF void CBasePlayer : : SelectPrevItem ( int iItem )
{
;
}
2017-07-01 23:40:10 +03:00
const char * CBasePlayer : : TeamID ( )
2015-09-30 03:49:22 +03:00
{
// Not fully connected yet
2016-07-14 17:12:17 +03:00
if ( ! pev )
2015-09-30 03:49:22 +03:00
return " " ;
// return their team name
return m_szTeamName ;
}
void CSprayCan : : Spawn ( entvars_t * pevOwner )
{
2017-06-29 13:21:56 +03:00
# ifdef REGAMEDLL_FIXES
pev - > origin = pevOwner - > origin + pevOwner - > view_ofs ;
# else
2015-09-30 03:49:22 +03:00
pev - > origin = pevOwner - > origin + Vector ( 0 , 0 , 32 ) ;
2017-06-29 13:21:56 +03:00
# endif
2017-10-12 17:50:56 +03:00
2015-09-30 03:49:22 +03:00
pev - > angles = pevOwner - > v_angle ;
pev - > owner = ENT ( pevOwner ) ;
pev - > frame = 0 ;
2016-03-17 20:44:52 +03:00
pev - > nextthink = gpGlobals - > time + 0.1f ;
2015-09-30 03:49:22 +03:00
EMIT_SOUND ( ENT ( pev ) , CHAN_VOICE , " player/sprayer.wav " , VOL_NORM , ATTN_NORM ) ;
}
2017-07-01 23:40:10 +03:00
void CSprayCan : : Think ( )
2015-09-30 03:49:22 +03:00
{
2018-05-31 10:53:34 +03:00
CBasePlayer * pPlayer = GET_PRIVATE < CBasePlayer > ( pev - > owner ) ;
2015-09-30 03:49:22 +03:00
2018-05-31 10:53:34 +03:00
int nFrames = - 1 ;
2015-09-30 03:49:22 +03:00
if ( pPlayer )
2018-05-31 10:53:34 +03:00
{
2015-09-30 03:49:22 +03:00
nFrames = pPlayer - > GetCustomDecalFrames ( ) ;
2018-05-31 10:53:34 +03:00
}
2015-09-30 03:49:22 +03:00
2018-05-31 10:53:34 +03:00
TraceResult tr ;
int playernum = ENTINDEX ( pev - > owner ) ;
2015-09-30 03:49:22 +03:00
UTIL_MakeVectors ( pev - > angles ) ;
UTIL_TraceLine ( pev - > origin , pev - > origin + gpGlobals - > v_forward * 128 , ignore_monsters , pev - > owner , & tr ) ;
// No customization present.
if ( nFrames = = - 1 )
{
UTIL_DecalTrace ( & tr , DECAL_LAMBDA6 ) ;
UTIL_Remove ( this ) ;
}
else
{
UTIL_PlayerDecalTrace ( & tr , playernum , pev - > frame , TRUE ) ;
// Just painted last custom frame.
if ( pev - > frame + + > = ( nFrames - 1 ) )
UTIL_Remove ( this ) ;
}
2016-03-17 20:44:52 +03:00
pev - > nextthink = gpGlobals - > time + 0.1f ;
2015-09-30 03:49:22 +03:00
}
void CBloodSplat : : Spawn ( entvars_t * pevOwner )
{
pev - > origin = pevOwner - > origin + Vector ( 0 , 0 , 32 ) ;
pev - > angles = pevOwner - > v_angle ;
pev - > owner = ENT ( pevOwner ) ;
SetThink ( & CBloodSplat : : Spray ) ;
2016-03-17 20:44:52 +03:00
pev - > nextthink = gpGlobals - > time + 0.1f ;
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
void CBloodSplat : : Spray ( )
2015-09-30 03:49:22 +03:00
{
TraceResult tr ;
if ( g_Language ! = LANGUAGE_GERMAN )
{
UTIL_MakeVectors ( pev - > angles ) ;
UTIL_TraceLine ( pev - > origin , pev - > origin + gpGlobals - > v_forward * 128 , ignore_monsters , pev - > owner , & tr ) ;
UTIL_BloodDecalTrace ( & tr , BLOOD_COLOR_RED ) ;
}
SetThink ( & CBloodSplat : : SUB_Remove ) ;
2016-03-17 20:44:52 +03:00
pev - > nextthink = gpGlobals - > time + 0.1f ;
2015-09-30 03:49:22 +03:00
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CHAIN ( CBaseEntity * , CBasePlayer , GiveNamedItem , ( const char * pszName ) , pszName )
2016-04-07 23:20:45 +03:00
2016-12-06 22:21:52 +03:00
CBaseEntity * EXT_FUNC CBasePlayer : : __API_HOOK ( GiveNamedItem ) ( const char * pszName )
2015-09-30 03:49:22 +03:00
{
string_t istr = MAKE_STRING ( pszName ) ;
edict_t * pent = CREATE_NAMED_ENTITY ( istr ) ;
if ( FNullEnt ( pent ) )
{
ALERT ( at_console , " NULL Ent in GiveNamedItem! \n " ) ;
2016-12-06 22:21:52 +03:00
return nullptr ;
2015-09-30 03:49:22 +03:00
}
2016-02-23 02:13:52 +03:00
pent - > v . origin = pev - > origin ;
2015-09-30 03:49:22 +03:00
pent - > v . spawnflags | = SF_NORESPAWN ;
2016-05-17 21:01:46 +03:00
DispatchSpawn ( pent ) ;
DispatchTouch ( pent , ENT ( pev ) ) ;
2016-12-06 22:21:52 +03:00
2018-05-31 10:53:34 +03:00
return GET_PRIVATE < CBaseEntity > ( pent ) ;
2016-05-17 21:01:46 +03:00
}
// external function for 3rd-party
2016-12-06 22:21:52 +03:00
CBaseEntity * CBasePlayer : : GiveNamedItemEx ( const char * pszName )
2016-05-17 21:01:46 +03:00
{
string_t istr = ALLOC_STRING ( pszName ) ;
edict_t * pent = CREATE_NAMED_ENTITY ( istr ) ;
if ( FNullEnt ( pent ) )
{
2017-10-12 22:54:10 +03:00
ALERT ( at_console , " NULL Ent in GiveNamedItemEx classname `%s`! \n " , pszName ) ;
2016-12-06 22:21:52 +03:00
return nullptr ;
2016-05-17 21:01:46 +03:00
}
pent - > v . origin = pev - > origin ;
pent - > v . spawnflags | = SF_NORESPAWN ;
2015-09-30 03:49:22 +03:00
DispatchSpawn ( pent ) ;
DispatchTouch ( pent , ENT ( pev ) ) ;
2016-05-16 17:07:27 +03:00
2018-05-31 10:53:34 +03:00
CBaseEntity * pEntity = GET_PRIVATE < CBaseEntity > ( pent ) ;
2017-10-12 17:50:56 +03:00
2016-05-16 17:07:27 +03:00
# ifdef REGAMEDLL_FIXES
// not allow the item to fall to the ground.
2016-12-06 22:21:52 +03:00
if ( FNullEnt ( pent - > v . owner ) | | pent - > v . owner ! = edict ( ) )
2016-05-16 17:07:27 +03:00
{
pent - > v . flags | = FL_KILLME ;
2017-10-12 17:50:56 +03:00
UTIL_Remove ( pEntity ) ;
2016-12-06 22:21:52 +03:00
return nullptr ;
2016-05-16 17:07:27 +03:00
}
# endif
2016-12-06 22:21:52 +03:00
2017-10-12 17:50:56 +03:00
return pEntity ;
2015-09-30 03:49:22 +03:00
}
2024-02-04 22:21:49 +03:00
// Creates a copy of the specified entity (pEntitySource) and gives it to the player
// The cloned entity inherits base properties (entvars) of the original entity
// Returns Pointer to the cloned entity, or NULL if the entity cannot be created
CBaseEntity * CBasePlayer : : GiveCopyItem ( CBaseEntity * pEntitySource )
{
edict_t * pEdict = CREATE_NAMED_ENTITY ( pEntitySource - > pev - > classname ) ;
if ( FNullEnt ( pEdict ) )
{
ALERT ( at_console , " NULL Ent in GiveCloneItem classname `%s`! \n " , STRING ( pEntitySource - > pev - > classname ) ) ;
return nullptr ;
}
// copy entity properties
Q_memcpy ( & pEdict - > v , pEntitySource - > pev , sizeof ( pEdict - > v ) ) ;
pEdict - > v . pContainingEntity = pEdict ;
pEdict - > v . origin = pev - > origin ;
pEdict - > v . spawnflags | = SF_NORESPAWN ;
pEdict - > v . owner = NULL ; // will re-link owner after touching
pEdict - > v . chain = ENT ( pEntitySource - > pev ) ; // refer to source copy entity
DispatchSpawn ( pEdict ) ;
DispatchTouch ( pEdict , ENT ( pev ) ) ;
pEdict - > v . chain = NULL ;
CBaseEntity * pEntity = GET_PRIVATE < CBaseEntity > ( pEdict ) ;
// not allow the item to fall to the ground.
if ( FNullEnt ( pEdict - > v . owner ) | | pEdict - > v . owner ! = edict ( ) )
{
pEdict - > v . flags | = FL_KILLME ;
UTIL_Remove ( pEntity ) ;
return nullptr ;
}
return pEntity ;
}
2016-12-09 15:39:16 +03:00
CBaseEntity * FindEntityForward ( CBaseEntity * pEntity )
2015-09-30 03:49:22 +03:00
{
TraceResult tr ;
2016-12-09 15:39:16 +03:00
Vector vecStart ( pEntity - > pev - > origin + pEntity - > pev - > view_ofs ) ;
2015-09-30 03:49:22 +03:00
2016-12-09 15:39:16 +03:00
UTIL_MakeVectors ( pEntity - > pev - > v_angle ) ;
UTIL_TraceLine ( vecStart , vecStart + gpGlobals - > v_forward * 8192 , dont_ignore_monsters , pEntity - > edict ( ) , & tr ) ;
2015-09-30 03:49:22 +03:00
2015-11-06 17:58:48 +03:00
if ( tr . flFraction ! = 1.0f & & ! FNullEnt ( tr . pHit ) )
2015-09-30 03:49:22 +03:00
{
CBaseEntity * pHit = CBaseEntity : : Instance ( tr . pHit ) ;
return pHit ;
}
2015-11-06 17:58:48 +03:00
2017-10-13 03:04:37 +03:00
return nullptr ;
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
BOOL CBasePlayer : : FlashlightIsOn ( )
2015-09-30 03:49:22 +03:00
{
return pev - > effects & EF_DIMLIGHT ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : FlashlightTurnOn ( )
2015-09-30 03:49:22 +03:00
{
if ( ! g_pGameRules - > FAllowFlashlight ( ) )
return ;
if ( pev - > weapons & ( 1 < < WEAPON_SUIT ) )
{
2015-11-06 17:58:48 +03:00
EMIT_SOUND ( ENT ( pev ) , CHAN_ITEM , SOUND_FLASHLIGHT_ON , VOL_NORM , ATTN_NORM ) ;
2015-09-30 03:49:22 +03:00
pev - > effects | = EF_DIMLIGHT ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgFlashlight , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 1 ) ;
WRITE_BYTE ( m_iFlashBattery ) ;
MESSAGE_END ( ) ;
m_flFlashLightTime = gpGlobals - > time + FLASH_DRAIN_TIME ;
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : FlashlightTurnOff ( )
2015-09-30 03:49:22 +03:00
{
2015-11-06 17:58:48 +03:00
EMIT_SOUND ( ENT ( pev ) , CHAN_ITEM , SOUND_FLASHLIGHT_OFF , VOL_NORM , ATTN_NORM ) ;
2015-09-30 03:49:22 +03:00
pev - > effects & = ~ EF_DIMLIGHT ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgFlashlight , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( m_iFlashBattery ) ;
MESSAGE_END ( ) ;
m_flFlashLightTime = gpGlobals - > time + FLASH_CHARGE_TIME ;
}
2016-12-06 22:21:52 +03:00
// When recording a demo, we need to have the server tell us the entire client state so that the client side .dll can behave correctly.
// Reset stuff so that the state is transmitted.
2016-02-04 03:18:26 +03:00
void CBasePlayer : : ForceClientDllUpdate ( )
2015-09-30 03:49:22 +03:00
{
2016-09-26 23:16:33 +03:00
# ifdef REGAMEDLL_FIXES
// fix for https://github.com/ValveSoftware/halflife/issues/1567
m_iClientHideHUD = - 1 ;
2023-11-08 17:15:29 +03:00
m_flNextSBarUpdateTime = - 1 ;
InitStatusBar ( ) ;
# ifdef BUILD_LATEST
m_tmNextAccountHealthUpdate = - 1 ;
# endif
2016-09-26 23:16:33 +03:00
# endif
2015-09-30 03:49:22 +03:00
m_iClientHealth = - 1 ;
m_iClientBattery = - 1 ;
2016-09-26 23:16:33 +03:00
2016-12-06 22:21:52 +03:00
m_fWeapon = FALSE ; // Force weapon send
m_fInitHUD = TRUE ; // Force HUD gmsgResetHUD message
2017-10-12 17:50:56 +03:00
m_iTrain | = TRAIN_NEW ; // Force new train message.
2015-09-30 03:49:22 +03:00
2016-12-06 22:21:52 +03:00
// Now force all the necessary messages to be sent.
2015-09-30 03:49:22 +03:00
UpdateClientData ( ) ;
HandleSignals ( ) ;
2023-11-08 17:15:29 +03:00
# ifdef REGAMEDLL_FIXES
// Update HUD backpack ammo
for ( int i = 0 ; i < MAX_AMMO_SLOTS ; i + + )
m_rgAmmoLast [ i ] = - 1 ;
// Force update server name
MESSAGE_BEGIN ( MSG_ONE , gmsgServerName , nullptr , pev ) ;
WRITE_STRING ( CVAR_GET_STRING ( " hostname " ) ) ;
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_ONE , SVC_ROOMTYPE , nullptr , pev ) ;
WRITE_SHORT ( int ( CVAR_GET_FLOAT ( " room_type " ) ) ) ;
MESSAGE_END ( ) ;
SendItemStatus ( ) ;
// Loop through all active players and update their info to the client who started recording the demo
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
{
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
if ( ! pPlayer | | FNullEnt ( pPlayer - > edict ( ) ) )
continue ;
if ( pPlayer - > IsDormant ( ) )
continue ;
if ( pev - > deadflag = = DEAD_NO )
{
// NOTE: Don't use here PlayerRelationShip,
// because we have to send a radar message about the players in the team anyway,
// even if they are not teammates
bool sameTeam = pPlayer - > m_iTeam = = m_iTeam ;
if ( sameTeam )
{
const Vector & vecOrigin = CSGameRules ( ) - > IsFreeForAll ( ) ?
g_vecZero : pPlayer - > pev - > origin ;
MESSAGE_BEGIN ( MSG_ONE , gmsgRadar , nullptr , pev ) ;
WRITE_BYTE ( pPlayer - > entindex ( ) ) ;
WRITE_COORD ( vecOrigin . x ) ;
WRITE_COORD ( vecOrigin . y ) ;
WRITE_COORD ( vecOrigin . z ) ;
MESSAGE_END ( ) ;
}
// Update last location of players
if ( sameTeam | | pPlayer - > m_iTeam = = SPECTATOR )
{
if ( pPlayer - > m_lastLocation [ 0 ] )
{
MESSAGE_BEGIN ( MSG_ONE , gmsgLocation , nullptr , pev ) ;
WRITE_BYTE ( pPlayer - > entindex ( ) ) ;
WRITE_STRING ( pPlayer - > m_lastLocation ) ;
MESSAGE_END ( ) ;
}
}
}
// Update team info
MESSAGE_BEGIN ( MSG_ONE , gmsgTeamInfo , nullptr , pev ) ;
WRITE_BYTE ( pPlayer - > entindex ( ) ) ;
WRITE_STRING ( GetTeamName ( pPlayer - > m_iTeam ) ) ;
MESSAGE_END ( ) ;
// Update score info Frags, Deaths, etc
MESSAGE_BEGIN ( MSG_ONE , gmsgScoreInfo , nullptr , pev ) ;
WRITE_BYTE ( pPlayer - > entindex ( ) ) ;
WRITE_SHORT ( int ( pPlayer - > pev - > frags ) ) ;
WRITE_SHORT ( pPlayer - > m_iDeaths ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( pPlayer - > m_iTeam ) ;
MESSAGE_END ( ) ;
// Update player attributes DEAD, BOMB, VIP etc
pPlayer - > SetScoreAttrib ( this ) ;
}
# endif
2015-09-30 03:49:22 +03:00
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , ImpulseCommands )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( ImpulseCommands ) ( )
2015-09-30 03:49:22 +03:00
{
TraceResult tr ;
// Handle use events
PlayerUse ( ) ;
int iImpulse = pev - > impulse ;
switch ( iImpulse )
{
case 99 :
{
int iOn ;
if ( ! gmsgLogo )
{
iOn = 1 ;
gmsgLogo = REG_USER_MSG ( " Logo " , 1 ) ;
}
else
iOn = 0 ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgLogo , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( iOn ) ;
MESSAGE_END ( ) ;
if ( ! iOn )
gmsgLogo = 0 ;
break ;
}
case 100 :
{
// temporary flashlight for level designers
if ( FlashlightIsOn ( ) )
FlashlightTurnOff ( ) ;
else
FlashlightTurnOn ( ) ;
break ;
}
case 201 :
{
// paint decal
if ( gpGlobals - > time < m_flNextDecalTime )
{
// too early!
break ;
}
UTIL_MakeVectors ( pev - > v_angle ) ;
UTIL_TraceLine ( pev - > origin + pev - > view_ofs , pev - > origin + pev - > view_ofs + gpGlobals - > v_forward * 128 , ignore_monsters , edict ( ) , & tr ) ;
if ( tr . flFraction ! = 1.0f )
{
// line hit something, so paint a decal
m_flNextDecalTime = gpGlobals - > time + CVAR_GET_FLOAT ( " decalfrequency " ) ;
2017-10-13 03:04:37 +03:00
CSprayCan * pCan = GetClassPtr < CCSSprayCan > ( ( CSprayCan * ) nullptr ) ;
2015-09-30 03:49:22 +03:00
pCan - > Spawn ( pev ) ;
}
break ;
}
default :
// check all of the cheat impulse commands now
CheatImpulseCommands ( iImpulse ) ;
}
pev - > impulse = 0 ;
}
void CBasePlayer : : CheatImpulseCommands ( int iImpulse )
{
2019-06-07 21:16:15 +03:00
if ( ! CVAR_GET_FLOAT ( " sv_cheats " ) )
2015-09-30 03:49:22 +03:00
return ;
CBaseEntity * pEntity ;
TraceResult tr ;
switch ( iImpulse )
{
case 101 :
2019-09-22 17:49:52 +03:00
# ifdef REGAMEDLL_ADD
AddAccount ( int ( maxmoney . value ) ) ;
ALERT ( at_console , " Crediting %s with $%i \n " , STRING ( pev - > netname ) , int ( maxmoney . value ) ) ;
# else
2015-09-30 03:49:22 +03:00
AddAccount ( 16000 ) ;
ALERT ( at_console , " Crediting %s with $16000 \n " , STRING ( pev - > netname ) ) ;
2019-09-22 17:49:52 +03:00
# endif
2015-09-30 03:49:22 +03:00
break ;
case 102 :
CGib : : SpawnRandomGibs ( pev , 1 , 1 ) ;
break ;
2019-10-09 13:18:42 +03:00
# ifndef REGAMEDLL_FIXES
2015-09-30 03:49:22 +03:00
case 103 :
{
// What the hell are you doing?
pEntity = FindEntityForward ( this ) ;
if ( pEntity )
{
CBaseMonster * pMonster = pEntity - > MyMonsterPointer ( ) ;
if ( pMonster )
pMonster - > ReportAIState ( ) ;
}
break ;
}
2019-10-09 13:18:42 +03:00
# endif
2015-09-30 03:49:22 +03:00
case 104 :
// Dump all of the global state varaibles (and global entity names)
gGlobalState . DumpGlobals ( ) ;
break ;
2019-10-09 13:18:42 +03:00
# ifndef REGAMEDLL_FIXES
2015-09-30 03:49:22 +03:00
case 105 :
{
// player makes no sound for monsters to hear.
if ( m_fNoPlayerSound )
{
ALERT ( at_console , " Player is audible \n " ) ;
m_fNoPlayerSound = FALSE ;
}
else
{
ALERT ( at_console , " Player is silent \n " ) ;
m_fNoPlayerSound = TRUE ;
}
break ;
}
2019-10-09 13:18:42 +03:00
# endif
2015-09-30 03:49:22 +03:00
case 106 :
{
// Give me the classname and targetname of this entity.
pEntity = FindEntityForward ( this ) ;
if ( pEntity )
{
ALERT ( at_console , " Classname: %s " , STRING ( pEntity - > pev - > classname ) ) ;
if ( ! FStringNull ( pEntity - > pev - > targetname ) )
ALERT ( at_console , " - Targetname: %s \n " , STRING ( pEntity - > pev - > targetname ) ) ;
else
ALERT ( at_console , " - TargetName: No Targetname \n " ) ;
ALERT ( at_console , " Model: %s \n " , STRING ( pEntity - > pev - > model ) ) ;
if ( pEntity - > pev - > globalname )
ALERT ( at_console , " Globalname: %s \n " , STRING ( pEntity - > pev - > globalname ) ) ;
}
break ;
}
case 107 :
{
TraceResult tr ;
edict_t * pWorld = INDEXENT ( 0 ) ;
Vector start = pev - > origin + pev - > view_ofs ;
Vector end = start + gpGlobals - > v_forward * 1024 ;
UTIL_TraceLine ( start , end , ignore_monsters , edict ( ) , & tr ) ;
2016-12-06 22:21:52 +03:00
if ( tr . pHit )
2015-09-30 03:49:22 +03:00
pWorld = tr . pHit ;
const char * pszTextureName = TRACE_TEXTURE ( pWorld , start , end ) ;
2016-12-06 22:21:52 +03:00
if ( pszTextureName )
2015-09-30 03:49:22 +03:00
ALERT ( at_console , " Texture: %s \n " , pszTextureName ) ;
break ;
}
case 202 :
{
// Random blood splatter
UTIL_MakeVectors ( pev - > v_angle ) ;
UTIL_TraceLine ( pev - > origin + pev - > view_ofs , pev - > origin + pev - > view_ofs + gpGlobals - > v_forward * 128 , ignore_monsters , edict ( ) , & tr ) ;
if ( tr . flFraction ! = 1.0f )
{
// line hit something, so paint a decal
2017-10-13 03:04:37 +03:00
CBloodSplat * pBlood = GetClassPtr < CCSBloodSplat > ( ( CBloodSplat * ) nullptr ) ;
2015-09-30 03:49:22 +03:00
pBlood - > Spawn ( pev ) ;
}
break ;
}
case 203 :
{
// remove creature.
pEntity = FindEntityForward ( this ) ;
2016-12-06 22:21:52 +03:00
if ( pEntity & & pEntity - > pev - > takedamage ! = DAMAGE_NO )
2015-09-30 03:49:22 +03:00
{
pEntity - > SetThink ( & CBaseEntity : : SUB_Remove ) ;
}
break ;
}
case 204 :
{
TraceResult tr ;
2016-05-11 17:06:43 +03:00
Vector dir ( 0 , 0 , 1 ) ;
2015-09-30 03:49:22 +03:00
2023-07-11 03:01:53 +03:00
UTIL_BloodDrips ( pev - > origin , BLOOD_COLOR_RED , 2000 ) ;
2015-09-30 03:49:22 +03:00
for ( int r = 1 ; r < 4 ; r + + )
{
float bloodRange = r * 50.0f ;
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < 50 ; i + + )
2015-09-30 03:49:22 +03:00
{
dir . x = RANDOM_FLOAT ( - 1 , 1 ) ;
dir . y = RANDOM_FLOAT ( - 1 , 1 ) ;
dir . z = RANDOM_FLOAT ( - 1 , 1 ) ;
if ( dir . x | | dir . y | | dir . z )
dir . NormalizeInPlace ( ) ;
else
dir . z = - 1.0f ;
UTIL_TraceLine ( EyePosition ( ) , EyePosition ( ) + dir * bloodRange , ignore_monsters , pev - > pContainingEntity , & tr ) ;
if ( tr . flFraction < 1.0f )
UTIL_BloodDecalTrace ( & tr , BLOOD_COLOR_RED ) ;
}
}
break ;
}
2019-08-13 22:52:09 +03:00
# ifdef REGAMEDLL_ADD
case 255 :
{
// Give weapons
for ( int wpnid = WEAPON_NONE + 1 ; wpnid < MAX_WEAPONS ; wpnid + + )
{
// unwanted candidates
if ( wpnid = = WEAPON_GLOCK
| | wpnid = = WEAPON_C4
| | wpnid = = WEAPON_KNIFE )
continue ;
// If by some case the weapon got invalid
const auto pInfo = GetWeaponInfo ( wpnid ) ;
if ( pInfo ) {
GiveNamedItemEx ( pInfo - > entityName ) ;
GiveAmmo ( pInfo - > maxRounds , pInfo - > ammoName2 ) ;
}
}
# ifdef REGAMEDLL_API
CSPlayer ( ) - > m_iWeaponInfiniteAmmo = WPNMODE_INFINITE_BPAMMO ;
2019-08-26 01:45:27 +03:00
CSPlayer ( ) - > m_iWeaponInfiniteIds = WEAPON_ALLWEAPONS ;
2019-08-13 22:52:09 +03:00
# endif
2019-08-26 01:45:27 +03:00
2019-08-13 22:52:09 +03:00
GiveNamedItemEx ( " item_longjump " ) ;
GiveNamedItemEx ( " item_thighpack " ) ;
GiveNamedItemEx ( " item_kevlar " ) ;
break ;
}
# endif
2015-09-30 03:49:22 +03:00
}
}
2017-11-22 20:27:55 +03:00
void OLD_CheckBuyZone ( CBasePlayer * pPlayer )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
const char * pszSpawnClass = nullptr ;
2015-09-30 03:49:22 +03:00
2017-11-11 15:30:31 +03:00
# ifdef REGAMEDLL_FIXES
2017-11-22 20:27:55 +03:00
if ( ! CSGameRules ( ) - > CanPlayerBuy ( pPlayer ) )
2017-11-11 15:30:31 +03:00
{
return ;
}
# endif
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iTeam = = TERRORIST )
2017-11-11 15:30:31 +03:00
{
2015-09-30 03:49:22 +03:00
pszSpawnClass = " info_player_deathmatch " ;
2017-11-11 15:30:31 +03:00
}
2017-11-22 20:27:55 +03:00
else if ( pPlayer - > m_iTeam = = CT )
2017-11-11 15:30:31 +03:00
{
2015-09-30 03:49:22 +03:00
pszSpawnClass = " info_player_start " ;
2017-11-11 15:30:31 +03:00
}
2015-09-30 03:49:22 +03:00
2016-12-06 22:21:52 +03:00
if ( pszSpawnClass )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
CBaseEntity * pSpot = nullptr ;
2016-12-06 22:21:52 +03:00
while ( ( pSpot = UTIL_FindEntityByClassname ( pSpot , pszSpawnClass ) ) )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
if ( ( pSpot - > pev - > origin - pPlayer - > pev - > origin ) . Length ( ) < 200.0f )
2017-05-04 01:09:46 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > m_signals . Signal ( SIGNAL_BUY ) ;
2017-05-04 01:09:46 +03:00
# ifdef REGAMEDLL_FIXES
break ;
# endif
}
2015-09-30 03:49:22 +03:00
}
}
}
2017-11-22 20:27:55 +03:00
void OLD_CheckBombTarget ( CBasePlayer * pPlayer )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
CBaseEntity * pSpot = nullptr ;
2016-12-06 22:21:52 +03:00
while ( ( pSpot = UTIL_FindEntityByClassname ( pSpot , " info_bomb_target " ) ) )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
if ( ( pSpot - > pev - > origin - pPlayer - > pev - > origin ) . Length ( ) < = 256.0f )
2017-05-04 01:09:46 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > m_signals . Signal ( SIGNAL_BOMB ) ;
2017-05-04 01:09:46 +03:00
# ifdef REGAMEDLL_FIXES
break ;
# endif
}
2015-09-30 03:49:22 +03:00
}
}
2017-11-22 20:27:55 +03:00
void OLD_CheckRescueZone ( CBasePlayer * pPlayer )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
CBaseEntity * pSpot = nullptr ;
2016-12-06 22:21:52 +03:00
while ( ( pSpot = UTIL_FindEntityByClassname ( pSpot , " info_hostage_rescue " ) ) )
2015-09-30 03:49:22 +03:00
{
2019-10-09 13:18:42 +03:00
if ( ( pSpot - > pev - > origin - pPlayer - > pev - > origin ) . Length ( ) < = MAX_HOSTAGES_RESCUE_RADIUS )
2017-05-04 01:09:46 +03:00
{
2017-11-22 20:27:55 +03:00
pPlayer - > m_signals . Signal ( SIGNAL_RESCUE ) ;
2017-05-04 01:09:46 +03:00
# ifdef REGAMEDLL_FIXES
break ;
# endif
}
2015-09-30 03:49:22 +03:00
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : HandleSignals ( )
2015-09-30 03:49:22 +03:00
{
2016-02-23 02:13:52 +03:00
if ( CSGameRules ( ) - > IsMultiplayer ( ) )
2015-09-30 03:49:22 +03:00
{
2017-07-01 23:40:10 +03:00
2017-05-06 21:42:15 +03:00
# ifdef REGAMEDLL_ADD
if ( buytime . value ! = 0.0f )
# endif
2017-07-01 23:40:10 +03:00
{
2019-07-30 15:26:01 +03:00
# ifdef REGAMEDLL_ADD
if ( buy_anywhere . value )
{
if ( pev - > deadflag = = DEAD_NO & & ( m_iTeam = = TERRORIST | | m_iTeam = = CT )
& & ! ( m_signals . GetSignal ( ) & SIGNAL_BUY )
// Restricted by map rules
& & CSGameRules ( ) - > CanPlayerBuy ( this )
)
{
// 0 = default. 1 = both teams. 2 = Terrorists. 3 = Counter-Terrorists.
if ( buy_anywhere . value = = 1
| | ( buy_anywhere . value = = 2 & & m_iTeam = = TERRORIST )
| | ( buy_anywhere . value = = 3 & & m_iTeam = = CT )
)
{
m_signals . Signal ( SIGNAL_BUY ) ;
}
}
}
# endif
{
if ( ! CSGameRules ( ) - > m_bMapHasBuyZone )
OLD_CheckBuyZone ( this ) ;
}
2017-05-06 21:42:15 +03:00
}
2015-09-30 03:49:22 +03:00
2021-10-28 14:10:02 +03:00
# ifdef REGAMEDLL_ADD
if ( m_bHasC4 & & ( plant_c4_anywhere . value | | CSPlayer ( ) - > m_bPlantC4Anywhere ) )
{
if ( IsAlive ( ) & & ( m_iTeam = = TERRORIST | | m_iTeam = = CT )
& & ! ( m_signals . GetSignal ( ) & SIGNAL_BOMB ) )
{
m_signals . Signal ( SIGNAL_BOMB ) ;
}
}
2022-04-16 15:11:13 +03:00
# endif
2021-10-28 14:10:02 +03:00
2016-02-23 02:13:52 +03:00
if ( ! CSGameRules ( ) - > m_bMapHasBombZone )
2015-09-30 03:49:22 +03:00
OLD_CheckBombTarget ( this ) ;
2016-02-23 02:13:52 +03:00
if ( ! CSGameRules ( ) - > m_bMapHasRescueZone )
2015-09-30 03:49:22 +03:00
OLD_CheckRescueZone ( this ) ;
}
int state = m_signals . GetSignal ( ) ;
int changed = m_signals . GetState ( ) ^ state ;
m_signals . Update ( ) ;
if ( changed & SIGNAL_BUY )
{
if ( state & SIGNAL_BUY )
BuyZoneIcon_Set ( this ) ;
else
BuyZoneIcon_Clear ( this ) ;
}
if ( changed & SIGNAL_BOMB )
{
if ( state & SIGNAL_BOMB )
BombTargetFlash_Set ( this ) ;
else
BombTargetFlash_Clear ( this ) ;
}
if ( changed & SIGNAL_RESCUE )
{
if ( state & SIGNAL_RESCUE )
RescueZoneIcon_Set ( this ) ;
else
RescueZoneIcon_Clear ( this ) ;
}
if ( changed & SIGNAL_ESCAPE )
{
if ( state & SIGNAL_ESCAPE )
EscapeZoneIcon_Set ( this ) ;
else
EscapeZoneIcon_Clear ( this ) ;
}
if ( changed & SIGNAL_VIPSAFETY )
{
if ( state & SIGNAL_VIPSAFETY )
VIP_SafetyZoneIcon_Set ( this ) ;
else
VIP_SafetyZoneIcon_Clear ( this ) ;
}
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CHAIN ( BOOL , CBasePlayer , AddPlayerItem , ( CBasePlayerItem * pItem ) , pItem )
2016-04-05 03:12:05 +03:00
2015-09-30 03:49:22 +03:00
// Add a weapon to the player (Item == Weapon == Selectable Object)
2017-07-01 23:40:10 +03:00
BOOL EXT_FUNC CBasePlayer : : __API_HOOK ( AddPlayerItem ) ( CBasePlayerItem * pItem )
2015-09-30 03:49:22 +03:00
{
2017-10-19 20:12:02 +03:00
CBasePlayerItem * pInsert = m_rgpPlayerItems [ pItem - > iItemSlot ( ) ] ;
2016-07-20 19:44:00 +03:00
while ( pInsert )
2015-09-30 03:49:22 +03:00
{
if ( FClassnameIs ( pInsert - > pev , STRING ( pItem - > pev - > classname ) ) )
{
if ( pItem - > AddDuplicate ( pInsert ) )
{
g_pGameRules - > PlayerGotWeapon ( this , pItem ) ;
pItem - > CheckRespawn ( ) ;
// ugly hack to update clip w/o an update clip message
pItem - > UpdateItemInfo ( ) ;
if ( m_pActiveItem )
m_pActiveItem - > UpdateItemInfo ( ) ;
pItem - > Kill ( ) ;
}
return FALSE ;
}
pInsert = pInsert - > m_pNext ;
}
2015-11-06 17:58:48 +03:00
2015-09-30 03:49:22 +03:00
if ( pItem - > AddToPlayer ( this ) )
{
g_pGameRules - > PlayerGotWeapon ( this , pItem ) ;
if ( pItem - > iItemSlot ( ) = = PRIMARY_WEAPON_SLOT )
m_bHasPrimary = true ;
pItem - > CheckRespawn ( ) ;
2017-10-19 20:12:02 +03:00
pItem - > m_pNext = m_rgpPlayerItems [ pItem - > iItemSlot ( ) ] ;
m_rgpPlayerItems [ pItem - > iItemSlot ( ) ] = pItem ;
2015-09-30 03:49:22 +03:00
if ( HasShield ( ) )
2019-09-22 17:39:06 +03:00
pev - > gamestate = HITGROUP_SHIELD_ENABLED ;
2015-09-30 03:49:22 +03:00
// should we switch to this item?
if ( g_pGameRules - > FShouldSwitchWeapon ( this , pItem ) )
{
if ( ! m_bShieldDrawn )
{
SwitchWeapon ( pItem ) ;
}
}
2016-10-05 18:27:50 +03:00
# ifdef REGAMEDLL_FIXES
m_iHideHUD & = ~ HIDEHUD_WEAPONS ;
# endif
2015-09-30 03:49:22 +03:00
return TRUE ;
}
return FALSE ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CHAIN ( BOOL , CBasePlayer , RemovePlayerItem , ( CBasePlayerItem * pItem ) , pItem )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
BOOL EXT_FUNC CBasePlayer : : __API_HOOK ( RemovePlayerItem ) ( CBasePlayerItem * pItem )
2015-09-30 03:49:22 +03:00
{
if ( m_pActiveItem = = pItem )
{
ResetAutoaim ( ) ;
2020-05-27 04:33:10 +03:00
# ifdef REGAMEDLL_FIXES
// if (m_iFOV != DEFAULT_FOV)
{
pev - > fov = m_iFOV = m_iLastZoom = DEFAULT_FOV ;
m_bResumeZoom = false ;
ResetMaxSpeed ( ) ;
}
# endif
2015-09-30 03:49:22 +03:00
pItem - > pev - > nextthink = 0 ;
2017-10-13 03:04:37 +03:00
pItem - > SetThink ( nullptr ) ;
m_pActiveItem = nullptr ;
2015-09-30 03:49:22 +03:00
pev - > viewmodel = 0 ;
pev - > weaponmodel = 0 ;
}
2017-07-17 14:42:21 +03:00
# ifndef REGAMEDLL_FIXES
else
# endif
if ( m_pLastItem = = pItem )
2017-10-13 03:04:37 +03:00
m_pLastItem = nullptr ;
2015-09-30 03:49:22 +03:00
CBasePlayerItem * pPrev = m_rgpPlayerItems [ pItem - > iItemSlot ( ) ] ;
if ( pPrev = = pItem )
{
m_rgpPlayerItems [ pItem - > iItemSlot ( ) ] = pItem - > m_pNext ;
return TRUE ;
}
while ( pPrev & & pPrev - > m_pNext ! = pItem )
pPrev = pPrev - > m_pNext ;
2016-12-06 22:21:52 +03:00
if ( pPrev )
2015-09-30 03:49:22 +03:00
{
pPrev - > m_pNext = pItem - > m_pNext ;
return TRUE ;
}
2016-02-23 02:13:52 +03:00
2015-09-30 03:49:22 +03:00
return FALSE ;
}
2017-07-25 19:51:04 +03:00
LINK_HOOK_CLASS_CHAIN ( int , CBasePlayer , GiveAmmo , ( int iCount , const char * szName , int iMax ) , iCount , szName , iMax )
2016-04-05 03:12:05 +03:00
2015-09-30 03:49:22 +03:00
// Returns the unique ID for the ammo, or -1 if error
2017-07-25 19:51:04 +03:00
int EXT_FUNC CBasePlayer : : __API_HOOK ( GiveAmmo ) ( int iCount , const char * szName , int iMax )
2015-09-30 03:49:22 +03:00
{
if ( pev - > flags & FL_SPECTATOR )
return - 1 ;
if ( ! szName )
{
// no ammo.
return - 1 ;
}
2016-12-06 22:21:52 +03:00
if ( iMax = = - 1 )
iMax = MaxAmmoCarry ( szName ) ;
2015-09-30 03:49:22 +03:00
if ( ! g_pGameRules - > CanHaveAmmo ( this , szName , iMax ) )
{
// game rules say I can't have any more of this ammo type.
return - 1 ;
}
int i = GetAmmoIndex ( szName ) ;
if ( i < 0 | | i > = MAX_AMMO_SLOTS )
return - 1 ;
int iAdd = Q_min ( iCount , iMax - m_rgAmmo [ i ] ) ;
if ( iAdd < 1 )
return i ;
m_rgAmmo [ i ] + = iAdd ;
// make sure the ammo messages have been linked first
if ( gmsgAmmoPickup )
{
// Send the message that ammo has been picked up
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgAmmoPickup , nullptr , pev ) ;
2019-10-09 13:18:42 +03:00
WRITE_BYTE ( i ) ; // ammo ID
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( iAdd ) ; // amount
MESSAGE_END ( ) ;
}
2016-02-23 02:13:52 +03:00
TabulateAmmo ( ) ;
2015-09-30 03:49:22 +03:00
return i ;
}
// Called every frame by the player PreThink
2016-02-04 03:18:26 +03:00
void CBasePlayer : : ItemPreFrame ( )
2015-09-30 03:49:22 +03:00
{
# ifdef CLIENT_WEAPONS
if ( m_flNextAttack > 0 )
return ;
# else
if ( gpGlobals - > time < m_flNextAttack )
return ;
2016-02-23 02:13:52 +03:00
# endif
2015-09-30 03:49:22 +03:00
if ( ! m_pActiveItem )
return ;
m_pActiveItem - > ItemPreFrame ( ) ;
}
// Called every frame by the player PostThink
2016-02-04 03:18:26 +03:00
void CBasePlayer : : ItemPostFrame ( )
2015-09-30 03:49:22 +03:00
{
static int fInSelect = FALSE ;
// check if the player is using a tank
2016-12-06 22:21:52 +03:00
if ( m_pTank )
2015-09-30 03:49:22 +03:00
return ;
2016-12-06 22:21:52 +03:00
if ( m_pActiveItem )
2015-09-30 03:49:22 +03:00
{
if ( HasShield ( ) & & IsReloading ( ) )
{
if ( pev - > button & IN_ATTACK2 )
m_flNextAttack = 0 ;
}
}
# ifdef CLIENT_WEAPONS
if ( m_flNextAttack > 0 )
# else
if ( gpGlobals - > time < m_flNextAttack )
2016-02-23 02:13:52 +03:00
# endif
2015-09-30 03:49:22 +03:00
return ;
ImpulseCommands ( ) ;
2016-12-06 22:21:52 +03:00
if ( m_pActiveItem )
2015-09-30 03:49:22 +03:00
m_pActiveItem - > ItemPostFrame ( ) ;
}
int CBasePlayer : : AmmoInventory ( int iAmmoIndex )
{
if ( iAmmoIndex = = - 1 )
return - 1 ;
return m_rgAmmo [ iAmmoIndex ] ;
}
int CBasePlayer : : GetAmmoIndex ( const char * psz )
{
if ( ! psz )
return - 1 ;
2017-10-13 03:04:37 +03:00
for ( int i = 1 ; i < MAX_AMMO_SLOTS ; i + + )
2015-09-30 03:49:22 +03:00
{
2017-10-19 20:12:02 +03:00
if ( ! CBasePlayerItem : : m_AmmoInfoArray [ i ] . pszName )
2015-09-30 03:49:22 +03:00
continue ;
2017-10-19 20:12:02 +03:00
if ( ! Q_stricmp ( CBasePlayerItem : : m_AmmoInfoArray [ i ] . pszName , psz ) )
2015-09-30 03:49:22 +03:00
return i ;
}
2016-02-23 02:13:52 +03:00
2015-09-30 03:49:22 +03:00
return - 1 ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : SendAmmoUpdate ( )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < MAX_AMMO_SLOTS ; i + + )
2015-09-30 03:49:22 +03:00
{
if ( m_rgAmmo [ i ] ! = m_rgAmmoLast [ i ] )
{
m_rgAmmoLast [ i ] = m_rgAmmo [ i ] ;
// send "Ammo" update message
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgAmmoX , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( i ) ;
2019-10-09 13:18:42 +03:00
WRITE_BYTE ( clamp ( m_rgAmmo [ i ] , 0 , 255 ) ) ; // clamp the value to one byte
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : SendHostagePos ( )
2015-09-30 03:49:22 +03:00
{
2019-10-09 13:18:42 +03:00
CHostage * pHostage = nullptr ;
2016-12-06 22:21:52 +03:00
while ( ( pHostage = UTIL_FindEntityByClassname ( pHostage , " hostage_entity " ) ) )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgHostagePos , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 1 ) ;
2019-10-09 13:18:42 +03:00
WRITE_BYTE ( pHostage - > m_iHostageIndex ) ;
2015-09-30 03:49:22 +03:00
WRITE_COORD ( pHostage - > pev - > origin . x ) ;
WRITE_COORD ( pHostage - > pev - > origin . y ) ;
WRITE_COORD ( pHostage - > pev - > origin . z ) ;
MESSAGE_END ( ) ;
}
SendHostageIcons ( ) ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : SendHostageIcons ( )
2015-09-30 03:49:22 +03:00
{
2019-09-18 11:04:32 +03:00
if ( ! AreRunningCZero ( )
# ifdef REGAMEDLL_ADD
& & ! show_scenarioicon . value
# endif
)
{
2015-09-30 03:49:22 +03:00
return ;
2019-09-18 11:04:32 +03:00
}
2015-09-30 03:49:22 +03:00
2017-11-22 20:27:55 +03:00
int hostagesCount = 0 ;
2019-10-09 13:18:42 +03:00
CHostage * pHostage = nullptr ;
2017-11-22 20:27:55 +03:00
2016-12-06 22:21:52 +03:00
while ( ( pHostage = UTIL_FindEntityByClassname ( pHostage , " hostage_entity " ) ) )
2015-09-30 03:49:22 +03:00
{
2016-12-06 22:21:52 +03:00
if ( pHostage - > IsAlive ( ) )
2017-11-22 20:27:55 +03:00
hostagesCount + + ;
2015-09-30 03:49:22 +03:00
}
2017-11-22 20:27:55 +03:00
if ( hostagesCount > MAX_HOSTAGE_ICON )
hostagesCount = MAX_HOSTAGE_ICON ;
2015-09-30 03:49:22 +03:00
2020-02-06 15:11:07 +03:00
char buf [ 18 ] ;
2017-11-22 20:27:55 +03:00
Q_snprintf ( buf , ARRAYSIZE ( buf ) , " hostage%d " , hostagesCount ) ;
2015-09-30 03:49:22 +03:00
2017-11-22 20:27:55 +03:00
if ( hostagesCount )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgScenarioIcon , nullptr , pev ) ;
2016-02-23 02:13:52 +03:00
WRITE_BYTE ( 1 ) ; // active
WRITE_STRING ( buf ) ; // sprite
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
}
else
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgScenarioIcon , nullptr , pev ) ;
2016-02-23 02:13:52 +03:00
WRITE_BYTE ( 0 ) ; // active
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : SendWeatherInfo ( )
2015-09-30 03:49:22 +03:00
{
2017-07-06 20:41:20 +03:00
auto SendReceiveW = [ & ] ( BYTE byte )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgReceiveW , nullptr , pev ) ;
2017-07-06 20:41:20 +03:00
WRITE_BYTE ( byte ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
2017-07-06 20:41:20 +03:00
} ;
2015-09-30 03:49:22 +03:00
2017-07-06 20:41:20 +03:00
/* Rain */
2019-10-09 13:18:42 +03:00
if ( UTIL_FindEntityByClassname ( nullptr , " env_rain " ) )
2017-07-06 20:41:20 +03:00
return SendReceiveW ( 1 ) ;
2019-10-09 13:18:42 +03:00
if ( UTIL_FindEntityByClassname ( nullptr , " func_rain " ) )
2017-07-06 20:41:20 +03:00
return SendReceiveW ( 1 ) ;
/* Snow */
2019-10-09 13:18:42 +03:00
if ( UTIL_FindEntityByClassname ( nullptr , " env_snow " ) )
2017-07-06 20:41:20 +03:00
return SendReceiveW ( 2 ) ;
2019-10-09 13:18:42 +03:00
if ( UTIL_FindEntityByClassname ( nullptr , " func_snow " ) )
2017-07-06 20:41:20 +03:00
return SendReceiveW ( 2 ) ;
2015-09-30 03:49:22 +03:00
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , UpdateClientData )
2016-04-05 03:12:05 +03:00
2015-09-30 03:49:22 +03:00
// resends any changed player HUD info to the client.
// Called every frame by PlayerPreThink
// Also called at start of demo recording and playback by
// ForceClientDllUpdate to ensure the demo gets messages
// reflecting all of the HUD state info.
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( UpdateClientData ) ( )
2015-09-30 03:49:22 +03:00
{
if ( m_fInitHUD )
{
m_fInitHUD = FALSE ;
gInitHUD = FALSE ;
2020-12-02 13:46:12 +03:00
# ifdef REGAMEDLL_FIXES
m_signals . Reset ( ) ;
# else
2015-09-30 03:49:22 +03:00
m_signals . Update ( ) ;
2020-12-02 13:46:12 +03:00
# endif
2015-09-30 03:49:22 +03:00
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgResetHUD , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
if ( ! m_fGameHUDInitialized )
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgInitHUD , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
2017-10-13 03:04:37 +03:00
CBaseEntity * pEntity = UTIL_FindEntityByClassname ( nullptr , " env_fog " ) ;
2016-12-06 22:21:52 +03:00
if ( pEntity )
2015-09-30 03:49:22 +03:00
{
2016-02-23 02:13:52 +03:00
CClientFog * pFog = static_cast < CClientFog * > ( pEntity ) ;
2015-09-30 03:49:22 +03:00
2016-02-23 02:13:52 +03:00
int r = clamp ( int ( pFog - > pev - > rendercolor [ 0 ] ) , 0 , 255 ) ;
int g = clamp ( int ( pFog - > pev - > rendercolor [ 1 ] ) , 0 , 255 ) ;
int b = clamp ( int ( pFog - > pev - > rendercolor [ 2 ] ) , 0 , 255 ) ;
2015-09-30 03:49:22 +03:00
union
{
float f ;
char b [ 4 ] ;
} density ;
density . f = pFog - > m_fDensity ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgFog , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( r ) ;
WRITE_BYTE ( g ) ;
WRITE_BYTE ( b ) ;
WRITE_BYTE ( density . b [ 0 ] ) ;
WRITE_BYTE ( density . b [ 1 ] ) ;
WRITE_BYTE ( density . b [ 2 ] ) ;
WRITE_BYTE ( density . b [ 3 ] ) ;
MESSAGE_END ( ) ;
}
2016-02-23 02:13:52 +03:00
g_pGameRules - > InitHUD ( this ) ;
2015-09-30 03:49:22 +03:00
m_fGameHUDInitialized = TRUE ;
2016-02-23 02:13:52 +03:00
if ( g_pGameRules - > IsMultiplayer ( ) )
2015-09-30 03:49:22 +03:00
{
FireTargets ( " game_playerjoin " , this , this , USE_TOGGLE , 0 ) ;
}
m_iObserverLastMode = OBS_ROAMING ;
m_iObserverC4State = 0 ;
m_bObserverHasDefuser = false ;
SetObserverAutoDirector ( false ) ;
}
2016-06-02 01:08:22 +03:00
# ifndef REGAMEDLL_FIXES
2015-09-30 03:49:22 +03:00
FireTargets ( " game_playerspawn " , this , this , USE_TOGGLE , 0 ) ;
2016-06-02 01:08:22 +03:00
# endif
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgMoney , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_LONG ( m_iAccount ) ;
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
if ( m_bHasDefuser )
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( STATUSICON_SHOW ) ;
WRITE_STRING ( " defuser " ) ;
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( 160 ) ;
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
}
SetBombIcon ( FALSE ) ;
SyncRoundTimer ( ) ;
SendHostagePos ( ) ;
SendWeatherInfo ( ) ;
2016-02-23 02:13:52 +03:00
if ( g_pGameRules - > IsMultiplayer ( ) )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgTeamScore , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_STRING ( GetTeam ( CT ) ) ;
2016-02-23 02:13:52 +03:00
WRITE_SHORT ( CSGameRules ( ) - > m_iNumCTWins ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgTeamScore , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_STRING ( GetTeam ( TERRORIST ) ) ;
2016-02-23 02:13:52 +03:00
WRITE_SHORT ( CSGameRules ( ) - > m_iNumTerroristWins ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
2016-09-26 23:16:33 +03:00
# ifdef REGAMEDLL_FIXES
// send "flashlight" update message
if ( FlashlightIsOn ( ) )
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgFlashlight , nullptr , pev ) ;
2016-09-26 23:16:33 +03:00
WRITE_BYTE ( 1 ) ;
WRITE_BYTE ( m_iFlashBattery ) ;
MESSAGE_END ( ) ;
}
# endif
2015-09-30 03:49:22 +03:00
}
if ( m_iHideHUD ! = m_iClientHideHUD )
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgHideWeapon , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( m_iHideHUD ) ;
MESSAGE_END ( ) ;
2016-12-06 22:21:52 +03:00
# ifdef REGAMEDLL_FIXES
if ( m_iHideHUD & & ! ( m_iHideHUD & HIDEHUD_OBSERVER_CROSSHAIR ) )
{
if ( m_iClientHideHUD < 0 )
m_iClientHideHUD = 0 ;
int hudChanged = m_iClientHideHUD ^ m_iHideHUD ;
2021-12-28 19:23:17 +03:00
if ( hudChanged & ( HIDEHUD_FLASHLIGHT | HIDEHUD_HEALTH | HIDEHUD_TIMER | HIDEHUD_MONEY | HIDEHUD_CROSSHAIR ) )
2016-12-06 22:21:52 +03:00
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgCrosshair , nullptr , pev ) ;
2016-12-06 22:21:52 +03:00
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
}
}
# endif
2015-09-30 03:49:22 +03:00
m_iClientHideHUD = m_iHideHUD ;
}
if ( m_iFOV ! = m_iClientFOV )
{
// cache FOV change at end of function, so weapon updates can see that FOV has changed
pev - > fov = m_iFOV ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgSetFOV , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( m_iFOV ) ;
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_SPEC , gmsgHLTV ) ;
WRITE_BYTE ( ENTINDEX ( edict ( ) ) ) ;
WRITE_BYTE ( m_iFOV ) ;
MESSAGE_END ( ) ;
}
// HACKHACK -- send the message to display the game title
if ( gDisplayTitle )
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgShowGameTitle , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
gDisplayTitle = FALSE ;
}
2016-02-23 02:13:52 +03:00
if ( int ( pev - > health ) ! = m_iClientHealth )
2015-09-30 03:49:22 +03:00
{
2016-02-23 02:13:52 +03:00
int iHealth = clamp ( int ( pev - > health ) , 0 , 255 ) ;
2015-09-30 03:49:22 +03:00
if ( pev - > health > 0.0f & & pev - > health < = 1.0f )
iHealth = 1 ;
// send "health" update message
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgHealth , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( iHealth ) ;
MESSAGE_END ( ) ;
2016-02-23 02:13:52 +03:00
m_iClientHealth = int ( pev - > health ) ;
2015-09-30 03:49:22 +03:00
}
2016-02-23 02:13:52 +03:00
if ( int ( pev - > armorvalue ) ! = m_iClientBattery )
2015-09-30 03:49:22 +03:00
{
2016-02-23 02:13:52 +03:00
m_iClientBattery = int ( pev - > armorvalue ) ;
2015-09-30 03:49:22 +03:00
// send "armor" update message
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBattery , nullptr , pev ) ;
2016-02-23 02:13:52 +03:00
WRITE_SHORT ( int ( pev - > armorvalue ) ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
if ( pev - > dmg_take ! = 0.0f | | pev - > dmg_save ! = 0.0f | | m_bitsHUDDamage ! = m_bitsDamageType )
{
// Comes from inside me if not set
Vector damageOrigin = pev - > origin ;
// send "damage" message
// causes screen to flash, and pain compass to show direction of damage
edict_t * other = pev - > dmg_inflictor ;
2016-12-06 22:21:52 +03:00
if ( other )
2015-09-30 03:49:22 +03:00
{
CBaseEntity * pEntity = CBaseEntity : : Instance ( other ) ;
2016-12-06 22:21:52 +03:00
if ( pEntity )
2015-09-30 03:49:22 +03:00
{
2023-09-30 10:54:32 +03:00
if ( pEntity = = this & & ( m_bitsDamageType & DMG_FALL ) )
damageOrigin = Vector ( 0 , 0 , 0 ) ; // do not show direction of damage caused by fall
else
damageOrigin = pEntity - > Center ( ) ;
2015-09-30 03:49:22 +03:00
}
}
// only send down damage type that have hud art
int visibleDamageBits = m_bitsDamageType & DMG_SHOWNHUD ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgDamage , nullptr , pev ) ;
2016-02-23 02:13:52 +03:00
WRITE_BYTE ( int ( pev - > dmg_save ) ) ;
WRITE_BYTE ( int ( pev - > dmg_take ) ) ;
2015-09-30 03:49:22 +03:00
WRITE_LONG ( visibleDamageBits ) ;
WRITE_COORD ( damageOrigin . x ) ;
WRITE_COORD ( damageOrigin . y ) ;
WRITE_COORD ( damageOrigin . z ) ;
MESSAGE_END ( ) ;
pev - > dmg_take = 0 ;
pev - > dmg_save = 0 ;
m_bitsHUDDamage = m_bitsDamageType ;
// Clear off non-time-based damage indicators
m_bitsDamageType & = DMG_TIMEBASED ;
}
// Update Flashlight
if ( m_flFlashLightTime & & m_flFlashLightTime < = gpGlobals - > time )
{
if ( FlashlightIsOn ( ) )
{
if ( m_iFlashBattery )
{
m_flFlashLightTime = gpGlobals - > time + FLASH_DRAIN_TIME ;
2016-02-23 02:13:52 +03:00
if ( - - m_iFlashBattery < = 0 )
2015-09-30 03:49:22 +03:00
{
FlashlightTurnOff ( ) ;
}
}
}
else
{
if ( m_iFlashBattery < 100 )
{
m_flFlashLightTime = gpGlobals - > time + FLASH_CHARGE_TIME ;
m_iFlashBattery + + ;
}
else
m_flFlashLightTime = 0 ;
}
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgFlashBattery , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( m_iFlashBattery ) ;
MESSAGE_END ( ) ;
}
if ( m_iTrain & TRAIN_NEW )
{
// send "train hud" update message
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgTrain , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( m_iTrain & 0xF ) ;
MESSAGE_END ( ) ;
m_iTrain & = ~ TRAIN_NEW ;
}
SendAmmoUpdate ( ) ;
// Update all the items
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < MAX_ITEM_TYPES ; i + + )
2015-09-30 03:49:22 +03:00
{
if ( m_rgpPlayerItems [ i ] )
{
// each item updates it's successors
m_rgpPlayerItems [ i ] - > UpdateClientData ( this ) ;
}
}
// Cache and client weapon change
m_pClientActiveItem = m_pActiveItem ;
m_iClientFOV = m_iFOV ;
// Update Status Bar
if ( m_flNextSBarUpdateTime < gpGlobals - > time )
{
UpdateStatusBar ( ) ;
2016-02-23 02:13:52 +03:00
m_flNextSBarUpdateTime = gpGlobals - > time + 0.2f ;
2015-09-30 03:49:22 +03:00
}
if ( ! ( m_flDisplayHistory & DHF_AMMO_EXHAUSTED ) )
{
if ( m_pActiveItem & & m_pActiveItem - > IsWeapon ( ) )
{
2016-02-23 02:13:52 +03:00
CBasePlayerWeapon * weapon = static_cast < CBasePlayerWeapon * > ( m_pActiveItem ) ;
2015-09-30 03:49:22 +03:00
2016-02-23 02:13:52 +03:00
if ( ! ( weapon - > iFlags ( ) & ITEM_FLAG_EXHAUSTIBLE ) )
2015-09-30 03:49:22 +03:00
{
2016-02-23 02:13:52 +03:00
if ( AmmoInventory ( weapon - > m_iPrimaryAmmoType ) < 1 & & weapon - > m_iClip = = 0 )
2015-09-30 03:49:22 +03:00
{
m_flDisplayHistory | = DHF_AMMO_EXHAUSTED ;
HintMessage ( " #Hint_out_of_ammo " ) ;
}
}
}
}
if ( gpGlobals - > time > m_tmHandleSignals )
{
m_tmHandleSignals = gpGlobals - > time + 0.5f ;
HandleSignals ( ) ;
}
if ( pev - > deadflag = = DEAD_NO & & gpGlobals - > time > m_tmNextRadarUpdate )
{
2016-01-28 07:48:09 +03:00
Vector vecOrigin = pev - > origin ;
2015-09-30 03:49:22 +03:00
m_tmNextRadarUpdate = gpGlobals - > time + 1.0f ;
2016-01-28 07:48:09 +03:00
# ifdef REGAMEDLL_ADD
2016-06-14 18:00:27 +03:00
if ( CSGameRules ( ) - > IsFreeForAll ( ) )
2016-01-28 07:48:09 +03:00
vecOrigin = g_vecZero ;
2016-02-23 02:13:52 +03:00
# endif
2016-01-28 07:48:09 +03:00
2016-02-23 02:13:52 +03:00
const float flToleranceDist = 64.0f ;
if ( ( pev - > origin - m_vLastOrigin ) . Length ( ) > = flToleranceDist )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
2015-09-30 03:49:22 +03:00
{
CBaseEntity * pEntity = UTIL_PlayerByIndex ( i ) ;
if ( ! pEntity | | i = = entindex ( ) )
continue ;
2016-03-17 20:44:52 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
2015-09-30 03:49:22 +03:00
if ( pPlayer - > pev - > flags = = FL_DORMANT )
continue ;
if ( pPlayer - > pev - > deadflag ! = DEAD_NO )
continue ;
if ( pPlayer - > m_iTeam = = m_iTeam )
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgRadar , nullptr , pPlayer - > pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( entindex ( ) ) ;
2016-01-28 07:48:09 +03:00
WRITE_COORD ( vecOrigin . x ) ;
WRITE_COORD ( vecOrigin . y ) ;
WRITE_COORD ( vecOrigin . z ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
}
}
}
m_vLastOrigin = pev - > origin ;
}
2019-06-04 17:41:30 +03:00
# ifdef BUILD_LATEST
2020-01-15 18:10:32 +03:00
if (
# ifdef REGAMEDLL_FIXES
( scoreboard_showmoney . value ! = - 1.0f | | scoreboard_showhealth . value ! = - 1.0f ) & &
# endif
( m_iTeam = = CT | | m_iTeam = = TERRORIST ) & &
2019-12-17 17:25:24 +03:00
( m_iLastAccount ! = m_iAccount | | m_iLastClientHealth ! = m_iClientHealth | | m_tmNextAccountHealthUpdate < gpGlobals - > time ) )
2019-06-04 17:41:30 +03:00
{
2019-12-17 17:25:24 +03:00
m_tmNextAccountHealthUpdate = gpGlobals - > time + 5.0f ;
2019-06-04 17:41:30 +03:00
2019-12-17 17:25:24 +03:00
for ( int playerIndex = 1 ; playerIndex < = gpGlobals - > maxClients ; playerIndex + + )
{
CBaseEntity * pEntity = UTIL_PlayerByIndex ( playerIndex ) ;
2019-06-04 17:41:30 +03:00
2019-12-17 17:25:24 +03:00
if ( ! pEntity )
continue ;
2019-08-26 00:26:55 +03:00
2019-12-17 17:25:24 +03:00
CBasePlayer * pPlayer = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
2019-06-04 17:41:30 +03:00
# ifdef REGAMEDLL_FIXES
2019-12-17 17:25:24 +03:00
if ( pPlayer - > IsDormant ( ) )
continue ;
2019-06-04 17:41:30 +03:00
# endif // REGAMEDLL_FIXES
2020-01-15 18:10:32 +03:00
# ifdef REGAMEDLL_FIXES
2020-03-05 15:21:07 +03:00
if ( scoreboard_showhealth . value ! = - 1.0f )
2020-01-15 18:10:32 +03:00
# endif
{
MESSAGE_BEGIN ( MSG_ONE , gmsgHealthInfo , nullptr , pPlayer - > edict ( ) ) ;
WRITE_BYTE ( entindex ( ) ) ;
WRITE_LONG ( ShouldToShowHealthInfo ( pPlayer ) ? m_iClientHealth : - 1 /* means that 'HP' field will be hidden */ ) ;
MESSAGE_END ( ) ;
}
2019-06-04 17:41:30 +03:00
2020-01-15 18:10:32 +03:00
# ifdef REGAMEDLL_FIXES
2020-03-05 15:21:07 +03:00
if ( scoreboard_showmoney . value ! = - 1.0f )
2020-01-15 18:10:32 +03:00
# endif
{
MESSAGE_BEGIN ( MSG_ONE , gmsgAccount , nullptr , pPlayer - > edict ( ) ) ;
WRITE_BYTE ( entindex ( ) ) ;
WRITE_LONG ( ShouldToShowAccount ( pPlayer ) ? m_iAccount : - 1 /* means that this 'Money' will be hidden */ ) ;
MESSAGE_END ( ) ;
}
2019-08-26 00:26:55 +03:00
}
2019-12-17 17:25:24 +03:00
m_iLastAccount = m_iAccount ;
m_iLastClientHealth = m_iClientHealth ;
2019-06-04 17:41:30 +03:00
}
# endif // #ifdef BUILD_LATEST
}
bool CBasePlayer : : ShouldToShowAccount ( CBasePlayer * pReceiver ) const
{
# ifdef BUILD_LATEST
int iShowAccount = static_cast < int > ( scoreboard_showmoney . value ) ;
# ifdef REGAMEDLL_FIXES
if ( iShowAccount = = 0 )
return false ; // don't send any update for this field to any clients
# endif
// show only Terrorist or CT 'Money' field to all clients
if ( m_iTeam = = iShowAccount )
return true ;
switch ( iShowAccount )
{
// show field to teammates
2019-10-09 13:09:23 +03:00
case 3 : return ! CSGameRules ( ) - > IsFreeForAll ( ) & & pReceiver - > m_iTeam = = m_iTeam ;
2019-06-04 17:41:30 +03:00
// show field to all clients
case 4 : return true ;
// show field to teammates and spectators
2019-10-09 13:09:23 +03:00
case 5 : return ( ( ! CSGameRules ( ) - > IsFreeForAll ( ) & & pReceiver - > m_iTeam = = m_iTeam ) | | pReceiver - > m_iTeam = = SPECTATOR ) ;
2019-06-04 17:41:30 +03:00
default :
break ;
}
# endif // #ifdef BUILD_LATEST
return false ;
}
bool CBasePlayer : : ShouldToShowHealthInfo ( CBasePlayer * pReceiver ) const
{
# ifdef BUILD_LATEST
int iShowHealth = static_cast < int > ( scoreboard_showhealth . value ) ;
# ifdef REGAMEDLL_FIXES
if ( iShowHealth = = 0 )
return false ; // don't send any update for this field to any clients
# endif
// show only Terrorist or CT 'HP' fields to all clients
if ( m_iTeam = = iShowHealth )
return true ;
switch ( iShowHealth )
{
// show field to teammates
2019-10-09 13:09:23 +03:00
case 3 : return ! CSGameRules ( ) - > IsFreeForAll ( ) & & pReceiver - > m_iTeam = = m_iTeam ;
2019-06-04 17:41:30 +03:00
// show field to all clients
case 4 : return true ;
// show field to teammates and spectators
2019-10-09 13:09:23 +03:00
case 5 : return ( ( ! CSGameRules ( ) - > IsFreeForAll ( ) & & pReceiver - > m_iTeam = = m_iTeam ) | | pReceiver - > m_iTeam = = SPECTATOR ) ;
2019-06-04 17:41:30 +03:00
default :
break ;
}
# endif // #ifdef BUILD_LATEST
return false ;
2015-09-30 03:49:22 +03:00
}
2017-07-01 23:40:10 +03:00
BOOL CBasePlayer : : FBecomeProne ( )
2015-09-30 03:49:22 +03:00
{
m_afPhysicsFlags | = PFLAG_ONBARNACLE ;
return TRUE ;
}
NOXREF void CBasePlayer : : BarnacleVictimBitten ( entvars_t * pevBarnacle )
{
TakeDamage ( pevBarnacle , pevBarnacle , pev - > armorvalue + pev - > health , DMG_SLASH | DMG_ALWAYSGIB ) ;
}
2016-02-04 03:18:26 +03:00
NOXREF void CBasePlayer : : BarnacleVictimReleased ( )
2015-09-30 03:49:22 +03:00
{
m_afPhysicsFlags & = ~ PFLAG_ONBARNACLE ;
}
// return player light level plus virtual muzzle flash
2017-07-01 23:40:10 +03:00
int CBasePlayer : : Illumination ( )
2015-09-30 03:49:22 +03:00
{
int iIllum = CBaseEntity : : Illumination ( ) ;
iIllum + = m_iWeaponFlash ;
if ( iIllum > 255 )
return 255 ;
return iIllum ;
}
void CBasePlayer : : EnableControl ( BOOL fControl )
{
if ( ! fControl )
pev - > flags | = FL_FROZEN ;
else
pev - > flags & = ~ FL_FROZEN ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , ResetMaxSpeed )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( ResetMaxSpeed ) ( )
2015-09-30 03:49:22 +03:00
{
float speed ;
2018-02-08 12:37:02 +03:00
if ( GetObserverMode ( ) ! = OBS_NONE )
2015-09-30 03:49:22 +03:00
{
// Player gets speed bonus in observer mode
speed = 900 ;
}
else if ( g_pGameRules - > IsMultiplayer ( ) & & g_pGameRules - > IsFreezePeriod ( ) )
{
// Player should not move during the freeze period
speed = 1 ;
}
// VIP is slow due to the armour he's wearing
2016-12-06 22:21:52 +03:00
else if ( m_bIsVIP )
2015-09-30 03:49:22 +03:00
{
speed = 227 ;
}
2016-12-06 22:21:52 +03:00
else if ( m_pActiveItem )
2015-09-30 03:49:22 +03:00
{
// Get player speed from selected weapon
speed = m_pActiveItem - > GetMaxSpeed ( ) ;
}
else
{
// No active item, set the player's speed to default
speed = 240 ;
}
pev - > maxspeed = speed ;
}
2019-06-05 22:57:40 +03:00
LINK_HOOK_CLASS_CHAIN ( bool , CBasePlayer , HintMessageEx , ( const char * pMessage , float duration , bool bDisplayIfPlayerDead , bool bOverride ) , pMessage , duration , bDisplayIfPlayerDead , bOverride )
bool EXT_FUNC CBasePlayer : : __API_HOOK ( HintMessageEx ) ( const char * pMessage , float duration , bool bDisplayIfPlayerDead , bool bOverride )
2015-09-30 03:49:22 +03:00
{
if ( ! bDisplayIfPlayerDead & & ! IsAlive ( ) )
return false ;
if ( bOverride | | m_bShowHints )
2019-06-05 22:57:40 +03:00
return m_hintMessageQueue . AddMessage ( pMessage , duration , true , nullptr ) ;
2015-09-30 03:49:22 +03:00
return true ;
}
2019-06-05 22:57:40 +03:00
bool EXT_FUNC CBasePlayer : : HintMessage ( const char * pMessage , BOOL bDisplayIfPlayerDead , BOOL bOverride )
{
2019-06-06 00:20:19 +03:00
return HintMessageEx ( pMessage , 6.0f , bDisplayIfPlayerDead = = TRUE , bOverride = = TRUE ) ;
2019-06-05 22:57:40 +03:00
}
2017-07-01 23:40:10 +03:00
Vector CBasePlayer : : GetAutoaimVector ( float flDelta )
2015-09-30 03:49:22 +03:00
{
Vector vecSrc ;
BOOL m_fOldTargeting ;
Vector angles ;
if ( g_iSkillLevel = = SKILL_HARD )
{
UTIL_MakeVectors ( pev - > v_angle + pev - > punchangle ) ;
return gpGlobals - > v_forward ;
}
vecSrc = GetGunPosition ( ) ;
m_fOldTargeting = m_fOnTarget ;
m_vecAutoAim = Vector ( 0 , 0 , 0 ) ;
angles = AutoaimDeflection ( vecSrc , 8192 , flDelta ) ;
if ( g_pGameRules - > AllowAutoTargetCrosshair ( ) )
{
if ( m_fOldTargeting ! = m_fOnTarget )
m_pActiveItem - > UpdateItemInfo ( ) ;
}
else
m_fOnTarget = FALSE ;
if ( angles . x > 180.0f )
angles . x - = 360.0f ;
if ( angles . x < - 180.0f )
angles . x + = 360.0f ;
if ( angles . y > 180.0f )
angles . y - = 360.0f ;
if ( angles . y < - 180.0f )
angles . y + = 360.0f ;
if ( angles . x > 25.0f )
angles . x = 25.0f ;
if ( angles . x < - 25.0f )
angles . x = - 25.0f ;
if ( angles . y > 12.0f )
angles . y = 12.0f ;
if ( angles . y < - 12.0f )
angles . y = - 12.0f ;
if ( g_iSkillLevel = = SKILL_EASY )
m_vecAutoAim = m_vecAutoAim * 0.67f + angles * 0.33f ;
else
m_vecAutoAim = angles * 0.9f ;
2016-12-06 22:21:52 +03:00
if ( g_psv_aim & & g_psv_aim - > value > 0.0f )
2015-09-30 03:49:22 +03:00
{
if ( m_vecAutoAim . x ! = m_lastx | | m_vecAutoAim . y ! = m_lasty )
{
SET_CROSSHAIRANGLE ( ENT ( pev ) , - m_vecAutoAim . x , m_vecAutoAim . y ) ;
m_lastx = m_vecAutoAim . x ;
m_lasty = m_vecAutoAim . y ;
}
}
UTIL_MakeVectors ( pev - > v_angle + pev - > punchangle + m_vecAutoAim ) ;
return gpGlobals - > v_forward ;
}
Vector CBasePlayer : : AutoaimDeflection ( Vector & vecSrc , float flDist , float flDelta )
{
m_fOnTarget = FALSE ;
return g_vecZero ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : ResetAutoaim ( )
2015-09-30 03:49:22 +03:00
{
if ( m_vecAutoAim . x ! = 0.0f | | m_vecAutoAim . y ! = 0.0f )
{
m_vecAutoAim = Vector ( 0 , 0 , 0 ) ;
SET_CROSSHAIRANGLE ( ENT ( pev ) , 0 , 0 ) ;
}
m_fOnTarget = FALSE ;
}
// UNDONE: Determine real frame limit, 8 is a placeholder.
// Note: -1 means no custom frames present.
void CBasePlayer : : SetCustomDecalFrames ( int nFrames )
{
if ( nFrames > 0 & & nFrames < 8 )
m_nCustomSprayFrames = nFrames ;
else
m_nCustomSprayFrames = - 1 ;
}
// Returns the # of custom frames this player's custom clan logo contains.
2016-02-04 03:18:26 +03:00
int CBasePlayer : : GetCustomDecalFrames ( )
2015-09-30 03:49:22 +03:00
{
return m_nCustomSprayFrames ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , Blind , ( float duration , float holdTime , float fadeTime , int alpha ) , duration , holdTime , fadeTime , alpha )
2016-04-05 03:12:05 +03:00
2017-07-01 23:40:10 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( Blind ) ( float duration , float holdTime , float fadeTime , int alpha )
2015-09-30 03:49:22 +03:00
{
m_blindUntilTime = gpGlobals - > time + duration ;
m_blindStartTime = gpGlobals - > time ;
m_blindHoldTime = holdTime ;
m_blindFadeTime = fadeTime ;
m_blindAlpha = alpha ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : InitStatusBar ( )
2015-09-30 03:49:22 +03:00
{
m_flStatusBarDisappearDelay = 0.0f ;
m_SbarString0 [ 0 ] = ' \0 ' ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : UpdateStatusBar ( )
2015-09-30 03:49:22 +03:00
{
2017-10-12 17:50:56 +03:00
int newSBarState [ SBAR_END ] ;
char sbuf0 [ MAX_SBAR_STRING ] ;
2015-09-30 03:49:22 +03:00
Q_memset ( newSBarState , 0 , sizeof ( newSBarState ) ) ;
Q_strcpy ( sbuf0 , m_SbarString0 ) ;
// Find an ID Target
TraceResult tr ;
UTIL_MakeVectors ( pev - > v_angle + pev - > punchangle ) ;
Vector vecSrc = EyePosition ( ) ;
2017-10-12 17:50:56 +03:00
Vector vecEnd = vecSrc + ( gpGlobals - > v_forward * ( ( pev - > flags & FL_SPECTATOR ) ! = 0 ? MAX_SPEC_ID_RANGE : MAX_ID_RANGE ) ) ;
2015-09-30 03:49:22 +03:00
UTIL_TraceLine ( vecSrc , vecEnd , dont_ignore_monsters , edict ( ) , & tr ) ;
if ( tr . flFraction ! = 1.0f )
{
if ( ! FNullEnt ( tr . pHit ) )
{
CBaseEntity * pEntity = CBaseEntity : : Instance ( tr . pHit ) ;
2017-10-13 03:04:37 +03:00
bool isVisiblePlayer = ( ( TheBots = = nullptr | | ! TheBots - > IsLineBlockedBySmoke ( & pev - > origin , & pEntity - > pev - > origin ) ) & & pEntity - > Classify ( ) = = CLASS_PLAYER ) ;
2015-09-30 03:49:22 +03:00
if ( gpGlobals - > time > = m_blindUntilTime & & isVisiblePlayer )
{
CBasePlayer * pTarget = ( CBasePlayer * ) pEntity ;
2021-04-12 15:55:03 +03:00
bool sameTeam = g_pGameRules - > PlayerRelationship ( this , pTarget ) = = GR_TEAMMATE ;
2019-10-09 13:09:23 +03:00
2017-10-19 20:12:02 +03:00
newSBarState [ SBAR_ID_TARGETNAME ] = ENTINDEX ( pTarget - > edict ( ) ) ;
2019-10-09 13:09:23 +03:00
newSBarState [ SBAR_ID_TARGETTYPE ] = sameTeam ? SBAR_TARGETTYPE_TEAMMATE : SBAR_TARGETTYPE_ENEMY ;
2015-09-30 03:49:22 +03:00
2019-10-09 13:09:23 +03:00
if ( sameTeam | | GetObserverMode ( ) ! = OBS_NONE )
2015-09-30 03:49:22 +03:00
{
2018-02-08 12:37:02 +03:00
if ( playerid . value ! = PLAYERID_MODE_OFF | | GetObserverMode ( ) ! = OBS_NONE )
2015-09-30 03:49:22 +03:00
Q_strcpy ( sbuf0 , " 1 %c1: %p2 \n 2 %h: %i3%% " ) ;
else
Q_strcpy ( sbuf0 , " " ) ;
2017-10-19 20:12:02 +03:00
newSBarState [ SBAR_ID_TARGETHEALTH ] = int ( ( pEntity - > pev - > health / pEntity - > pev - > max_health ) * 100 ) ;
2015-09-30 03:49:22 +03:00
if ( ! ( m_flDisplayHistory & DHF_FRIEND_SEEN ) & & ! ( pev - > flags & FL_SPECTATOR ) )
{
m_flDisplayHistory | = DHF_FRIEND_SEEN ;
HintMessage ( " #Hint_spotted_a_friend " ) ;
}
}
2018-02-08 12:37:02 +03:00
else if ( GetObserverMode ( ) = = OBS_NONE )
2015-09-30 03:49:22 +03:00
{
if ( playerid . value ! = PLAYERID_MODE_TEAMONLY & & playerid . value ! = PLAYERID_MODE_OFF )
Q_strcpy ( sbuf0 , " 1 %c1: %p2 " ) ;
else
Q_strcpy ( sbuf0 , " " ) ;
if ( ! ( m_flDisplayHistory & DHF_ENEMY_SEEN ) )
{
m_flDisplayHistory | = DHF_ENEMY_SEEN ;
HintMessage ( " #Hint_spotted_an_enemy " ) ;
}
}
m_flStatusBarDisappearDelay = gpGlobals - > time + 2.0f ;
}
else if ( pEntity - > Classify ( ) = = CLASS_HUMAN_PASSIVE )
{
2018-02-08 12:37:02 +03:00
if ( playerid . value ! = PLAYERID_MODE_OFF | | GetObserverMode ( ) ! = OBS_NONE )
2015-09-30 03:49:22 +03:00
Q_strcpy ( sbuf0 , " 1 %c1 %h: %i3%% " ) ;
else
Q_strcpy ( sbuf0 , " " ) ;
2017-10-19 20:12:02 +03:00
newSBarState [ SBAR_ID_TARGETTYPE ] = SBAR_TARGETTYPE_HOSTAGE ;
newSBarState [ SBAR_ID_TARGETHEALTH ] = int ( ( pEntity - > pev - > health / pEntity - > pev - > max_health ) * 100 ) ;
2015-09-30 03:49:22 +03:00
if ( ! ( m_flDisplayHistory & DHF_HOSTAGE_SEEN_FAR ) & & tr . flFraction > 0.1f )
{
m_flDisplayHistory | = DHF_HOSTAGE_SEEN_FAR ;
if ( m_iTeam = = TERRORIST )
HintMessage ( " #Hint_prevent_hostage_rescue " , TRUE ) ;
else if ( m_iTeam = = CT )
HintMessage ( " #Hint_rescue_the_hostages " , TRUE ) ;
}
else if ( m_iTeam = = CT & & ! ( m_flDisplayHistory & DHF_HOSTAGE_SEEN_NEAR ) & & tr . flFraction < = 0.1f )
{
m_flDisplayHistory | = ( DHF_HOSTAGE_SEEN_NEAR | DHF_HOSTAGE_SEEN_FAR ) ;
HintMessage ( " #Hint_press_use_so_hostage_will_follow " ) ;
}
m_flStatusBarDisappearDelay = gpGlobals - > time + 2.0f ;
}
}
}
else if ( m_flStatusBarDisappearDelay > gpGlobals - > time )
{
// hold the values for a short amount of time after viewing the object
2017-10-19 20:12:02 +03:00
newSBarState [ SBAR_ID_TARGETTYPE ] = m_izSBarState [ SBAR_ID_TARGETTYPE ] ;
newSBarState [ SBAR_ID_TARGETNAME ] = m_izSBarState [ SBAR_ID_TARGETNAME ] ;
newSBarState [ SBAR_ID_TARGETHEALTH ] = m_izSBarState [ SBAR_ID_TARGETHEALTH ] ;
2015-09-30 03:49:22 +03:00
}
2016-02-23 02:13:52 +03:00
bool bForceResend = false ;
2015-09-30 03:49:22 +03:00
2016-02-23 02:13:52 +03:00
if ( Q_strcmp ( sbuf0 , m_SbarString0 ) ! = 0 )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusText , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( 0 ) ;
WRITE_STRING ( sbuf0 ) ;
MESSAGE_END ( ) ;
Q_strcpy ( m_SbarString0 , sbuf0 ) ;
// make sure everything's resent
2016-02-23 02:13:52 +03:00
bForceResend = true ;
2015-09-30 03:49:22 +03:00
}
// Check values and send if they don't match
2017-10-13 03:04:37 +03:00
for ( int i = 1 ; i < SBAR_END ; i + + )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
if ( newSBarState [ i ] ! = m_izSBarState [ i ] | | bForceResend )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusValue , nullptr , pev ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( i ) ;
2017-10-13 03:04:37 +03:00
WRITE_SHORT ( newSBarState [ i ] ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
2017-10-13 03:04:37 +03:00
m_izSBarState [ i ] = newSBarState [ i ] ;
2015-09-30 03:49:22 +03:00
}
}
}
2017-10-12 17:50:56 +03:00
LINK_HOOK_CLASS_CHAIN ( CBaseEntity * , CBasePlayer , DropPlayerItem , ( const char * pszItemName ) , pszItemName )
2016-06-20 10:05:47 +03:00
2016-07-14 17:12:17 +03:00
// DropPlayerItem - drop the named item, or if no name, the active item.
2017-10-12 17:50:56 +03:00
CBaseEntity * EXT_FUNC CBasePlayer : : __API_HOOK ( DropPlayerItem ) ( const char * pszItemName )
2015-09-30 03:49:22 +03:00
{
if ( ! Q_strlen ( pszItemName ) )
{
// if this string has no length, the client didn't type a name!
// assume player wants to drop the active item.
// make the string null to make future operations in this function easier
2017-10-13 03:04:37 +03:00
pszItemName = nullptr ;
2015-09-30 03:49:22 +03:00
}
if ( m_bIsVIP )
{
ClientPrint ( pev , HUD_PRINTCENTER , " #Weapon_Cannot_Be_Dropped " ) ;
2017-10-12 17:50:56 +03:00
return nullptr ;
2015-09-30 03:49:22 +03:00
}
else if ( ! pszItemName & & HasShield ( ) )
{
DropShield ( ) ;
2017-10-12 17:50:56 +03:00
return nullptr ;
2015-09-30 03:49:22 +03:00
}
2016-10-07 15:19:51 +03:00
# ifndef REGAMEDLL_FIXES
2017-10-13 03:04:37 +03:00
CBasePlayerItem * pWeapon = nullptr ;
for ( int i = 0 ; i < MAX_ITEM_TYPES ; i + + )
2015-09-30 03:49:22 +03:00
{
2016-10-07 15:19:51 +03:00
pWeapon = m_rgpPlayerItems [ i ] ;
2016-07-14 17:12:17 +03:00
while ( pWeapon )
2015-09-30 03:49:22 +03:00
{
if ( pszItemName )
{
2016-10-07 15:19:51 +03:00
if ( FClassnameIs ( pWeapon - > pev , pszItemName ) )
2015-09-30 03:49:22 +03:00
break ;
}
else
{
if ( pWeapon = = m_pActiveItem )
break ;
}
pWeapon = pWeapon - > m_pNext ;
}
if ( pWeapon )
2016-10-07 15:19:51 +03:00
break ;
}
# else
auto pWeapon = pszItemName ? GetItemByName ( pszItemName ) : m_pActiveItem ;
# endif
if ( pWeapon )
{
if ( ! pWeapon - > CanDrop ( ) )
2015-09-30 03:49:22 +03:00
{
2016-10-07 15:19:51 +03:00
ClientPrint ( pev , HUD_PRINTCENTER , " #Weapon_Cannot_Be_Dropped " ) ;
2017-10-12 17:50:56 +03:00
return nullptr ;
2016-10-07 15:19:51 +03:00
}
2015-09-30 03:49:22 +03:00
2016-10-07 15:19:51 +03:00
// take item off hud
pev - > weapons & = ~ ( 1 < < pWeapon - > m_iId ) ;
2019-10-09 13:18:42 +03:00
# ifdef REGAMEDLL_FIXES
// No more weapon
if ( ( pev - > weapons & ~ ( 1 < < WEAPON_SUIT ) ) = = 0 ) {
m_iHideHUD | = HIDEHUD_WEAPONS ;
}
# endif
2016-10-07 15:19:51 +03:00
g_pGameRules - > GetNextBestWeapon ( this , pWeapon ) ;
UTIL_MakeVectors ( pev - > angles ) ;
2015-09-30 03:49:22 +03:00
2023-10-11 01:03:48 +03:00
# ifndef REGAMEDLL_FIXES
2016-10-07 15:19:51 +03:00
if ( pWeapon - > iItemSlot ( ) = = PRIMARY_WEAPON_SLOT )
2023-10-11 01:03:48 +03:00
m_bHasPrimary = false ; // I may have more than just 1 primary weapon :)
# endif
2015-09-30 03:49:22 +03:00
2016-10-07 15:19:51 +03:00
if ( FClassnameIs ( pWeapon - > pev , " weapon_c4 " ) )
{
m_bHasC4 = false ;
pev - > body = 0 ;
SetBombIcon ( FALSE ) ;
pWeapon - > m_pPlayer - > SetProgressBarTime ( 0 ) ;
if ( ! CSGameRules ( ) - > m_flRestartRoundTime )
2015-09-30 03:49:22 +03:00
{
2016-10-07 15:19:51 +03:00
UTIL_LogPrintf ( " \" %s<%i><%s><TERRORIST> \" triggered \" Dropped_The_Bomb \" \n " , STRING ( pev - > netname ) , GETPLAYERUSERID ( edict ( ) ) , GETPLAYERAUTHID ( edict ( ) ) ) ;
g_pGameRules - > m_bBombDropped = TRUE ;
2015-09-30 03:49:22 +03:00
2017-10-13 03:04:37 +03:00
CBaseEntity * pEntity = nullptr ;
2016-12-06 22:21:52 +03:00
while ( ( pEntity = UTIL_FindEntityByClassname ( pEntity , " player " ) ) )
2015-09-30 03:49:22 +03:00
{
2016-10-07 15:19:51 +03:00
if ( FNullEnt ( pEntity - > edict ( ) ) )
break ;
2015-09-30 03:49:22 +03:00
2016-10-07 15:19:51 +03:00
if ( ! pEntity - > IsPlayer ( ) )
continue ;
2015-09-30 03:49:22 +03:00
2016-10-07 15:19:51 +03:00
if ( pEntity - > pev - > flags ! = FL_DORMANT )
{
CBasePlayer * pOther = GetClassPtr < CCSPlayer > ( ( CBasePlayer * ) pEntity - > pev ) ;
2015-09-30 03:49:22 +03:00
2016-10-07 15:19:51 +03:00
if ( pOther - > pev - > deadflag = = DEAD_NO & & pOther - > m_iTeam = = TERRORIST )
2015-09-30 03:49:22 +03:00
{
2016-10-07 15:19:51 +03:00
ClientPrint ( pOther - > pev , HUD_PRINTCENTER , " #Game_bomb_drop " , STRING ( pev - > netname ) ) ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBombDrop , nullptr , pOther - > pev ) ;
2016-10-07 15:19:51 +03:00
WRITE_COORD ( pev - > origin . x ) ;
WRITE_COORD ( pev - > origin . y ) ;
WRITE_COORD ( pev - > origin . z ) ;
2016-12-06 22:21:52 +03:00
WRITE_BYTE ( BOMB_FLAG_DROPPED ) ;
2016-10-07 15:19:51 +03:00
MESSAGE_END ( ) ;
2015-09-30 03:49:22 +03:00
}
}
}
}
2016-10-07 15:19:51 +03:00
}
2020-03-27 05:17:41 +03:00
const char * modelname = GetCSModelName ( pWeapon - > m_iId ) ;
2020-04-02 13:39:29 +03:00
Vector vecOrigin = pev - > origin + gpGlobals - > v_forward * 10 ;
Vector vecAngles = pev - > angles ;
Vector vecVelocity = gpGlobals - > v_forward * 300 + gpGlobals - > v_forward * 100 ;
2023-07-10 15:45:24 +03:00
bool bPackAmmo = false ;
# ifdef REGAMEDLL_ADD
if ( ammodrop . value > = 2.0f )
bPackAmmo = true ;
# endif
2020-04-02 13:39:29 +03:00
CWeaponBox * pWeaponBox = CreateWeaponBox ( pWeapon , this ,
modelname ,
vecOrigin ,
vecAngles ,
vecVelocity ,
CGameRules : : GetItemKillDelay ( ) ,
2023-07-10 15:45:24 +03:00
bPackAmmo
) ;
2020-04-02 13:39:29 +03:00
2020-03-27 05:17:41 +03:00
if ( ! pWeaponBox )
{
return nullptr ;
}
2015-09-30 03:49:22 +03:00
2023-10-11 01:03:48 +03:00
# ifdef REGAMEDLL_FIXES
if ( ! m_rgpPlayerItems [ PRIMARY_WEAPON_SLOT ] ) {
m_bHasPrimary = false ; // ensure value assignation on successful weapon removal
}
# endif
2016-10-07 15:19:51 +03:00
if ( FClassnameIs ( pWeapon - > pev , " weapon_c4 " ) )
{
pWeaponBox - > m_bIsBomb = true ;
pWeaponBox - > SetThink ( & CWeaponBox : : BombThink ) ;
pWeaponBox - > pev - > nextthink = gpGlobals - > time + 1.0f ;
2015-09-30 03:49:22 +03:00
2016-12-06 22:21:52 +03:00
if ( TheCSBots ( ) )
2015-09-30 03:49:22 +03:00
{
2016-10-07 15:19:51 +03:00
// tell the bots about the dropped bomb
TheCSBots ( ) - > SetLooseBomb ( pWeaponBox ) ;
TheCSBots ( ) - > OnEvent ( EVENT_BOMB_DROPPED ) ;
2015-09-30 03:49:22 +03:00
}
2016-10-07 15:19:51 +03:00
}
2015-09-30 03:49:22 +03:00
2017-10-12 17:50:56 +03:00
return pWeaponBox ;
2015-09-30 03:49:22 +03:00
}
2017-10-12 17:50:56 +03:00
return nullptr ;
2015-09-30 03:49:22 +03:00
}
2016-07-14 17:12:17 +03:00
// Does the player already have this item?
bool CBasePlayer : : HasPlayerItem ( CBasePlayerItem * pCheckItem )
2015-09-30 03:49:22 +03:00
{
2017-10-19 20:12:02 +03:00
auto item = m_rgpPlayerItems [ pCheckItem - > iItemSlot ( ) ] ;
2016-07-14 17:12:17 +03:00
while ( item )
2015-09-30 03:49:22 +03:00
{
2016-07-14 17:12:17 +03:00
if ( FClassnameIs ( item - > pev , STRING ( pCheckItem - > pev - > classname ) ) )
return true ;
2015-09-30 03:49:22 +03:00
2016-07-14 17:12:17 +03:00
item = item - > m_pNext ;
2015-09-30 03:49:22 +03:00
}
2016-02-23 02:13:52 +03:00
2016-07-14 17:12:17 +03:00
return false ;
2015-09-30 03:49:22 +03:00
}
2016-07-14 17:12:17 +03:00
// Does the player already have this item?
bool CBasePlayer : : HasNamedPlayerItem ( const char * pszItemName )
2015-09-30 03:49:22 +03:00
{
2016-07-14 17:12:17 +03:00
for ( auto item : m_rgpPlayerItems )
2015-09-30 03:49:22 +03:00
{
2016-07-14 17:12:17 +03:00
while ( item )
2015-09-30 03:49:22 +03:00
{
2016-07-14 17:12:17 +03:00
if ( FClassnameIs ( item - > pev , pszItemName ) )
return true ;
2015-09-30 03:49:22 +03:00
2016-07-14 17:12:17 +03:00
item = item - > m_pNext ;
2015-09-30 03:49:22 +03:00
}
}
2016-07-14 17:12:17 +03:00
return false ;
2015-09-30 03:49:22 +03:00
}
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , SwitchTeam )
void CBasePlayer : : __API_HOOK ( SwitchTeam ) ( )
2015-09-30 03:49:22 +03:00
{
int oldTeam ;
char * szOldTeam ;
char * szNewTeam ;
const char * szName ;
2016-05-30 14:19:56 +03:00
char * szNewModel = nullptr ;
2015-09-30 03:49:22 +03:00
oldTeam = m_iTeam ;
if ( m_iTeam = = CT )
{
m_iTeam = TERRORIST ;
switch ( m_iModelName )
{
case MODEL_URBAN :
m_iModelName = MODEL_LEET ;
2016-05-30 14:19:56 +03:00
szNewModel = " leet " ;
2015-09-30 03:49:22 +03:00
break ;
case MODEL_GIGN :
m_iModelName = MODEL_GUERILLA ;
2016-05-30 14:19:56 +03:00
szNewModel = " guerilla " ;
2015-09-30 03:49:22 +03:00
break ;
case MODEL_SAS :
m_iModelName = MODEL_ARCTIC ;
2016-05-30 14:19:56 +03:00
szNewModel = " arctic " ;
2015-09-30 03:49:22 +03:00
break ;
case MODEL_SPETSNAZ :
2017-10-12 17:50:56 +03:00
if ( AreRunningCZero ( ) )
2015-09-30 03:49:22 +03:00
{
m_iModelName = MODEL_MILITIA ;
2016-05-30 14:19:56 +03:00
szNewModel = " militia " ;
2015-09-30 03:49:22 +03:00
break ;
}
default :
if ( m_iModelName = = MODEL_GSG9 | | ! IsBot ( ) | | ! TheBotProfiles - > GetCustomSkinModelname ( m_iModelName ) )
{
m_iModelName = MODEL_TERROR ;
2016-05-30 14:19:56 +03:00
szNewModel = " terror " ;
2015-09-30 03:49:22 +03:00
}
break ;
}
}
else if ( m_iTeam = = TERRORIST )
{
m_iTeam = CT ;
switch ( m_iModelName )
{
case MODEL_TERROR :
m_iModelName = MODEL_GSG9 ;
2016-05-30 14:19:56 +03:00
szNewModel = " gsg9 " ;
2015-09-30 03:49:22 +03:00
break ;
case MODEL_ARCTIC :
m_iModelName = MODEL_SAS ;
2016-05-30 14:19:56 +03:00
szNewModel = " sas " ;
2015-09-30 03:49:22 +03:00
break ;
case MODEL_GUERILLA :
m_iModelName = MODEL_GIGN ;
2016-05-30 14:19:56 +03:00
szNewModel = " gign " ;
2015-09-30 03:49:22 +03:00
break ;
case MODEL_MILITIA :
2017-10-12 17:50:56 +03:00
if ( AreRunningCZero ( ) )
2015-09-30 03:49:22 +03:00
{
m_iModelName = MODEL_SPETSNAZ ;
2016-05-30 14:19:56 +03:00
szNewModel = " spetsnaz " ;
2015-09-30 03:49:22 +03:00
break ;
}
default :
if ( m_iModelName = = MODEL_LEET | | ! IsBot ( ) | | ! TheBotProfiles - > GetCustomSkinModelname ( m_iModelName ) )
{
m_iModelName = MODEL_URBAN ;
2016-05-30 14:19:56 +03:00
szNewModel = " urban " ;
2015-09-30 03:49:22 +03:00
}
break ;
}
}
2016-05-30 14:19:56 +03:00
SetClientUserInfoModel ( GET_INFO_BUFFER ( edict ( ) ) , szNewModel ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_BEGIN ( MSG_ALL , gmsgTeamInfo ) ;
2015-12-18 19:32:50 +03:00
WRITE_BYTE ( entindex ( ) ) ;
2016-05-04 00:53:03 +03:00
WRITE_STRING ( GetTeamName ( m_iTeam ) ) ;
2015-09-30 03:49:22 +03:00
MESSAGE_END ( ) ;
2016-12-06 22:21:52 +03:00
if ( TheBots )
2015-12-05 22:40:30 +03:00
{
TheBots - > OnEvent ( EVENT_PLAYER_CHANGED_TEAM , this ) ;
}
2015-09-30 03:49:22 +03:00
UpdateLocation ( true ) ;
if ( m_iTeam )
{
SetScoreboardAttributes ( ) ;
}
if ( pev - > netname )
{
szName = STRING ( pev - > netname ) ;
if ( ! szName [ 0 ] )
szName = " <unconnected> " ;
}
else
szName = " <unconnected> " ;
UTIL_ClientPrintAll ( HUD_PRINTNOTIFY , ( m_iTeam = = TERRORIST ) ? " #Game_join_terrorist_auto " : " #Game_join_ct_auto " , szName ) ;
if ( m_bHasDefuser )
{
2019-06-21 23:19:32 +03:00
RemoveDefuser ( ) ;
2015-09-30 03:49:22 +03:00
2019-10-09 13:18:42 +03:00
# ifndef REGAMEDLL_FIXES
// NOTE: unreachable code - Vaqtincha
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < MAX_ITEM_TYPES ; i + + )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
m_pActiveItem = m_rgpPlayerItems [ i ] ;
2015-09-30 03:49:22 +03:00
if ( m_pActiveItem & & FClassnameIs ( m_pActiveItem - > pev , " item_thighpack " ) )
{
m_pActiveItem - > Drop ( ) ;
2017-10-13 03:04:37 +03:00
m_rgpPlayerItems [ i ] = nullptr ;
2015-09-30 03:49:22 +03:00
}
}
2019-10-09 13:18:42 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
szOldTeam = GetTeam ( oldTeam ) ;
szNewTeam = GetTeam ( m_iTeam ) ;
2016-02-23 02:13:52 +03:00
UTIL_LogPrintf ( " \" %s<%i><%s><%s> \" joined team \" %s \" (auto) \n " , STRING ( pev - > netname ) , GETPLAYERUSERID ( edict ( ) ) , GETPLAYERAUTHID ( edict ( ) ) , szOldTeam , szNewTeam ) ;
2015-09-30 03:49:22 +03:00
2016-01-25 20:02:57 +03:00
CCSBot * pBot = static_cast < CCSBot * > ( this ) ;
2015-09-30 03:49:22 +03:00
if ( pBot - > IsBot ( ) )
{
const BotProfile * pProfile = pBot - > GetProfile ( ) ;
2016-12-06 22:21:52 +03:00
if ( pProfile )
2015-09-30 03:49:22 +03:00
{
2016-02-23 02:13:52 +03:00
bool bKick = false ;
2015-09-30 03:49:22 +03:00
if ( m_iTeam = = CT & & ! pProfile - > IsValidForTeam ( BOT_TEAM_CT ) )
2016-02-23 02:13:52 +03:00
bKick = true ;
2015-09-30 03:49:22 +03:00
else if ( m_iTeam = = TERRORIST & & ! pProfile - > IsValidForTeam ( BOT_TEAM_T ) )
2016-02-23 02:13:52 +03:00
bKick = true ;
2015-09-30 03:49:22 +03:00
2016-02-23 02:13:52 +03:00
if ( bKick )
2015-09-30 03:49:22 +03:00
{
SERVER_COMMAND ( UTIL_VarArgs ( " kick \" %s \" \n " , STRING ( pev - > netname ) ) ) ;
}
}
}
2021-10-14 13:54:09 +03:00
# ifdef REGAMEDLL_FIXES
// Initialize the player counts now that a player has switched teams
int NumDeadCT , NumDeadTerrorist , NumAliveTerrorist , NumAliveCT ;
CSGameRules ( ) - > InitializePlayerCounts ( NumAliveTerrorist , NumAliveCT , NumDeadTerrorist , NumDeadCT ) ;
# endif
2015-09-30 03:49:22 +03:00
}
void CBasePlayer : : UpdateShieldCrosshair ( bool draw )
{
if ( draw )
m_iHideHUD & = ~ HIDEHUD_CROSSHAIR ;
else
m_iHideHUD | = HIDEHUD_CROSSHAIR ;
}
BOOL CBasePlayer : : SwitchWeapon ( CBasePlayerItem * pWeapon )
{
if ( ! pWeapon - > CanDeploy ( ) )
{
return FALSE ;
}
ResetAutoaim ( ) ;
2016-10-05 18:27:50 +03:00
if ( m_pActiveItem )
2015-09-30 03:49:22 +03:00
{
m_pActiveItem - > Holster ( ) ;
}
CBasePlayerItem * pTemp = m_pActiveItem ;
m_pActiveItem = pWeapon ;
m_pLastItem = pTemp ;
2016-10-05 18:27:50 +03:00
2015-09-30 03:49:22 +03:00
pWeapon - > Deploy ( ) ;
2016-10-05 18:27:50 +03:00
if ( pWeapon - > m_pPlayer )
2015-09-30 03:49:22 +03:00
{
pWeapon - > m_pPlayer - > ResetMaxSpeed ( ) ;
}
if ( HasShield ( ) )
{
UpdateShieldCrosshair ( true ) ;
}
return TRUE ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : TabulateAmmo ( )
2015-09-30 03:49:22 +03:00
{
ammo_buckshot = AmmoInventory ( GetAmmoIndex ( " buckshot " ) ) ;
ammo_9mm = AmmoInventory ( GetAmmoIndex ( " 9mm " ) ) ;
ammo_556nato = AmmoInventory ( GetAmmoIndex ( " 556Nato " ) ) ;
ammo_556natobox = AmmoInventory ( GetAmmoIndex ( " 556NatoBox " ) ) ;
ammo_762nato = AmmoInventory ( GetAmmoIndex ( " 762Nato " ) ) ;
ammo_45acp = AmmoInventory ( GetAmmoIndex ( " 45acp " ) ) ;
ammo_50ae = AmmoInventory ( GetAmmoIndex ( " 50AE " ) ) ;
ammo_338mag = AmmoInventory ( GetAmmoIndex ( " 338Magnum " ) ) ;
ammo_57mm = AmmoInventory ( GetAmmoIndex ( " 57mm " ) ) ;
ammo_357sig = AmmoInventory ( GetAmmoIndex ( " 357SIG " ) ) ;
}
2017-01-29 02:56:29 +03:00
LINK_ENTITY_TO_CLASS ( monster_hevsuit_dead , CDeadHEV , CCSDeadHEV )
2015-09-30 03:49:22 +03:00
2017-07-01 23:40:10 +03:00
void CDeadHEV : : Spawn ( )
2015-09-30 03:49:22 +03:00
{
PRECACHE_MODEL ( " models/player.mdl " ) ;
SET_MODEL ( ENT ( pev ) , " models/player.mdl " ) ;
pev - > effects = 0 ;
pev - > yaw_speed = 8.0f ;
pev - > sequence = 0 ;
pev - > body = 1 ;
m_bloodColor = BLOOD_COLOR_RED ;
2017-10-19 20:12:02 +03:00
pev - > sequence = LookupSequence ( m_szPoses [ m_iPose ] ) ;
2015-09-30 03:49:22 +03:00
if ( pev - > sequence = = - 1 )
{
ALERT ( at_console , " Dead hevsuit with bad pose \n " ) ;
pev - > sequence = 0 ;
pev - > effects = EF_BRIGHTFIELD ;
}
2016-07-14 17:12:17 +03:00
// Corpses have less health
2015-09-30 03:49:22 +03:00
pev - > health = 8 ;
MonsterInitDead ( ) ;
}
2017-10-19 20:12:02 +03:00
void CDeadHEV : : KeyValue ( KeyValueData * pkvd )
{
if ( FStrEq ( pkvd - > szKeyName , " pose " ) )
{
m_iPose = Q_atoi ( pkvd - > szValue ) ;
pkvd - > fHandled = TRUE ;
}
else
{
CBaseMonster : : KeyValue ( pkvd ) ;
}
}
2017-01-29 02:56:29 +03:00
LINK_ENTITY_TO_CLASS ( player_weaponstrip , CStripWeapons , CCSStripWeapons )
2015-09-30 03:49:22 +03:00
2021-06-06 15:17:07 +03:00
void CStripWeapons : : KeyValue ( KeyValueData * pkvd )
{
# ifdef REGAMEDLL_ADD
if ( FStrEq ( pkvd - > szKeyName , " primary " ) & & Q_atoi ( pkvd - > szValue ) > 0 )
{
m_bitsIgnoreSlots | = ( 1 < < PRIMARY_WEAPON_SLOT ) ;
pkvd - > fHandled = TRUE ;
}
else if ( FStrEq ( pkvd - > szKeyName , " secondary " ) & & Q_atoi ( pkvd - > szValue ) > 0 )
{
m_bitsIgnoreSlots | = ( 1 < < PISTOL_SLOT ) ;
pkvd - > fHandled = TRUE ;
}
else if ( FStrEq ( pkvd - > szKeyName , " knife " ) & & Q_atoi ( pkvd - > szValue ) > 0 )
{
m_bitsIgnoreSlots | = ( 1 < < KNIFE_SLOT ) ;
pkvd - > fHandled = TRUE ;
}
else if ( FStrEq ( pkvd - > szKeyName , " grenade " ) & & Q_atoi ( pkvd - > szValue ) > 0 )
{
m_bitsIgnoreSlots | = ( 1 < < GRENADE_SLOT ) ;
pkvd - > fHandled = TRUE ;
}
else if ( FStrEq ( pkvd - > szKeyName , " bomb " ) & & Q_atoi ( pkvd - > szValue ) > 0 )
{
m_bitsIgnoreSlots | = ( 1 < < C4_SLOT ) ;
pkvd - > fHandled = TRUE ;
}
else if ( FStrEq ( pkvd - > szKeyName , " items " ) & & Q_atoi ( pkvd - > szValue ) > 0 )
{
m_bitsIgnoreSlots | = ( 1 < < ALL_OTHER_ITEMS ) ;
pkvd - > fHandled = TRUE ;
}
else if ( FStrEq ( pkvd - > szKeyName , " special " ) )
{
m_iszSpecialItem = ALLOC_STRING ( pkvd - > szValue ) ;
}
else
# endif
{
CPointEntity : : KeyValue ( pkvd ) ;
}
}
2017-07-01 23:40:10 +03:00
void CStripWeapons : : Use ( CBaseEntity * pActivator , CBaseEntity * pCaller , USE_TYPE useType , float value )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
CBasePlayer * pPlayer = nullptr ;
2016-12-06 22:21:52 +03:00
if ( pActivator & & pActivator - > IsPlayer ( ) )
2015-09-30 03:49:22 +03:00
{
pPlayer = ( CBasePlayer * ) pActivator ;
}
else if ( ! g_pGameRules - > IsDeathmatch ( ) )
{
pPlayer = ( CBasePlayer * ) Instance ( INDEXENT ( 1 ) ) ;
}
2016-12-06 22:21:52 +03:00
if ( pPlayer )
2015-09-30 03:49:22 +03:00
{
2021-06-06 15:17:07 +03:00
# ifdef REGAMEDLL_ADD
if ( m_bitsIgnoreSlots ! = 0 | | m_iszSpecialItem )
{
if ( m_iszSpecialItem )
{
2022-04-16 15:11:13 +03:00
const char * weaponName = STRING ( m_iszSpecialItem ) ;
WeaponSlotInfo * slotInfo = GetWeaponSlot ( weaponName ) ;
if ( slotInfo ! = nullptr & & slotInfo - > slot = = GRENADE_SLOT )
pPlayer - > CSPlayer ( ) - > RemovePlayerItemEx ( weaponName , true ) ;
else
pPlayer - > CSPlayer ( ) - > RemovePlayerItem ( weaponName ) ;
2021-06-06 15:17:07 +03:00
}
for ( int slot = PRIMARY_WEAPON_SLOT ; slot < = ALL_OTHER_ITEMS ; slot + + )
{
if ( m_bitsIgnoreSlots & ( 1 < < slot ) )
continue ;
if ( slot = = ALL_OTHER_ITEMS )
{
pPlayer - > CSPlayer ( ) - > RemovePlayerItem ( " item_longjump " ) ;
pPlayer - > CSPlayer ( ) - > RemovePlayerItem ( " item_assaultsuit " ) ;
pPlayer - > CSPlayer ( ) - > RemovePlayerItem ( " item_kevlar " ) ;
pPlayer - > CSPlayer ( ) - > RemovePlayerItem ( " item_thighpack " ) ;
pPlayer - > CSPlayer ( ) - > RemovePlayerItem ( " weapon_shield " ) ;
}
else
{
pPlayer - > ForEachItem ( slot , [ pPlayer ] ( CBasePlayerItem * pItem )
{
2022-04-16 15:11:13 +03:00
if ( pItem - > iItemSlot ( ) = = GRENADE_SLOT )
pPlayer - > CSPlayer ( ) - > RemovePlayerItemEx ( STRING ( pItem - > pev - > classname ) , true ) ;
else
pPlayer - > CSPlayer ( ) - > RemovePlayerItem ( STRING ( pItem - > pev - > classname ) ) ;
2021-06-06 15:17:07 +03:00
return false ;
} ) ;
}
}
}
else
# endif
{
pPlayer - > RemoveAllItems ( FALSE ) ;
}
2015-09-30 03:49:22 +03:00
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : StudioEstimateGait ( )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
real_t dt ;
2015-09-30 03:49:22 +03:00
Vector est_velocity ;
dt = gpGlobals - > frametime ;
if ( dt < 0 )
dt = 0 ;
else if ( dt > 1.0 )
dt = 1 ;
if ( dt = = 0 )
{
m_flGaitMovement = 0 ;
return ;
}
est_velocity = pev - > origin - m_prevgaitorigin ;
m_prevgaitorigin = pev - > origin ;
m_flGaitMovement = est_velocity . Length ( ) ;
if ( dt < = 0 | | m_flGaitMovement / dt < 5 )
{
m_flGaitMovement = 0 ;
est_velocity . x = 0 ;
est_velocity . y = 0 ;
}
if ( ! est_velocity . x & & ! est_velocity . y )
{
2017-11-22 20:27:55 +03:00
real_t flYawDiff = pev - > angles . y - m_flGaityaw ;
real_t flYaw = Q_fmod ( flYawDiff , 360 ) ;
2015-09-30 03:49:22 +03:00
2016-02-23 02:13:52 +03:00
flYawDiff = flYawDiff - int64 ( flYawDiff / 360 ) * 360 ;
2015-09-30 03:49:22 +03:00
if ( flYawDiff > 180 )
flYawDiff - = 360 ;
if ( flYawDiff < - 180 )
flYawDiff + = 360 ;
if ( flYaw < - 180 )
flYaw + = 360 ;
else if ( flYaw > 180 )
flYaw - = 360 ;
if ( flYaw > - 5 & & flYaw < 5 )
2016-02-23 02:13:52 +03:00
m_flYawModifier = 0.05f ;
2015-09-30 03:49:22 +03:00
if ( flYaw < - 90 | | flYaw > 90 )
2016-02-23 02:13:52 +03:00
m_flYawModifier = 3.5f ;
2015-09-30 03:49:22 +03:00
2016-02-23 02:13:52 +03:00
if ( dt < 0.25f )
2015-09-30 03:49:22 +03:00
flYawDiff * = dt * m_flYawModifier ;
else
flYawDiff * = dt ;
2017-11-07 17:27:54 +03:00
# ifdef REGAMEDLL_FIXES
2017-11-22 20:27:55 +03:00
if ( real_t ( Q_abs ( flYawDiff ) ) < 0.1f )
2017-11-07 17:27:54 +03:00
# else
2017-11-22 20:27:55 +03:00
if ( real_t ( Q_abs ( int64 ( flYawDiff ) ) ) < 0.1f )
2017-11-07 17:27:54 +03:00
# endif
2015-09-30 03:49:22 +03:00
flYawDiff = 0 ;
m_flGaityaw + = flYawDiff ;
2016-02-23 02:13:52 +03:00
m_flGaityaw - = int64 ( m_flGaityaw / 360 ) * 360 ;
2015-09-30 03:49:22 +03:00
m_flGaitMovement = 0 ;
}
else
{
2017-11-22 20:27:55 +03:00
m_flGaityaw = ( Q_atan2 ( real_t ( est_velocity . y ) , real_t ( est_velocity . x ) ) * 180 / M_PI ) ;
2015-09-30 03:49:22 +03:00
if ( m_flGaityaw > 180 )
m_flGaityaw = 180 ;
if ( m_flGaityaw < - 180 )
m_flGaityaw = - 180 ;
}
}
void CBasePlayer : : StudioPlayerBlend ( int * pBlend , float * pPitch )
{
// calc up/down pointing
2016-02-23 02:13:52 +03:00
float range = float ( int64 ( * pPitch * 3.0f ) ) ;
2015-09-30 03:49:22 +03:00
* pBlend = range ;
if ( range < = - 45.0f )
{
* pBlend = 255 ;
* pPitch = 0 ;
}
else if ( range > = 45.0f )
{
* pBlend = 0 ;
* pPitch = 0 ;
}
else
{
2016-02-23 02:13:52 +03:00
* pBlend = int64 ( ( 45.0f - range ) * ( 255.0f / 90.0f ) ) ;
2015-09-30 03:49:22 +03:00
* pPitch = 0 ;
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : CalculatePitchBlend ( )
2015-09-30 03:49:22 +03:00
{
int iBlend ;
float temp = pev - > angles . x ;
StudioPlayerBlend ( & iBlend , & temp ) ;
pev - > blending [ 1 ] = iBlend ;
m_flPitch = iBlend ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : CalculateYawBlend ( )
2015-09-30 03:49:22 +03:00
{
float dt ;
float maxyaw = 255.0f ;
2017-11-22 20:27:55 +03:00
real_t flYaw ; // view direction relative to movement
real_t blend_yaw ;
2015-09-30 03:49:22 +03:00
dt = gpGlobals - > frametime ;
2016-02-23 02:13:52 +03:00
if ( dt < 0.0f )
2015-09-30 03:49:22 +03:00
dt = 0 ;
2016-02-23 02:13:52 +03:00
else if ( dt > 1.0f )
2015-09-30 03:49:22 +03:00
dt = 1 ;
StudioEstimateGait ( ) ;
2015-12-05 22:40:30 +03:00
// calc side to side turning
2017-11-22 20:27:55 +03:00
flYaw = Q_fmod ( real_t ( pev - > angles . y - m_flGaityaw ) , 360 ) ;
2015-09-30 03:49:22 +03:00
if ( flYaw < - 180 )
flYaw + = 360 ;
else if ( flYaw > 180 )
flYaw - = 360 ;
if ( m_flGaitMovement ! = 0.0 )
{
if ( flYaw > 120 )
{
m_flGaityaw - = 180 ;
m_flGaitMovement = - m_flGaitMovement ;
flYaw - = 180 ;
}
else if ( flYaw < - 120 )
{
m_flGaityaw + = 180 ;
m_flGaitMovement = - m_flGaitMovement ;
flYaw + = 180 ;
}
}
flYaw = ( flYaw / 90 ) * 128 + 127 ;
if ( flYaw > 255 )
flYaw = 255 ;
else if ( flYaw < 0 )
flYaw = 0 ;
blend_yaw = maxyaw - flYaw ;
2016-02-23 02:13:52 +03:00
pev - > blending [ 0 ] = int64 ( blend_yaw ) ;
2015-09-30 03:49:22 +03:00
m_flYaw = blend_yaw ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : StudioProcessGait ( )
2015-09-30 03:49:22 +03:00
{
mstudioseqdesc_t * pseqdesc ;
2017-11-22 20:27:55 +03:00
real_t dt = gpGlobals - > frametime ;
2015-09-30 03:49:22 +03:00
if ( dt < 0.0 )
dt = 0 ;
else if ( dt > 1.0 )
dt = 1 ;
CalculateYawBlend ( ) ;
CalculatePitchBlend ( ) ;
2016-02-23 02:13:52 +03:00
studiohdr_t * pstudiohdr = ( studiohdr_t * ) GET_MODEL_PTR ( edict ( ) ) ;
2015-09-30 03:49:22 +03:00
2016-02-23 02:13:52 +03:00
if ( ! pstudiohdr )
2015-09-30 03:49:22 +03:00
return ;
pseqdesc = ( mstudioseqdesc_t * ) ( ( byte * ) pstudiohdr + pstudiohdr - > seqindex ) + pev - > gaitsequence ;
2015-12-05 22:40:30 +03:00
// calc gait frame
2015-09-30 03:49:22 +03:00
if ( pseqdesc - > linearmovement . x > 0.0f )
m_flGaitframe + = ( m_flGaitMovement / pseqdesc - > linearmovement . x ) * pseqdesc - > numframes ;
else
m_flGaitframe + = pev - > framerate * pseqdesc - > fps * dt ;
2015-12-05 22:40:30 +03:00
// do modulo
2016-02-23 02:13:52 +03:00
m_flGaitframe - = int ( m_flGaitframe / pseqdesc - > numframes ) * pseqdesc - > numframes ;
2015-09-30 03:49:22 +03:00
if ( m_flGaitframe < 0 )
m_flGaitframe + = pseqdesc - > numframes ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : ResetStamina ( )
2015-09-30 03:49:22 +03:00
{
pev - > fuser1 = 0 ;
pev - > fuser3 = 0 ;
pev - > fuser2 = 0 ;
}
2017-11-22 20:27:55 +03:00
real_t GetPlayerPitch ( const edict_t * pEdict )
2015-09-30 03:49:22 +03:00
{
2016-06-14 01:13:13 +03:00
if ( ! pEdict )
2016-06-12 16:55:45 +03:00
return 0.0f ;
2016-06-14 01:13:13 +03:00
2016-02-04 03:18:26 +03:00
entvars_t * pev = VARS ( const_cast < edict_t * > ( pEdict ) ) ;
2016-06-14 01:13:13 +03:00
CBasePlayer * pPlayer = CBasePlayer : : Instance ( pev ) ;
2015-09-30 03:49:22 +03:00
2016-06-14 01:13:13 +03:00
if ( ! pPlayer | | ! pPlayer - > IsPlayer ( ) )
2015-09-30 03:49:22 +03:00
return 0.0f ;
return pPlayer - > m_flPitch ;
}
2017-11-22 20:27:55 +03:00
real_t GetPlayerYaw ( const edict_t * pEdict )
2015-09-30 03:49:22 +03:00
{
2016-06-14 01:13:13 +03:00
if ( ! pEdict )
2016-06-12 16:55:45 +03:00
return 0.0f ;
2016-06-14 01:13:13 +03:00
2016-02-04 03:18:26 +03:00
entvars_t * pev = VARS ( const_cast < edict_t * > ( pEdict ) ) ;
2016-06-14 01:13:13 +03:00
CBasePlayer * pPlayer = CBasePlayer : : Instance ( pev ) ;
2015-09-30 03:49:22 +03:00
2016-06-14 01:13:13 +03:00
if ( ! pPlayer | | ! pPlayer - > IsPlayer ( ) )
2015-09-30 03:49:22 +03:00
return 0.0f ;
return pPlayer - > m_flYaw ;
}
int GetPlayerGaitsequence ( const edict_t * pEdict )
{
2016-06-14 01:13:13 +03:00
if ( ! pEdict )
return 1 ;
2016-02-04 03:18:26 +03:00
entvars_t * pev = VARS ( const_cast < edict_t * > ( pEdict ) ) ;
2016-06-14 01:13:13 +03:00
CBasePlayer * pPlayer = CBasePlayer : : Instance ( pev ) ;
2015-09-30 03:49:22 +03:00
2016-06-14 01:13:13 +03:00
if ( ! pPlayer | | ! pPlayer - > IsPlayer ( ) )
2015-09-30 03:49:22 +03:00
return 1 ;
return pPlayer - > m_iGaitsequence ;
}
2023-07-16 15:55:58 +03:00
float CBasePlayer : : GetDyingAnimationDuration ( ) const
{
float animDuration = - 1.0f ;
if ( CGameRules : : GetDyingTime ( ) < DEATH_ANIMATION_TIME ) // a short time, timeDiff estimates to be small
{
float flSequenceDuration = GetSequenceDuration ( ) ;
if ( flSequenceDuration > 0 )
animDuration = flSequenceDuration ;
}
if ( animDuration < = 0 )
animDuration = CGameRules : : GetDyingTime ( ) ; // in case of failure
return animDuration ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : SpawnClientSideCorpse ( )
2015-09-30 03:49:22 +03:00
{
2017-01-20 17:52:37 +03:00
# ifdef REGAMEDLL_FIXES
// not allow to spawn, if the player was torn to gib
if ( pev - > effects & EF_NODRAW )
return ;
2023-07-12 20:43:37 +03:00
// deadflag == DEAD_RESPAWNABLE already checked before
2017-01-20 17:52:37 +03:00
# endif
2017-05-24 19:07:37 +03:00
# ifdef REGAMEDLL_ADD
if ( forcerespawn . value > 0.0f )
return ;
# endif
2015-09-30 03:49:22 +03:00
char * infobuffer = GET_INFO_BUFFER ( edict ( ) ) ;
char * pModel = GET_KEY_VALUE ( infobuffer , " model " ) ;
2023-07-12 20:43:37 +03:00
float timeDiff = pev - > animtime - gpGlobals - > time ;
2023-09-28 12:18:15 +03:00
# ifdef REGAMEDLL_ADD
2023-07-12 20:43:37 +03:00
if ( CGameRules : : GetDyingTime ( ) < DEATH_ANIMATION_TIME ) // a short time, timeDiff estimates to be small
{
2023-07-16 15:55:58 +03:00
float animDuration = GetDyingAnimationDuration ( ) ;
2023-07-12 20:43:37 +03:00
2023-09-28 12:18:15 +03:00
// client receives a negative value
animDuration * = - 1.0 ;
2023-07-12 20:43:37 +03:00
if ( animDuration < timeDiff ) // reasonable way to fix client side unfinished sequence bug
{
2023-09-28 12:18:15 +03:00
// by some reason, if client receives a value less
// than "(negative current sequence time) * 100"
2023-07-12 20:43:37 +03:00
// animation will play visually awkward
2023-09-28 12:18:15 +03:00
// at this function call time, player death animation
2023-07-12 20:43:37 +03:00
// has already finished so we can safely fake it
2023-09-28 12:18:15 +03:00
timeDiff = animDuration ;
2023-07-12 20:43:37 +03:00
}
}
# endif
2015-09-30 03:49:22 +03:00
MESSAGE_BEGIN ( MSG_ALL , gmsgSendCorpse ) ;
WRITE_STRING ( pModel ) ;
WRITE_LONG ( pev - > origin . x * 128 ) ;
WRITE_LONG ( pev - > origin . y * 128 ) ;
WRITE_LONG ( pev - > origin . z * 128 ) ;
WRITE_COORD ( pev - > angles . x ) ;
WRITE_COORD ( pev - > angles . y ) ;
WRITE_COORD ( pev - > angles . z ) ;
2023-07-12 20:43:37 +03:00
WRITE_LONG ( timeDiff * 100 ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( pev - > sequence ) ;
WRITE_BYTE ( pev - > body ) ;
WRITE_BYTE ( m_iTeam ) ;
WRITE_BYTE ( entindex ( ) ) ;
MESSAGE_END ( ) ;
2023-07-12 20:43:37 +03:00
# ifndef REGAMEDLL_FIXES
// already defined in StartDeathCam
2015-09-30 03:49:22 +03:00
m_canSwitchObserverModes = true ;
2023-09-28 12:18:15 +03:00
# endif
2015-09-30 03:49:22 +03:00
2016-10-05 18:27:50 +03:00
if ( TheTutor )
2015-09-30 03:49:22 +03:00
{
TheTutor - > OnEvent ( EVENT_CLIENT_CORPSE_SPAWNED , this ) ;
}
}
BOOL CBasePlayer : : IsArmored ( int nHitGroup )
{
BOOL fApplyArmor = FALSE ;
2016-05-17 21:01:46 +03:00
if ( m_iKevlar = = ARMOR_NONE )
2015-09-30 03:49:22 +03:00
return FALSE ;
switch ( nHitGroup )
{
case HITGROUP_HEAD :
{
2016-05-17 21:01:46 +03:00
fApplyArmor = ( m_iKevlar = = ARMOR_VESTHELM ) ;
2015-09-30 03:49:22 +03:00
break ;
}
case HITGROUP_GENERIC :
case HITGROUP_CHEST :
case HITGROUP_STOMACH :
case HITGROUP_LEFTARM :
case HITGROUP_RIGHTARM :
fApplyArmor = TRUE ;
break ;
}
return fApplyArmor ;
}
BOOL CBasePlayer : : ShouldDoLargeFlinch ( int nHitGroup , int nGunType )
{
if ( pev - > flags & FL_DUCKING )
return FALSE ;
if ( nHitGroup ! = HITGROUP_LEFTLEG & & nHitGroup ! = HITGROUP_RIGHTLEG )
{
switch ( nGunType )
{
case WEAPON_SCOUT :
case WEAPON_AUG :
case WEAPON_SG550 :
case WEAPON_GALIL :
case WEAPON_FAMAS :
case WEAPON_AWP :
case WEAPON_M3 :
case WEAPON_M4A1 :
case WEAPON_G3SG1 :
case WEAPON_DEAGLE :
case WEAPON_SG552 :
case WEAPON_AK47 :
return TRUE ;
}
}
return FALSE ;
}
void CBasePlayer : : SetPrefsFromUserinfo ( char * infobuffer )
{
const char * pszKeyVal ;
pszKeyVal = GET_KEY_VALUE ( infobuffer , " _cl_autowepswitch " ) ;
2016-02-23 02:13:52 +03:00
if ( Q_strcmp ( pszKeyVal , " " ) ! = 0 )
2015-09-30 03:49:22 +03:00
m_iAutoWepSwitch = Q_atoi ( pszKeyVal ) ;
else
m_iAutoWepSwitch = 1 ;
pszKeyVal = GET_KEY_VALUE ( infobuffer , " _vgui_menus " ) ;
2016-02-23 02:13:52 +03:00
if ( Q_strcmp ( pszKeyVal , " " ) ! = 0 )
2015-09-30 03:49:22 +03:00
m_bVGUIMenus = Q_atoi ( pszKeyVal ) ! = 0 ;
else
m_bVGUIMenus = true ;
pszKeyVal = GET_KEY_VALUE ( infobuffer , " _ah " ) ;
2016-02-23 02:13:52 +03:00
if ( Q_strcmp ( pszKeyVal , " " ) ! = 0 )
2015-09-30 03:49:22 +03:00
m_bShowHints = Q_atoi ( pszKeyVal ) ! = 0 ;
else
m_bShowHints = true ;
}
bool CBasePlayer : : IsLookingAtPosition ( Vector * pos , float angleTolerance )
{
Vector to = * pos - EyePosition ( ) ;
Vector idealAngle = UTIL_VecToAngles ( to ) ;
idealAngle . x = 360.0 - idealAngle . x ;
float deltaYaw = NormalizeAngle ( idealAngle . y - pev - > v_angle . y ) ;
float deltaPitch = NormalizeAngle ( idealAngle . x - pev - > v_angle . x ) ;
2016-02-23 02:13:52 +03:00
return ( Q_abs ( deltaYaw ) < angleTolerance
& & Q_abs ( deltaPitch ) < angleTolerance ) ;
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
bool CBasePlayer : : CanAffordPrimary ( )
2015-09-30 03:49:22 +03:00
{
2016-10-05 18:27:50 +03:00
auto team = ( m_iTeam = = CT ) ? TERRORIST : ( m_iTeam = = TERRORIST ) ? CT : UNASSIGNED ;
if ( team = = UNASSIGNED )
return false ;
2015-09-30 03:49:22 +03:00
2016-10-05 18:27:50 +03:00
for ( auto & weapon : g_weaponStruct )
2015-09-30 03:49:22 +03:00
{
2016-10-05 18:27:50 +03:00
if ( ( weapon . m_side & team ) & & weapon . m_slot = = PRIMARY_WEAPON_SLOT & & m_iAccount > = weapon . m_price )
return true ;
2015-09-30 03:49:22 +03:00
}
return false ;
}
2016-02-04 03:18:26 +03:00
bool CBasePlayer : : CanAffordPrimaryAmmo ( )
2015-09-30 03:49:22 +03:00
{
2017-10-19 20:12:02 +03:00
CBasePlayerWeapon * pPrimary = static_cast < CBasePlayerWeapon * > ( m_rgpPlayerItems [ PRIMARY_WEAPON_SLOT ] ) ;
for ( auto & weapon : g_weaponStruct ) {
if ( weapon . m_type = = pPrimary - > m_iId & & m_iAccount > = weapon . m_ammoPrice )
2015-09-30 03:49:22 +03:00
return true ;
}
return false ;
}
2016-02-04 03:18:26 +03:00
bool CBasePlayer : : CanAffordSecondaryAmmo ( )
2015-09-30 03:49:22 +03:00
{
2017-10-19 20:12:02 +03:00
CBasePlayerWeapon * pSecondary = static_cast < CBasePlayerWeapon * > ( m_rgpPlayerItems [ PISTOL_SLOT ] ) ;
for ( auto & weapon : g_weaponStruct ) {
if ( weapon . m_type = = pSecondary - > m_iId & & m_iAccount > = weapon . m_ammoPrice )
2015-09-30 03:49:22 +03:00
return true ;
}
return false ;
}
2016-02-04 03:18:26 +03:00
bool CBasePlayer : : CanAffordArmor ( )
2015-09-30 03:49:22 +03:00
{
2016-05-17 21:01:46 +03:00
if ( m_iKevlar = = ARMOR_KEVLAR & & pev - > armorvalue = = 100.0f & & m_iAccount > = HELMET_PRICE )
2015-09-30 03:49:22 +03:00
return true ;
return ( m_iAccount > = KEVLAR_PRICE ) ;
}
2016-02-04 03:18:26 +03:00
bool CBasePlayer : : CanAffordDefuseKit ( )
2015-09-30 03:49:22 +03:00
{
return ( m_iAccount > = DEFUSEKIT_PRICE ) ;
}
2016-02-04 03:18:26 +03:00
bool CBasePlayer : : CanAffordGrenade ( )
2015-09-30 03:49:22 +03:00
{
return ( m_iAccount > = FLASHBANG_PRICE ) ;
}
2016-02-04 03:18:26 +03:00
bool CBasePlayer : : NeedsPrimaryAmmo ( )
2015-09-30 03:49:22 +03:00
{
2017-10-19 20:12:02 +03:00
CBasePlayerWeapon * pPrimary = static_cast < CBasePlayerWeapon * > ( m_rgpPlayerItems [ PRIMARY_WEAPON_SLOT ] ) ;
if ( ! pPrimary | | pPrimary - > m_iId = = WEAPON_SHIELDGUN ) {
2015-09-30 03:49:22 +03:00
return false ;
2017-10-19 20:12:02 +03:00
}
2015-09-30 03:49:22 +03:00
2017-10-19 20:12:02 +03:00
return ( m_rgAmmo [ pPrimary - > m_iPrimaryAmmoType ] < pPrimary - > iMaxAmmo1 ( ) ) ;
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
bool CBasePlayer : : NeedsSecondaryAmmo ( )
2015-09-30 03:49:22 +03:00
{
2017-10-19 20:12:02 +03:00
CBasePlayerWeapon * pSecondary = static_cast < CBasePlayerWeapon * > ( m_rgpPlayerItems [ PISTOL_SLOT ] ) ;
if ( ! pSecondary ) {
2015-09-30 03:49:22 +03:00
return false ;
2017-10-19 20:12:02 +03:00
}
2015-09-30 03:49:22 +03:00
2017-10-19 20:12:02 +03:00
return ( m_rgAmmo [ pSecondary - > m_iPrimaryAmmoType ] < pSecondary - > iMaxAmmo1 ( ) ) ;
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
bool CBasePlayer : : NeedsArmor ( )
2015-09-30 03:49:22 +03:00
{
2016-05-17 21:01:46 +03:00
if ( m_iKevlar = = ARMOR_NONE )
2015-09-30 03:49:22 +03:00
return true ;
return ( pev - > armorvalue < 50.0f ) ;
}
2016-02-04 03:18:26 +03:00
bool CBasePlayer : : NeedsDefuseKit ( )
2015-09-30 03:49:22 +03:00
{
if ( m_bHasDefuser | | m_iTeam ! = CT )
return false ;
2016-02-23 02:13:52 +03:00
return ( CSGameRules ( ) - > m_bMapHasBombTarget ) ;
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
bool CBasePlayer : : NeedsGrenade ( )
2015-09-30 03:49:22 +03:00
{
int iAmmoIndex = GetAmmoIndex ( " HEGrenade " ) ;
2017-10-19 20:12:02 +03:00
if ( iAmmoIndex > 0 & & m_rgAmmo [ iAmmoIndex ] )
2015-09-30 03:49:22 +03:00
return false ;
iAmmoIndex = GetAmmoIndex ( " Flashbang " ) ;
2017-10-19 20:12:02 +03:00
if ( iAmmoIndex > 0 & & m_rgAmmo [ iAmmoIndex ] )
2015-09-30 03:49:22 +03:00
return false ;
iAmmoIndex = GetAmmoIndex ( " SmokeGrenade " ) ;
2017-10-19 20:12:02 +03:00
if ( iAmmoIndex > 0 & & m_rgAmmo [ iAmmoIndex ] )
2015-09-30 03:49:22 +03:00
return false ;
return true ;
}
void CBasePlayer : : ClientCommand ( const char * cmd , const char * arg1 , const char * arg2 , const char * arg3 )
{
BotArgs [ 0 ] = cmd ;
BotArgs [ 1 ] = arg1 ;
BotArgs [ 2 ] = arg2 ;
BotArgs [ 3 ] = arg3 ;
UseBotArgs = true ;
2018-05-31 09:55:07 +03:00
: : ClientCommand_ ( ENT ( pev ) ) ;
2015-09-30 03:49:22 +03:00
UseBotArgs = false ;
}
const char * GetBuyStringForWeaponClass ( int weaponClass )
{
switch ( weaponClass )
{
case WEAPONCLASS_PISTOL :
return " deagle elites fn57 usp glock p228 shield " ;
case WEAPONCLASS_SNIPERRIFLE :
return " awp sg550 g3sg1 scout " ;
case WEAPONCLASS_GRENADE :
return " hegren " ;
case WEAPONCLASS_SHOTGUN :
return " xm1014 m3 " ;
case WEAPONCLASS_SUBMACHINEGUN :
return " p90 ump45 mp5 tmp mac10 " ;
case WEAPONCLASS_MACHINEGUN :
return " m249 " ;
case WEAPONCLASS_RIFLE :
return " sg552 aug ak47 m4a1 galil famas " ;
}
2017-10-13 03:04:37 +03:00
return nullptr ;
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : ClearAutoBuyData ( )
2015-09-30 03:49:22 +03:00
{
m_autoBuyString [ 0 ] = ' \0 ' ;
}
void CBasePlayer : : AddAutoBuyData ( const char * str )
{
int len = Q_strlen ( m_autoBuyString ) ;
2016-02-23 02:13:52 +03:00
if ( len < sizeof ( m_autoBuyString ) - 1 )
2015-09-30 03:49:22 +03:00
{
if ( len > 0 )
2016-04-05 03:12:05 +03:00
{
Q_strncat ( m_autoBuyString , " " , len ) ;
}
2015-09-30 03:49:22 +03:00
2016-02-23 02:13:52 +03:00
# ifndef REGAMEDLL_FIXES
2016-04-05 03:12:05 +03:00
Q_strncat ( m_autoBuyString , str , sizeof ( m_autoBuyString ) - Q_strlen ( m_autoBuyString ) ) ;
2016-02-23 02:13:52 +03:00
# else
2016-04-05 03:12:05 +03:00
Q_strncat ( m_autoBuyString , str , sizeof ( m_autoBuyString ) - Q_strlen ( m_autoBuyString ) - 1 ) ;
2016-02-23 02:13:52 +03:00
# endif
2015-09-30 03:49:22 +03:00
}
}
void CBasePlayer : : InitRebuyData ( const char * str )
{
if ( ! str | | Q_strlen ( str ) > MAX_REBUY_LENGTH )
{
return ;
}
2016-12-06 22:21:52 +03:00
if ( m_rebuyString )
2015-09-30 03:49:22 +03:00
{
2016-04-05 03:12:05 +03:00
delete [ ] m_rebuyString ;
2017-10-13 03:04:37 +03:00
m_rebuyString = nullptr ;
2015-09-30 03:49:22 +03:00
}
2017-10-19 20:12:02 +03:00
m_rebuyString = new char [ Q_strlen ( str ) + 1 ] ;
2015-09-30 03:49:22 +03:00
Q_strcpy ( m_rebuyString , str ) ;
2017-10-19 20:12:02 +03:00
m_rebuyString [ Q_strlen ( str ) ] = ' \0 ' ;
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : AutoBuy ( )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
const char * c = nullptr ;
2015-09-30 03:49:22 +03:00
bool boughtPrimary = false ;
bool boughtSecondary = false ;
2017-10-19 20:12:02 +03:00
char prioritizedString [ MAX_AUTOBUY_LENGTH ] ;
2015-09-30 03:49:22 +03:00
c = PickFlashKillWeaponString ( ) ;
2016-12-06 22:21:52 +03:00
if ( c )
2015-09-30 03:49:22 +03:00
{
ParseAutoBuyString ( c , boughtPrimary , boughtSecondary ) ;
}
c = PickGrenadeKillWeaponString ( ) ;
2016-12-06 22:21:52 +03:00
if ( c )
2015-09-30 03:49:22 +03:00
{
ParseAutoBuyString ( c , boughtPrimary , boughtSecondary ) ;
}
c = PickPrimaryCareerTaskWeapon ( ) ;
2016-12-06 22:21:52 +03:00
if ( c )
2015-09-30 03:49:22 +03:00
{
Q_strcpy ( prioritizedString , c ) ;
PrioritizeAutoBuyString ( prioritizedString , m_autoBuyString ) ;
ParseAutoBuyString ( prioritizedString , boughtPrimary , boughtSecondary ) ;
}
c = PickSecondaryCareerTaskWeapon ( ) ;
2016-12-06 22:21:52 +03:00
if ( c )
2015-09-30 03:49:22 +03:00
{
Q_strcpy ( prioritizedString , c ) ;
PrioritizeAutoBuyString ( prioritizedString , m_autoBuyString ) ;
ParseAutoBuyString ( prioritizedString , boughtPrimary , boughtSecondary ) ;
}
ParseAutoBuyString ( m_autoBuyString , boughtPrimary , boughtSecondary ) ;
c = PickFlashKillWeaponString ( ) ;
2016-12-06 22:21:52 +03:00
if ( c )
2015-09-30 03:49:22 +03:00
{
ParseAutoBuyString ( c , boughtPrimary , boughtSecondary ) ;
}
2016-12-06 22:21:52 +03:00
if ( TheTutor )
2015-11-06 17:58:48 +03:00
{
2015-09-30 03:49:22 +03:00
TheTutor - > OnEvent ( EVENT_PLAYER_LEFT_BUY_ZONE ) ;
2015-11-06 17:58:48 +03:00
}
2015-09-30 03:49:22 +03:00
}
bool IsPrimaryWeaponClass ( int classId )
{
return ( classId > = WEAPONCLASS_SUBMACHINEGUN & & classId < = WEAPONCLASS_SNIPERRIFLE ) ;
}
bool IsPrimaryWeaponId ( int id )
{
int classId = WEAPONCLASS_NONE ;
const char * alias = WeaponIDToAlias ( id ) ;
2016-12-06 22:21:52 +03:00
if ( alias )
2015-09-30 03:49:22 +03:00
{
classId = AliasToWeaponClass ( alias ) ;
}
return IsPrimaryWeaponClass ( classId ) ;
}
bool IsSecondaryWeaponClass ( int classId )
{
return ( classId = = WEAPONCLASS_PISTOL ) ;
}
bool IsSecondaryWeaponId ( int id )
{
int classId = WEAPONCLASS_NONE ;
const char * alias = WeaponIDToAlias ( id ) ;
2016-12-06 22:21:52 +03:00
if ( alias )
2015-09-30 03:49:22 +03:00
{
classId = AliasToWeaponClass ( alias ) ;
}
return IsSecondaryWeaponClass ( classId ) ;
}
const char * GetWeaponAliasFromName ( const char * weaponName )
{
2016-10-05 18:27:50 +03:00
const char cut_weapon [ ] = " weapon_ " ;
if ( ! Q_strncmp ( weaponName , cut_weapon , sizeof ( cut_weapon ) - 1 ) )
2015-09-30 03:49:22 +03:00
{
2016-10-05 18:27:50 +03:00
weaponName + = sizeof ( cut_weapon ) - 1 ;
2015-09-30 03:49:22 +03:00
}
return weaponName ;
}
bool CurrentWeaponSatisfies ( CBasePlayerWeapon * pWeapon , int id , int classId )
{
2017-10-13 03:04:37 +03:00
if ( ! pWeapon )
2015-09-30 03:49:22 +03:00
return false ;
const char * weaponName = GetWeaponAliasFromName ( pWeapon - > pszName ( ) ) ;
if ( id & & AliasToWeaponID ( weaponName ) = = id )
return true ;
if ( classId & & AliasToWeaponClass ( weaponName ) = = classId )
return true ;
return false ;
}
2016-02-04 03:18:26 +03:00
const char * CBasePlayer : : PickPrimaryCareerTaskWeapon ( )
2015-11-06 17:58:48 +03:00
{
const int BufLen = 256 ;
static char buf [ BufLen ] ;
2017-10-19 20:12:02 +03:00
CBasePlayerWeapon * pPrimary ;
2015-11-06 17:58:48 +03:00
std : : vector < CCareerTask * > taskVector ;
2017-10-13 03:04:37 +03:00
if ( ! TheCareerTasks )
2015-11-06 17:58:48 +03:00
{
2017-10-13 03:04:37 +03:00
return nullptr ;
2015-11-06 17:58:48 +03:00
}
buf [ 0 ] = ' \0 ' ;
2017-10-19 20:12:02 +03:00
pPrimary = static_cast < CBasePlayerWeapon * > ( m_rgpPlayerItems [ PRIMARY_WEAPON_SLOT ] ) ;
2015-11-06 17:58:48 +03:00
2017-10-13 03:04:37 +03:00
for ( auto pTask : * TheCareerTasks - > GetTasks ( ) )
2015-11-06 17:58:48 +03:00
{
if ( pTask - > IsComplete ( ) | | pTask - > GetWeaponId ( ) = = WEAPON_HEGRENADE )
continue ;
if ( ! IsPrimaryWeaponId ( pTask - > GetWeaponId ( ) ) )
{
if ( ! IsPrimaryWeaponClass ( pTask - > GetWeaponClassId ( ) ) )
{
continue ;
}
}
2017-10-19 20:12:02 +03:00
if ( pPrimary )
2015-11-06 17:58:48 +03:00
{
2017-10-19 20:12:02 +03:00
if ( CurrentWeaponSatisfies ( pPrimary , pTask - > GetWeaponId ( ) , pTask - > GetWeaponClassId ( ) ) )
2015-11-06 17:58:48 +03:00
{
if ( IsPrimaryWeaponId ( pTask - > GetWeaponId ( ) ) )
{
return WeaponIDToAlias ( pTask - > GetWeaponId ( ) ) ;
}
else
{
return GetBuyStringForWeaponClass ( pTask - > GetWeaponClassId ( ) ) ;
}
}
}
taskVector . push_back ( pTask ) ;
}
int taskNum = taskVector . size ( ) ;
if ( taskNum > 1 )
{
// randomize names weapons of list
int rand = RANDOM_LONG ( 0 , taskNum - 1 ) ;
2016-10-05 18:27:50 +03:00
SWAP ( taskVector [ 0 ] , taskVector [ rand ] ) ;
2015-11-06 17:58:48 +03:00
}
if ( ! taskNum )
{
2017-10-13 03:04:37 +03:00
return nullptr ;
2015-11-06 17:58:48 +03:00
}
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < taskNum ; i + + )
2015-11-06 17:58:48 +03:00
{
CCareerTask * pTask = taskVector [ i ] ;
if ( IsPrimaryWeaponId ( pTask - > GetWeaponId ( ) ) )
2016-02-23 02:13:52 +03:00
Q_strncat ( buf , WeaponIDToAlias ( pTask - > GetWeaponId ( ) ) , sizeof ( buf ) - Q_strlen ( buf ) - 1 ) ;
2015-11-06 17:58:48 +03:00
else
2016-02-23 02:13:52 +03:00
Q_strncat ( buf , GetBuyStringForWeaponClass ( pTask - > GetWeaponClassId ( ) ) , sizeof ( buf ) - Q_strlen ( buf ) - 1 ) ;
2015-11-06 17:58:48 +03:00
2016-02-23 02:13:52 +03:00
Q_strncat ( buf , " " , sizeof ( buf ) - Q_strlen ( buf ) - 1 ) ;
2015-11-06 17:58:48 +03:00
}
return buf ;
}
2015-09-30 03:49:22 +03:00
2016-02-04 03:18:26 +03:00
const char * CBasePlayer : : PickSecondaryCareerTaskWeapon ( )
2015-11-06 17:58:48 +03:00
{
const int BufLen = 256 ;
static char buf [ BufLen ] ;
2017-10-19 20:12:02 +03:00
CBasePlayerWeapon * pSecondary ;
2015-11-06 17:58:48 +03:00
std : : vector < CCareerTask * > taskVector ;
2017-10-13 03:04:37 +03:00
if ( ! TheCareerTasks )
2015-11-06 17:58:48 +03:00
{
2017-10-13 03:04:37 +03:00
return nullptr ;
2015-11-06 17:58:48 +03:00
}
2017-10-19 20:12:02 +03:00
pSecondary = static_cast < CBasePlayerWeapon * > ( m_rgpPlayerItems [ PISTOL_SLOT ] ) ;
2015-11-06 17:58:48 +03:00
2017-10-13 03:04:37 +03:00
for ( auto pTask : * TheCareerTasks - > GetTasks ( ) )
2015-11-06 17:58:48 +03:00
{
if ( pTask - > IsComplete ( ) | | pTask - > GetWeaponId ( ) = = WEAPON_HEGRENADE )
continue ;
if ( ! IsSecondaryWeaponId ( pTask - > GetWeaponId ( ) ) )
{
if ( ! IsSecondaryWeaponClass ( pTask - > GetWeaponClassId ( ) ) )
{
continue ;
}
}
2017-10-19 20:12:02 +03:00
if ( pSecondary )
2015-11-06 17:58:48 +03:00
{
2017-10-19 20:12:02 +03:00
if ( CurrentWeaponSatisfies ( pSecondary , pTask - > GetWeaponId ( ) , pTask - > GetWeaponClassId ( ) ) )
2015-11-06 17:58:48 +03:00
{
if ( IsSecondaryWeaponId ( pTask - > GetWeaponId ( ) ) )
{
return WeaponIDToAlias ( pTask - > GetWeaponId ( ) ) ;
}
else
{
return GetBuyStringForWeaponClass ( pTask - > GetWeaponClassId ( ) ) ;
}
}
}
taskVector . push_back ( pTask ) ;
}
int taskNum = taskVector . size ( ) ;
if ( taskNum > 1 )
{
// randomize names weapons of list
int rand = RANDOM_LONG ( 0 , taskNum - 1 ) ;
2016-10-05 18:27:50 +03:00
SWAP ( taskVector [ 0 ] , taskVector [ rand ] ) ;
2015-11-06 17:58:48 +03:00
}
if ( ! taskNum )
{
2017-10-13 03:04:37 +03:00
return nullptr ;
2015-11-06 17:58:48 +03:00
}
buf [ 0 ] = ' \0 ' ;
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < taskNum ; i + + )
2015-11-06 17:58:48 +03:00
{
CCareerTask * pTask = taskVector [ i ] ;
if ( IsSecondaryWeaponId ( pTask - > GetWeaponId ( ) ) )
2016-02-23 02:13:52 +03:00
Q_strncat ( buf , WeaponIDToAlias ( pTask - > GetWeaponId ( ) ) , sizeof ( buf ) - Q_strlen ( buf ) - 1 ) ;
2015-11-06 17:58:48 +03:00
else
2016-02-23 02:13:52 +03:00
Q_strncat ( buf , GetBuyStringForWeaponClass ( pTask - > GetWeaponClassId ( ) ) , sizeof ( buf ) - Q_strlen ( buf ) - 1 ) ;
2015-11-06 17:58:48 +03:00
2016-02-23 02:13:52 +03:00
Q_strncat ( buf , " " , sizeof ( buf ) - Q_strlen ( buf ) - 1 ) ;
2015-11-06 17:58:48 +03:00
}
return buf ;
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
const char * CBasePlayer : : PickFlashKillWeaponString ( )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
if ( ! TheCareerTasks )
return nullptr ;
2015-12-05 22:40:30 +03:00
2015-09-30 03:49:22 +03:00
bool foundOne = false ;
2017-10-13 03:04:37 +03:00
for ( auto pTask : * TheCareerTasks - > GetTasks ( ) )
2015-09-30 03:49:22 +03:00
{
if ( ! pTask - > IsComplete ( ) & & ! Q_strcmp ( pTask - > GetTaskName ( ) , " killblind " ) )
{
foundOne = true ;
break ;
}
}
if ( foundOne )
return " flash flash " ;
2017-10-13 03:04:37 +03:00
return nullptr ;
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
const char * CBasePlayer : : PickGrenadeKillWeaponString ( )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
if ( ! TheCareerTasks )
return nullptr ;
2015-12-05 22:40:30 +03:00
2015-09-30 03:49:22 +03:00
bool foundOne = false ;
2017-10-13 03:04:37 +03:00
for ( auto pTask : * TheCareerTasks - > GetTasks ( ) )
2015-09-30 03:49:22 +03:00
{
if ( ! pTask - > IsComplete ( ) & & pTask - > GetWeaponId ( ) = = WEAPON_HEGRENADE )
{
foundOne = true ;
break ;
}
}
if ( foundOne )
return " hegren " ;
2017-10-13 03:04:37 +03:00
return nullptr ;
2015-09-30 03:49:22 +03:00
}
2016-01-06 15:50:26 +03:00
// PostAutoBuyCommandProcessing - reorders the tokens in autobuyString based on the order of tokens in the priorityString.
2015-09-30 03:49:22 +03:00
void CBasePlayer : : PrioritizeAutoBuyString ( char * autobuyString , const char * priorityString )
{
2017-10-19 20:12:02 +03:00
char newString [ MAX_AUTOBUY_LENGTH ] ;
2015-09-30 03:49:22 +03:00
int newStringPos = 0 ;
char priorityToken [ 32 ] ;
if ( ! priorityString | | ! autobuyString )
return ;
const char * priorityChar = priorityString ;
while ( * priorityChar ! = ' \0 ' )
{
int i = 0 ;
2016-01-06 15:50:26 +03:00
// get the next token from the priority string.
2015-09-30 03:49:22 +03:00
while ( * priorityChar ! = ' \0 ' & & * priorityChar ! = ' ' )
{
2016-01-25 20:02:57 +03:00
priorityToken [ i + + ] = * priorityChar ;
2017-10-13 03:04:37 +03:00
priorityChar + + ;
2015-09-30 03:49:22 +03:00
}
2016-01-06 15:50:26 +03:00
priorityToken [ i ] = ' \0 ' ;
2015-09-30 03:49:22 +03:00
2016-01-06 15:50:26 +03:00
// skip spaces
2015-09-30 03:49:22 +03:00
while ( * priorityChar = = ' ' )
2017-10-13 03:04:37 +03:00
priorityChar + + ;
2015-09-30 03:49:22 +03:00
2016-01-06 15:50:26 +03:00
if ( Q_strlen ( priorityToken ) = = 0 )
{
2015-09-30 03:49:22 +03:00
continue ;
2016-01-06 15:50:26 +03:00
}
2015-09-30 03:49:22 +03:00
2016-01-06 15:50:26 +03:00
// see if the priority token is in the autobuy string.
// if it is, copy that token to the new string and blank out
// that token in the autobuy string.
2015-09-30 03:49:22 +03:00
char * autoBuyPosition = Q_strstr ( autobuyString , priorityToken ) ;
2016-12-06 22:21:52 +03:00
if ( autoBuyPosition )
2015-09-30 03:49:22 +03:00
{
while ( * autoBuyPosition ! = ' \0 ' & & * autoBuyPosition ! = ' ' )
{
2017-10-13 03:04:37 +03:00
newString [ newStringPos ] = * autoBuyPosition ;
2015-09-30 03:49:22 +03:00
* autoBuyPosition = ' ' ;
2017-10-13 03:04:37 +03:00
newStringPos + + ;
autoBuyPosition + + ;
2015-09-30 03:49:22 +03:00
}
2017-10-13 03:04:37 +03:00
newString [ newStringPos + + ] = ' ' ;
2015-09-30 03:49:22 +03:00
}
}
2016-01-06 15:50:26 +03:00
// now just copy anything left in the autobuyString to the new string in the order it's in already.
2015-09-30 03:49:22 +03:00
char * autobuyPosition = autobuyString ;
while ( * autobuyPosition ! = ' \0 ' )
{
2016-01-06 15:50:26 +03:00
// skip spaces
2015-09-30 03:49:22 +03:00
while ( * autobuyPosition = = ' ' )
2017-10-13 03:04:37 +03:00
autobuyPosition + + ;
2015-09-30 03:49:22 +03:00
2016-01-06 15:50:26 +03:00
// copy the token over to the new string.
2015-09-30 03:49:22 +03:00
while ( * autobuyPosition ! = ' \0 ' & & * autobuyPosition ! = ' ' )
{
2017-10-19 20:12:02 +03:00
newString [ newStringPos + + ] = * autobuyPosition ;
2017-10-13 03:04:37 +03:00
autobuyPosition + + ;
2015-09-30 03:49:22 +03:00
}
2016-01-06 15:50:26 +03:00
// add a space at the end.
2017-10-13 03:04:37 +03:00
newString [ newStringPos + + ] = ' ' ;
2015-09-30 03:49:22 +03:00
}
2016-01-06 15:50:26 +03:00
// terminate the string. Trailing spaces shouldn't matter.
2017-10-13 03:04:37 +03:00
newString [ newStringPos ] = ' \0 ' ;
2016-01-06 15:50:26 +03:00
2015-09-30 03:49:22 +03:00
Q_sprintf ( autobuyString , " %s " , newString ) ;
}
void CBasePlayer : : ParseAutoBuyString ( const char * string , bool & boughtPrimary , bool & boughtSecondary )
{
char command [ 32 ] ;
const char * c = string ;
if ( ! string | | ! string [ 0 ] )
return ;
2016-01-06 15:50:26 +03:00
// loop through the string of commands, trying each one in turn.
2015-09-30 03:49:22 +03:00
while ( * c )
{
int i = 0 ;
2016-01-06 15:50:26 +03:00
// copy the next word into the command buffer.
2015-12-18 19:32:50 +03:00
while ( * c & & ( * c ! = ' ' ) & & i < sizeof ( command ) - 1 )
2015-09-30 03:49:22 +03:00
{
2015-12-18 19:32:50 +03:00
command [ i + + ] = * c + + ;
2015-09-30 03:49:22 +03:00
}
if ( * c = = ' ' )
2016-01-06 15:50:26 +03:00
{
// skip the space.
2017-10-13 03:04:37 +03:00
c + + ;
2016-01-06 15:50:26 +03:00
}
2015-09-30 03:49:22 +03:00
2016-01-06 15:50:26 +03:00
// terminate the string.
2015-12-18 19:32:50 +03:00
command [ i ] = ' \0 ' ;
2015-09-30 03:49:22 +03:00
2016-01-06 15:50:26 +03:00
// clear out any spaces.
i = 0 ;
2015-12-18 19:32:50 +03:00
while ( command [ i ] ! = ' \0 ' )
2015-09-30 03:49:22 +03:00
{
2016-01-06 15:50:26 +03:00
if ( command [ i ] = = ' ' )
2015-09-30 03:49:22 +03:00
{
2015-12-18 19:32:50 +03:00
command [ i ] = ' \0 ' ;
2015-09-30 03:49:22 +03:00
break ;
}
2017-11-22 20:27:55 +03:00
2017-10-12 17:50:56 +03:00
i + + ;
2015-09-30 03:49:22 +03:00
}
2016-01-06 15:50:26 +03:00
// make sure we actually have a command.
if ( Q_strlen ( command ) = = 0 )
{
2015-09-30 03:49:22 +03:00
continue ;
2016-01-06 15:50:26 +03:00
}
2015-09-30 03:49:22 +03:00
AutoBuyInfoStruct * commandInfo = GetAutoBuyCommandInfo ( command ) ;
if ( ShouldExecuteAutoBuyCommand ( commandInfo , boughtPrimary , boughtSecondary ) )
{
ClientCommand ( commandInfo - > m_command ) ;
2016-01-06 15:50:26 +03:00
// check to see if we actually bought a primary or secondary weapon this time.
2015-09-30 03:49:22 +03:00
PostAutoBuyCommandProcessing ( commandInfo , boughtPrimary , boughtSecondary ) ;
}
}
}
bool CBasePlayer : : ShouldExecuteAutoBuyCommand ( AutoBuyInfoStruct * commandInfo , bool boughtPrimary , bool boughtSecondary )
{
if ( ! commandInfo )
2016-01-06 15:50:26 +03:00
{
2015-09-30 03:49:22 +03:00
return false ;
2016-01-06 15:50:26 +03:00
}
2015-09-30 03:49:22 +03:00
2016-01-06 15:50:26 +03:00
if ( boughtPrimary & & ( commandInfo - > m_class & AUTOBUYCLASS_PRIMARY ) ! = 0 & & ( commandInfo - > m_class & AUTOBUYCLASS_AMMO ) = = 0 )
{
// this is a primary weapon and we already have one.
2015-09-30 03:49:22 +03:00
return false ;
2016-01-06 15:50:26 +03:00
}
2015-09-30 03:49:22 +03:00
2016-01-06 15:50:26 +03:00
if ( boughtSecondary & & ( commandInfo - > m_class & AUTOBUYCLASS_SECONDARY ) ! = 0 & & ( commandInfo - > m_class & AUTOBUYCLASS_AMMO ) = = 0 )
{
// this is a secondary weapon and we already have one.
2015-09-30 03:49:22 +03:00
return false ;
2016-01-06 15:50:26 +03:00
}
2015-09-30 03:49:22 +03:00
return true ;
}
AutoBuyInfoStruct * CBasePlayer : : GetAutoBuyCommandInfo ( const char * command )
{
2016-01-06 15:50:26 +03:00
// loop through all the commands till we find the one that matches.
2016-12-06 22:21:52 +03:00
for ( auto & buyInfo : g_autoBuyInfo )
2015-09-30 03:49:22 +03:00
{
2016-12-06 22:21:52 +03:00
if ( buyInfo . m_class = = AUTOBUYCLASS_NONE )
continue ;
2015-09-30 03:49:22 +03:00
2016-12-06 22:21:52 +03:00
if ( FStrEq ( buyInfo . m_command , command ) )
return & buyInfo ;
2015-09-30 03:49:22 +03:00
}
2016-12-06 22:21:52 +03:00
return nullptr ;
2015-09-30 03:49:22 +03:00
}
void CBasePlayer : : PostAutoBuyCommandProcessing ( AutoBuyInfoStruct * commandInfo , bool & boughtPrimary , bool & boughtSecondary )
{
2017-10-13 03:04:37 +03:00
if ( ! commandInfo )
2016-01-06 15:50:26 +03:00
{
return ;
}
2017-10-19 20:12:02 +03:00
CBasePlayerWeapon * pPrimary = static_cast < CBasePlayerWeapon * > ( m_rgpPlayerItems [ PRIMARY_WEAPON_SLOT ] ) ;
CBasePlayerWeapon * pSecondary = static_cast < CBasePlayerWeapon * > ( m_rgpPlayerItems [ PISTOL_SLOT ] ) ;
2015-09-30 03:49:22 +03:00
2017-10-19 20:12:02 +03:00
if ( pPrimary & & FClassnameIs ( pPrimary - > pev , commandInfo - > m_classname ) )
2016-01-06 15:50:26 +03:00
{
// I just bought the gun I was trying to buy.
2015-09-30 03:49:22 +03:00
boughtPrimary = true ;
2016-01-06 15:50:26 +03:00
}
2017-10-19 20:12:02 +03:00
else if ( ! pPrimary & & ( ( commandInfo - > m_class & AUTOBUYCLASS_SHIELD ) = = AUTOBUYCLASS_SHIELD ) & & HasShield ( ) )
2016-01-06 15:50:26 +03:00
{
// the shield is a primary weapon even though it isn't a "real" weapon.
2015-09-30 03:49:22 +03:00
boughtPrimary = true ;
2016-01-06 15:50:26 +03:00
}
2017-10-19 20:12:02 +03:00
else if ( pSecondary & & FClassnameIs ( pSecondary - > pev , commandInfo - > m_classname ) )
2016-01-06 15:50:26 +03:00
{
// I just bought the pistol I was trying to buy.
2015-09-30 03:49:22 +03:00
boughtSecondary = true ;
2016-01-06 15:50:26 +03:00
}
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : BuildRebuyStruct ( )
2015-09-30 03:49:22 +03:00
{
if ( m_bIsInRebuy )
2016-01-06 15:50:26 +03:00
{
// if we are in the middle of a rebuy, we don't want to update the buy struct.
2015-09-30 03:49:22 +03:00
return ;
2016-01-06 15:50:26 +03:00
}
2015-09-30 03:49:22 +03:00
2017-10-19 20:12:02 +03:00
CBasePlayerWeapon * pPrimary = static_cast < CBasePlayerWeapon * > ( m_rgpPlayerItems [ PRIMARY_WEAPON_SLOT ] ) ;
CBasePlayerWeapon * pSecondary = static_cast < CBasePlayerWeapon * > ( m_rgpPlayerItems [ PISTOL_SLOT ] ) ;
2015-09-30 03:49:22 +03:00
2016-01-06 15:50:26 +03:00
// do the primary weapon/ammo stuff.
2017-10-19 20:12:02 +03:00
if ( ! pPrimary )
2015-09-30 03:49:22 +03:00
{
2016-01-06 15:50:26 +03:00
// count a shieldgun as a primary.
2015-09-30 03:49:22 +03:00
if ( HasShield ( ) )
2016-01-06 15:50:26 +03:00
{
2015-09-30 03:49:22 +03:00
m_rebuyStruct . m_primaryWeapon = WEAPON_SHIELDGUN ;
2016-01-06 15:50:26 +03:00
m_rebuyStruct . m_primaryAmmo = 0 ; // shields don't have ammo.
}
2015-09-30 03:49:22 +03:00
else
2016-01-06 15:50:26 +03:00
{
m_rebuyStruct . m_primaryWeapon = 0 ; // if we don't have a shield and we don't have a primary weapon, we got nuthin.
m_rebuyStruct . m_primaryAmmo = 0 ; // can't have ammo if we don't have a gun right?
}
}
else
{
2017-10-19 20:12:02 +03:00
m_rebuyStruct . m_primaryWeapon = pPrimary - > m_iId ;
m_rebuyStruct . m_primaryAmmo = m_rgAmmo [ pPrimary - > m_iPrimaryAmmoType ] ;
2015-09-30 03:49:22 +03:00
}
2016-01-06 15:50:26 +03:00
// do the secondary weapon/ammo stuff.
2017-10-19 20:12:02 +03:00
if ( ! pSecondary )
2015-09-30 03:49:22 +03:00
{
2016-01-06 15:50:26 +03:00
m_rebuyStruct . m_secondaryWeapon = 0 ;
m_rebuyStruct . m_secondaryAmmo = 0 ; // can't have ammo if we don't have a gun right?
2015-09-30 03:49:22 +03:00
}
else
{
2017-10-19 20:12:02 +03:00
m_rebuyStruct . m_secondaryWeapon = pSecondary - > m_iId ;
m_rebuyStruct . m_secondaryAmmo = m_rgAmmo [ pSecondary - > m_iPrimaryAmmoType ] ;
2015-09-30 03:49:22 +03:00
}
2016-01-06 15:50:26 +03:00
// HE Grenade
int iAmmoIndex = GetAmmoIndex ( " HEGrenade " ) ;
2015-09-30 03:49:22 +03:00
if ( iAmmoIndex ! = - 1 )
2017-10-19 20:12:02 +03:00
m_rebuyStruct . m_heGrenade = m_rgAmmo [ iAmmoIndex ] ;
2015-09-30 03:49:22 +03:00
else
m_rebuyStruct . m_heGrenade = 0 ;
2016-01-06 15:50:26 +03:00
// flashbang
2015-09-30 03:49:22 +03:00
iAmmoIndex = GetAmmoIndex ( " Flashbang " ) ;
if ( iAmmoIndex ! = - 1 )
2017-10-19 20:12:02 +03:00
m_rebuyStruct . m_flashbang = m_rgAmmo [ iAmmoIndex ] ;
2015-09-30 03:49:22 +03:00
else
m_rebuyStruct . m_flashbang = 0 ;
2016-01-06 15:50:26 +03:00
// smokegrenade
2015-09-30 03:49:22 +03:00
iAmmoIndex = GetAmmoIndex ( " SmokeGrenade " ) ;
if ( iAmmoIndex ! = - 1 )
2017-10-19 20:12:02 +03:00
m_rebuyStruct . m_smokeGrenade = m_rgAmmo [ iAmmoIndex ] ;
2015-09-30 03:49:22 +03:00
else
m_rebuyStruct . m_smokeGrenade = 0 ;
2017-10-12 17:50:56 +03:00
m_rebuyStruct . m_defuser = m_bHasDefuser ; // defuser
2016-01-06 15:50:26 +03:00
m_rebuyStruct . m_nightVision = m_bHasNightVision ; // night vision
2017-10-12 17:50:56 +03:00
m_rebuyStruct . m_armor = m_iKevlar ; // check for armor.
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : Rebuy ( )
2015-09-30 03:49:22 +03:00
{
char * fileData = m_rebuyString ;
char * token ;
m_bIsInRebuy = true ;
while ( true )
{
2017-10-12 17:50:56 +03:00
fileData = SharedParse ( fileData ) ;
token = SharedGetToken ( ) ;
2015-09-30 03:49:22 +03:00
if ( ! fileData )
break ;
if ( ! Q_stricmp ( token , " primaryWeapon " ) )
RebuyPrimaryWeapon ( ) ;
else if ( ! Q_stricmp ( token , " primaryAmmo " ) )
RebuyPrimaryAmmo ( ) ;
else if ( ! Q_stricmp ( token , " secondaryWeapon " ) )
RebuySecondaryWeapon ( ) ;
else if ( ! Q_stricmp ( token , " secondaryAmmo " ) )
RebuySecondaryAmmo ( ) ;
else if ( ! Q_stricmp ( token , " hegrenade " ) )
RebuyHEGrenade ( ) ;
else if ( ! Q_stricmp ( token , " flashbang " ) )
RebuyFlashbang ( ) ;
else if ( ! Q_stricmp ( token , " smokegrenade " ) )
RebuySmokeGrenade ( ) ;
else if ( ! Q_stricmp ( token , " defuser " ) )
RebuyDefuser ( ) ;
else if ( ! Q_stricmp ( token , " nightvision " ) )
RebuyNightVision ( ) ;
else if ( ! Q_stricmp ( token , " armor " ) )
RebuyArmor ( ) ;
}
m_bIsInRebuy = false ;
2016-01-06 15:50:26 +03:00
// after we're done buying, the user is done with their equipment purchasing experience.
// so we are effectively out of the buy zone.
2016-12-06 22:21:52 +03:00
if ( TheTutor )
2015-12-05 22:40:30 +03:00
{
2015-09-30 03:49:22 +03:00
TheTutor - > OnEvent ( EVENT_PLAYER_LEFT_BUY_ZONE ) ;
2015-12-05 22:40:30 +03:00
}
2015-09-30 03:49:22 +03:00
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : RebuyPrimaryWeapon ( )
2015-09-30 03:49:22 +03:00
{
2017-10-19 20:12:02 +03:00
if ( ! m_rgpPlayerItems [ PRIMARY_WEAPON_SLOT ] )
2015-09-30 03:49:22 +03:00
{
if ( m_rebuyStruct . m_primaryWeapon )
{
const char * alias = WeaponIDToAlias ( m_rebuyStruct . m_primaryWeapon ) ;
2016-12-06 22:21:52 +03:00
if ( alias )
2015-09-30 03:49:22 +03:00
ClientCommand ( alias ) ;
}
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : RebuyPrimaryAmmo ( )
2015-09-30 03:49:22 +03:00
{
2017-10-19 20:12:02 +03:00
CBasePlayerWeapon * pPrimary = static_cast < CBasePlayerWeapon * > ( m_rgpPlayerItems [ PRIMARY_WEAPON_SLOT ] ) ;
if ( pPrimary )
2015-09-30 03:49:22 +03:00
{
2016-01-06 15:50:26 +03:00
// if we had more ammo before than we have now, buy more.
2017-10-19 20:12:02 +03:00
if ( m_rebuyStruct . m_primaryAmmo > m_rgAmmo [ pPrimary - > m_iPrimaryAmmoType ] ) {
2015-09-30 03:49:22 +03:00
ClientCommand ( " primammo " ) ;
2017-10-19 20:12:02 +03:00
}
2015-09-30 03:49:22 +03:00
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : RebuySecondaryWeapon ( )
2015-09-30 03:49:22 +03:00
{
if ( m_rebuyStruct . m_secondaryWeapon )
{
const char * alias = WeaponIDToAlias ( m_rebuyStruct . m_secondaryWeapon ) ;
2017-10-19 20:12:02 +03:00
if ( alias ) {
2015-09-30 03:49:22 +03:00
ClientCommand ( alias ) ;
2017-10-19 20:12:02 +03:00
}
2015-09-30 03:49:22 +03:00
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : RebuySecondaryAmmo ( )
2015-09-30 03:49:22 +03:00
{
2017-10-19 20:12:02 +03:00
CBasePlayerWeapon * pSecondary = static_cast < CBasePlayerWeapon * > ( m_rgpPlayerItems [ PISTOL_SLOT ] ) ;
if ( pSecondary )
2015-09-30 03:49:22 +03:00
{
2017-10-19 20:12:02 +03:00
if ( m_rebuyStruct . m_secondaryAmmo > m_rgAmmo [ pSecondary - > m_iPrimaryAmmoType ] ) {
2015-09-30 03:49:22 +03:00
ClientCommand ( " secammo " ) ;
2017-10-19 20:12:02 +03:00
}
2015-09-30 03:49:22 +03:00
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : RebuyHEGrenade ( )
2015-09-30 03:49:22 +03:00
{
int iAmmoIndex = GetAmmoIndex ( " HEGrenade " ) ;
if ( iAmmoIndex = = - 1 )
return ;
2017-10-19 20:12:02 +03:00
int numToBuy = m_rebuyStruct . m_heGrenade - m_rgAmmo [ iAmmoIndex ] ;
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < numToBuy ; i + + )
2015-09-30 03:49:22 +03:00
ClientCommand ( " hegren " ) ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : RebuyFlashbang ( )
2015-09-30 03:49:22 +03:00
{
int iAmmoIndex = GetAmmoIndex ( " Flashbang " ) ;
if ( iAmmoIndex = = - 1 )
return ;
2017-10-19 20:12:02 +03:00
int numToBuy = m_rebuyStruct . m_flashbang - m_rgAmmo [ iAmmoIndex ] ;
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < numToBuy ; i + + )
2015-09-30 03:49:22 +03:00
ClientCommand ( " flash " ) ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : RebuySmokeGrenade ( )
2015-09-30 03:49:22 +03:00
{
int iAmmoIndex = GetAmmoIndex ( " SmokeGrenade " ) ;
if ( iAmmoIndex = = - 1 )
return ;
2017-10-19 20:12:02 +03:00
int numToBuy = m_rebuyStruct . m_smokeGrenade - m_rgAmmo [ iAmmoIndex ] ;
2017-10-13 03:04:37 +03:00
for ( int i = 0 ; i < numToBuy ; i + + )
2015-09-30 03:49:22 +03:00
ClientCommand ( " sgren " ) ;
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : RebuyDefuser ( )
2015-09-30 03:49:22 +03:00
{
2016-01-06 15:50:26 +03:00
// If we don't have a defuser, and we want one, buy it!
if ( m_rebuyStruct . m_defuser & & ! m_bHasDefuser )
2015-09-30 03:49:22 +03:00
{
2016-01-06 15:50:26 +03:00
ClientCommand ( " defuser " ) ;
2015-09-30 03:49:22 +03:00
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : RebuyNightVision ( )
2015-09-30 03:49:22 +03:00
{
2016-01-06 15:50:26 +03:00
// If we don't have night vision and we want one, buy it!
if ( m_rebuyStruct . m_nightVision & & ! m_bHasNightVision )
2015-09-30 03:49:22 +03:00
{
2016-01-06 15:50:26 +03:00
ClientCommand ( " nvgs " ) ;
2015-09-30 03:49:22 +03:00
}
}
2016-02-04 03:18:26 +03:00
void CBasePlayer : : RebuyArmor ( )
2015-09-30 03:49:22 +03:00
{
if ( m_rebuyStruct . m_armor )
{
if ( m_rebuyStruct . m_armor > m_iKevlar )
{
2016-05-17 21:01:46 +03:00
if ( m_rebuyStruct . m_armor = = ARMOR_KEVLAR )
2015-09-30 03:49:22 +03:00
ClientCommand ( " vest " ) ;
else
ClientCommand ( " vesthelm " ) ;
}
}
}
bool CBasePlayer : : IsObservingPlayer ( CBasePlayer * pPlayer )
{
if ( ! pPlayer | | pev - > flags = = FL_DORMANT )
return false ;
if ( FNullEnt ( pPlayer ) )
return false ;
2018-02-08 12:37:02 +03:00
return ( GetObserverMode ( ) = = OBS_IN_EYE & & pev - > iuser2 = = pPlayer - > entindex ( ) ) ! = 0 ;
2015-09-30 03:49:22 +03:00
}
void CBasePlayer : : UpdateLocation ( bool forceUpdate )
{
2016-02-23 02:13:52 +03:00
if ( ! forceUpdate & & m_flLastUpdateTime > = gpGlobals - > time + 2.0f )
2015-09-30 03:49:22 +03:00
return ;
2024-04-08 12:42:08 +03:00
const char * placeName = nullptr ;
2015-09-30 03:49:22 +03:00
2024-04-07 12:41:56 +03:00
if ( pev - > deadflag = = DEAD_NO & & (
# ifdef REGAMEDLL_ADD
2024-04-08 12:42:08 +03:00
( location_area_info . value = = 1 | | location_area_info . value = = 3 ) | |
2024-04-07 12:41:56 +03:00
# endif
AreBotsAllowed ( ) ) )
2015-09-30 03:49:22 +03:00
{
// search the place name where is located the player
Place playerPlace = TheNavAreaGrid . GetPlace ( & pev - > origin ) ;
const BotPhraseList * placeList = TheBotPhrases - > GetPlaceList ( ) ;
2017-10-13 03:04:37 +03:00
for ( auto phrase : * placeList )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
if ( phrase - > GetID ( ) = = playerPlace )
2015-09-30 03:49:22 +03:00
{
2017-10-13 03:04:37 +03:00
placeName = phrase - > GetName ( ) ;
2015-09-30 03:49:22 +03:00
break ;
}
}
2024-04-07 14:49:08 +03:00
2024-04-08 12:42:08 +03:00
if ( ! placeName )
2024-04-07 14:49:08 +03:00
placeName = TheNavAreaGrid . IDToName ( playerPlace ) ;
2015-09-30 03:49:22 +03:00
}
2024-04-08 08:41:22 +03:00
if ( ! placeName | | ! placeName [ 0 ] | | ( m_lastLocation [ 0 ] & & ! Q_strcmp ( placeName , & m_lastLocation [ 1 ] ) ) )
2015-09-30 03:49:22 +03:00
{
return ;
}
m_flLastUpdateTime = gpGlobals - > time ;
Q_snprintf ( m_lastLocation , sizeof ( m_lastLocation ) , " #%s " , placeName ) ;
2017-10-13 03:04:37 +03:00
for ( int i = 1 ; i < = gpGlobals - > maxClients ; i + + )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
CBasePlayer * pPlayer = UTIL_PlayerByIndex ( i ) ;
2015-09-30 03:49:22 +03:00
2017-11-22 20:27:55 +03:00
if ( ! pPlayer )
2015-09-30 03:49:22 +03:00
continue ;
2017-11-22 20:27:55 +03:00
if ( pPlayer - > m_iTeam = = m_iTeam | | pPlayer - > m_iTeam = = SPECTATOR )
2015-09-30 03:49:22 +03:00
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgLocation , nullptr , pPlayer - > edict ( ) ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( entindex ( ) ) ;
WRITE_STRING ( m_lastLocation ) ;
MESSAGE_END ( ) ;
}
else if ( forceUpdate )
{
2017-11-22 20:27:55 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgLocation , nullptr , pPlayer - > edict ( ) ) ;
2015-09-30 03:49:22 +03:00
WRITE_BYTE ( entindex ( ) ) ;
WRITE_STRING ( " " ) ;
MESSAGE_END ( ) ;
}
}
}
2016-06-03 18:32:33 +03:00
2016-06-08 00:41:07 +03:00
void CBasePlayer : : ReloadWeapons ( CBasePlayerItem * pWeapon , bool bForceReload , bool bForceRefill )
2016-06-03 18:32:33 +03:00
{
2016-06-08 00:41:07 +03:00
# ifdef REGAMEDLL_ADD
bool bCanAutoReload = ( bForceReload | | auto_reload_weapons . value ! = 0.0f ) ;
bool bCanRefillBPAmmo = ( bForceRefill | | refill_bpammo_weapons . value ! = 0.0f ) ;
if ( ! bCanAutoReload & & ! bCanRefillBPAmmo )
return ;
2016-06-03 18:32:33 +03:00
// if we died in the previous round
// so that we have nothing to reload
if ( ! m_bNotKilled )
return ;
// to ignore first spawn on ClientPutinServer
if ( m_bJustConnected )
return ;
2017-10-13 03:04:37 +03:00
for ( int i = PRIMARY_WEAPON_SLOT ; i < = PISTOL_SLOT ; i + + )
2016-06-03 18:32:33 +03:00
{
auto item = m_rgpPlayerItems [ i ] ;
2016-12-06 22:21:52 +03:00
while ( item )
2016-06-03 18:32:33 +03:00
{
if ( pWeapon = = nullptr | | pWeapon = = item )
2016-06-08 00:41:07 +03:00
{
if ( bCanRefillBPAmmo ) {
2017-10-19 20:12:02 +03:00
m_rgAmmo [ item - > PrimaryAmmoIndex ( ) ] = item - > iMaxAmmo1 ( ) ;
2016-06-08 00:41:07 +03:00
}
if ( bCanAutoReload ) {
( ( CBasePlayerWeapon * ) item ) - > InstantReload ( bCanRefillBPAmmo ) ;
}
}
2016-06-03 18:32:33 +03:00
if ( pWeapon = = item )
break ;
item = item - > m_pNext ;
}
2016-12-06 22:21:52 +03:00
if ( pWeapon & & pWeapon = = item )
2016-06-03 18:32:33 +03:00
break ;
}
2016-06-08 00:41:07 +03:00
# endif
2016-06-03 18:32:33 +03:00
}
2016-06-15 00:21:34 +03:00
void CBasePlayer : : TeamChangeUpdate ( )
{
MESSAGE_BEGIN ( MSG_ALL , gmsgTeamInfo ) ;
WRITE_BYTE ( entindex ( ) ) ;
WRITE_STRING ( GetTeamName ( m_iTeam ) ) ;
MESSAGE_END ( ) ;
if ( m_iTeam ! = UNASSIGNED )
{
SetScoreboardAttributes ( ) ;
}
}
2016-06-20 22:32:02 +03:00
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CHAIN ( bool , CBasePlayer , HasRestrictItem , ( ItemID item , ItemRestType type ) , item , type )
2016-06-20 22:32:02 +03:00
bool EXT_FUNC CBasePlayer : : __API_HOOK ( HasRestrictItem ) ( ItemID item , ItemRestType type ) {
return false ;
}
2016-07-14 17:12:17 +03:00
void CBasePlayer : : DropSecondary ( )
{
if ( HasShield ( ) )
{
if ( IsProtectedByShield ( ) & & m_pActiveItem ) {
( ( CBasePlayerWeapon * ) m_pActiveItem ) - > SecondaryAttack ( ) ;
}
m_bShieldDrawn = false ;
}
# ifdef REGAMEDLL_ADD
2016-10-07 15:19:51 +03:00
ForEachItem ( PISTOL_SLOT , [ this ] ( CBasePlayerItem * item ) {
2016-07-14 17:12:17 +03:00
DropPlayerItem ( STRING ( item - > pev - > classname ) ) ;
2016-10-07 15:19:51 +03:00
return false ;
} ) ;
2016-07-14 17:12:17 +03:00
# else
2017-10-19 20:12:02 +03:00
auto item = m_rgpPlayerItems [ PISTOL_SLOT ] ;
2016-07-14 17:12:17 +03:00
if ( item )
{
DropPlayerItem ( STRING ( item - > pev - > classname ) ) ;
}
# endif
}
void CBasePlayer : : DropPrimary ( )
{
if ( HasShield ( ) ) {
DropShield ( ) ;
return ;
}
# ifdef REGAMEDLL_ADD
2016-10-07 15:19:51 +03:00
ForEachItem ( PRIMARY_WEAPON_SLOT , [ this ] ( CBasePlayerItem * item ) {
2016-07-14 17:12:17 +03:00
DropPlayerItem ( STRING ( item - > pev - > classname ) ) ;
2016-10-07 15:19:51 +03:00
return false ;
} ) ;
2016-07-14 17:12:17 +03:00
# else
2017-10-19 20:12:02 +03:00
auto item = m_rgpPlayerItems [ PRIMARY_WEAPON_SLOT ] ;
2016-07-14 17:12:17 +03:00
if ( item )
{
DropPlayerItem ( STRING ( item - > pev - > classname ) ) ;
}
# endif
}
2016-09-26 23:16:33 +03:00
2016-10-07 15:19:51 +03:00
CBasePlayerItem * CBasePlayer : : GetItemByName ( const char * itemName ) {
2016-12-06 22:21:52 +03:00
return ForEachItem ( [ itemName ] ( CBasePlayerItem * item ) {
2016-10-07 15:19:51 +03:00
return FClassnameIs ( item - > pev , itemName ) ;
} ) ;
}
2016-09-26 23:16:33 +03:00
2016-10-07 15:19:51 +03:00
CBasePlayerItem * CBasePlayer : : GetItemById ( WeaponIdType weaponID ) {
2016-12-06 22:21:52 +03:00
return ForEachItem ( [ weaponID ] ( CBasePlayerItem * item ) {
2016-10-07 15:19:51 +03:00
return item - > m_iId = = weaponID ;
} ) ;
2016-09-26 23:16:33 +03:00
}
void CBasePlayer : : RemoveBomb ( )
{
2016-10-07 15:19:51 +03:00
auto pBomb = GetItemByName ( " weapon_c4 " ) ;
2016-09-26 23:16:33 +03:00
if ( ! pBomb )
return ;
m_bHasC4 = false ;
pev - > body = 0 ;
SetBombIcon ( FALSE ) ;
SetProgressBarTime ( 0 ) ;
if ( m_pActiveItem = = pBomb ) {
( ( CBasePlayerWeapon * ) pBomb ) - > RetireWeapon ( ) ;
}
if ( RemovePlayerItem ( pBomb ) ) {
pev - > weapons & = ~ ( 1 < < pBomb - > m_iId ) ;
2019-10-09 13:18:42 +03:00
# ifdef REGAMEDLL_FIXES
// No more weapon
if ( ( pev - > weapons & ~ ( 1 < < WEAPON_SUIT ) ) = = 0 ) {
m_iHideHUD | = HIDEHUD_WEAPONS ;
}
# endif
2016-09-26 23:16:33 +03:00
pBomb - > Kill ( ) ;
}
}
2016-10-11 14:51:28 +03:00
2023-10-11 01:02:27 +03:00
void CBasePlayer : : GiveDefuser ( )
{
m_bHasDefuser = true ;
pev - > body = 1 ;
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pev ) ;
WRITE_BYTE ( STATUSICON_SHOW ) ;
WRITE_STRING ( " defuser " ) ;
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( 160 ) ;
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
SendItemStatus ( ) ;
# if defined(REGAMEDLL_FIXES) || defined(BUILD_LATEST)
SetScoreboardAttributes ( ) ;
# endif
}
2019-06-21 23:19:32 +03:00
void CBasePlayer : : RemoveDefuser ( )
{
m_bHasDefuser = false ;
pev - > body = 0 ;
2023-09-05 06:52:44 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pev ) ;
WRITE_BYTE ( STATUSICON_HIDE ) ;
WRITE_STRING ( " defuser " ) ;
MESSAGE_END ( ) ;
SendItemStatus ( ) ;
# ifdef REGAMEDLL_FIXES
if ( m_bIsDefusing )
{
SetProgressBarTime ( 0 ) ;
m_bIsDefusing = false ;
}
2023-09-28 12:18:15 +03:00
# else
2023-09-05 06:52:44 +03:00
SetProgressBarTime ( 0 ) ;
# endif
}
CItemThighPack * SpawnDefuser ( const Vector & vecOrigin , edict_t * pentOwner )
{
CItemThighPack * pDefuser = ( CItemThighPack * ) CBaseEntity : : Create ( " item_thighpack " , vecOrigin , g_vecZero , pentOwner ) ;
if ( pDefuser )
{
pDefuser - > SetThink ( & CBaseEntity : : SUB_Remove ) ;
pDefuser - > pev - > nextthink = gpGlobals - > time + CGameRules : : GetItemKillDelay ( ) ;
pDefuser - > pev - > spawnflags | = SF_NORESPAWN ;
}
return pDefuser ;
2019-06-21 23:19:32 +03:00
}
2016-10-11 14:51:28 +03:00
void CBasePlayer : : Disconnect ( )
{
2017-10-13 03:04:37 +03:00
SetThink ( nullptr ) ;
2016-10-11 14:51:28 +03:00
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , OnSpawnEquip , ( bool addDefault , bool equipGame ) , addDefault , equipGame )
2016-12-06 22:21:52 +03:00
void EXT_FUNC CBasePlayer : : __API_HOOK ( OnSpawnEquip ) ( bool addDefault , bool equipGame )
{
if ( equipGame )
{
2021-05-22 14:15:28 +03:00
CGamePlayerEquip * pWeaponEntity = nullptr ;
2016-12-06 22:21:52 +03:00
while ( ( pWeaponEntity = UTIL_FindEntityByClassname ( pWeaponEntity , " game_player_equip " ) ) )
{
2021-05-22 14:15:28 +03:00
# ifdef REGAMEDLL_FIXES
if ( pWeaponEntity - > CanEquipOverTouch ( this ) )
# endif
{
pWeaponEntity - > Touch ( this ) ;
addDefault = false ;
}
2016-12-06 22:21:52 +03:00
}
}
if ( m_bNotKilled )
addDefault = false ;
if ( addDefault | | m_bIsVIP )
{
GiveDefaultItems ( ) ;
}
2021-06-22 14:48:55 +03:00
# ifdef REGAMEDLL_ADD
2022-11-24 19:04:42 +03:00
if ( ! m_bIsVIP )
2021-06-22 14:48:55 +03:00
{
switch ( static_cast < ArmorType > ( ( int ) free_armor . value ) )
{
2021-10-14 16:10:16 +03:00
case ARMOR_KEVLAR : GiveNamedItemEx ( " item_kevlar " ) ; break ;
case ARMOR_VESTHELM : GiveNamedItemEx ( " item_assaultsuit " ) ; break ;
2021-06-22 14:48:55 +03:00
}
}
2024-01-12 11:55:00 +03:00
if ( NeedsDefuseKit ( ) & & ( int ) defuser_allocation . value = = DEFUSERALLOCATION_ALL )
GiveNamedItemEx ( " item_thighpack " ) ;
2021-06-22 14:48:55 +03:00
# endif
2016-12-06 22:21:52 +03:00
}
void CBasePlayer : : HideTimer ( )
{
// HACK HACK, we need to hide only the timer.
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBombDrop , nullptr , pev ) ;
2016-12-06 22:21:52 +03:00
WRITE_COORD ( 0 ) ;
WRITE_COORD ( 0 ) ;
WRITE_COORD ( 0 ) ;
WRITE_BYTE ( BOMB_FLAG_PLANTED ) ;
MESSAGE_END ( ) ;
2017-10-13 03:04:37 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgBombPickup , nullptr , pev ) ;
2016-12-06 22:21:52 +03:00
MESSAGE_END ( ) ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CHAIN2 ( bool , CBasePlayer , MakeBomber )
2016-12-06 22:21:52 +03:00
bool EXT_FUNC CBasePlayer : : __API_HOOK ( MakeBomber ) ( )
{
2017-10-13 03:04:37 +03:00
if ( ! GiveNamedItemEx ( " weapon_c4 " ) )
2016-12-06 22:21:52 +03:00
{
// something happened?
// C4 failed to attach to the player
return false ;
}
m_bHasC4 = true ;
pev - > body = 1 ;
2023-11-26 07:24:29 +03:00
SetBombIcon ( ) ;
2016-12-06 22:21:52 +03:00
m_flDisplayHistory | = DHF_BOMB_RETRIEVED ;
HintMessage ( " #Hint_you_have_the_bomb " , FALSE , TRUE ) ;
// Log this information
UTIL_LogPrintf ( " \" %s<%i><%s><TERRORIST> \" triggered \" Spawned_With_The_Bomb \" \n " , STRING ( pev - > netname ) , GETPLAYERUSERID ( edict ( ) ) , GETPLAYERAUTHID ( edict ( ) ) ) ;
g_pGameRules - > m_bBombDropped = FALSE ;
return true ;
}
2017-01-29 02:56:29 +03:00
LINK_HOOK_CLASS_CHAIN2 ( bool , CBasePlayer , GetIntoGame )
2016-12-06 22:21:52 +03:00
bool EXT_FUNC CBasePlayer : : __API_HOOK ( GetIntoGame ) ( )
{
m_bNotKilled = false ;
m_iIgnoreGlobalChat = IGNOREMSG_NONE ;
m_iTeamKills = 0 ;
m_iFOV = DEFAULT_FOV ;
Q_memset ( & m_rebuyStruct , 0 , sizeof ( m_rebuyStruct ) ) ;
m_bIsInRebuy = false ;
m_bJustConnected = false ;
m_fLastMovement = gpGlobals - > time ;
ResetMaxSpeed ( ) ;
m_iJoiningState = JOINED ;
if ( CSGameRules ( ) - > m_bMapHasEscapeZone & & m_iTeam = = CT )
{
# ifndef REGAMEDLL_ADD
m_iAccount = 0 ;
# endif
CheckStartMoney ( ) ;
AddAccount ( startmoney . value , RT_INTO_GAME ) ;
}
if ( g_pGameRules - > FPlayerCanRespawn ( this ) )
{
Spawn ( ) ;
CSGameRules ( ) - > CheckWinConditions ( ) ;
2019-12-17 01:13:33 +03:00
if ( ! CSGameRules ( ) - > m_flRestartRoundTime & & CSGameRules ( ) - > m_bMapHasBombTarget & & ! CSGameRules ( ) - > IsThereABomber ( ) & & ! CSGameRules ( ) - > IsThereABomb ( )
# ifdef REGAMEDLL_ADD
& & give_player_c4 . value
# endif
)
2016-12-06 22:21:52 +03:00
{
CSGameRules ( ) - > GiveC4 ( ) ;
}
if ( m_iTeam = = TERRORIST )
{
CSGameRules ( ) - > m_iNumEscapers + + ;
}
}
else
{
pev - > deadflag = DEAD_RESPAWNABLE ;
MAKE_STRING_CLASS ( " player " , pev ) ;
pev - > flags & = ( FL_PROXY | FL_FAKECLIENT ) ;
pev - > flags | = ( FL_SPECTATOR | FL_CLIENT ) ;
edict_t * pentSpawnSpot = g_pGameRules - > GetPlayerSpawnSpot ( this ) ;
StartObserver ( pev - > origin , pentSpawnSpot - > v . angles ) ;
CSGameRules ( ) - > CheckWinConditions ( ) ;
MESSAGE_BEGIN ( MSG_ALL , gmsgTeamInfo ) ;
WRITE_BYTE ( entindex ( ) ) ;
WRITE_STRING ( GetTeamName ( m_iTeam ) ) ;
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_ALL , gmsgLocation ) ;
WRITE_BYTE ( entindex ( ) ) ;
WRITE_STRING ( " " ) ;
MESSAGE_END ( ) ;
MESSAGE_BEGIN ( MSG_ALL , gmsgScoreInfo ) ;
WRITE_BYTE ( ENTINDEX ( edict ( ) ) ) ;
WRITE_SHORT ( int ( pev - > frags ) ) ;
WRITE_SHORT ( m_iDeaths ) ;
WRITE_SHORT ( 0 ) ;
WRITE_SHORT ( m_iTeam ) ;
MESSAGE_END ( ) ;
if ( ! ( m_flDisplayHistory & DHF_SPEC_DUCK ) )
{
HintMessage ( " #Spec_Duck " , TRUE , TRUE ) ;
m_flDisplayHistory | = DHF_SPEC_DUCK ;
}
}
return true ;
}
2017-01-20 17:52:37 +03:00
void CBasePlayer : : PlayerRespawnThink ( )
{
# ifdef REGAMEDLL_ADD
2018-02-08 12:37:02 +03:00
if ( GetObserverMode ( ) ! = OBS_NONE & & ( m_iTeam = = UNASSIGNED | | m_iTeam = = SPECTATOR ) )
2017-01-20 17:52:37 +03:00
return ;
// Player cannot respawn while in the Choose Appearance menu
if ( m_iMenu = = Menu_ChooseAppearance | | m_iJoiningState = = SHOWTEAMSELECT )
return ;
if ( pev - > deadflag < DEAD_DYING )
return ;
2021-06-06 15:16:09 +03:00
if ( CSPlayer ( ) - > m_flRespawnPending > 0 )
2017-01-20 17:52:37 +03:00
{
2021-06-06 15:16:09 +03:00
if ( CSPlayer ( ) - > m_flRespawnPending < = gpGlobals - > time )
{
// Pending respawn caused by game doesn't respawn with disabled CVar
if ( CSPlayer ( ) - > m_bGameForcingRespawn & & ! forcerespawn . value )
{
CSPlayer ( ) - > m_flRespawnPending = 0.0f ;
CSPlayer ( ) - > m_bGameForcingRespawn = false ;
return ;
}
2020-05-27 04:20:59 +03:00
2021-06-06 15:16:09 +03:00
Spawn ( ) ;
pev - > button = 0 ;
pev - > nextthink = - 1 ;
return ;
}
}
else if ( pev - > deadflag = = DEAD_DEAD & & forcerespawn . value > 0 )
{
CSPlayer ( ) - > m_bGameForcingRespawn = true ;
CSPlayer ( ) - > m_flRespawnPending = gpGlobals - > time + forcerespawn . value ;
2017-01-20 17:52:37 +03:00
}
2021-06-06 15:16:09 +03:00
2017-01-20 17:52:37 +03:00
# endif
}
ReGameDLL API: Implemented hookchain's CSGameRules::CanPlayerHearPlayer, CBasePlayer::SwitchTeam, CBasePlayer::CanSwitchTeam, CBasePlayer::ThrowGrenade, CWeaponBox::SetModel, CGrenade::DefuseBombStart, CGrenade::DefuseBombEnd, CGrenade::ExplodeHeGrenade, CGrenade::ExplodeFlashbang, CGrenade::ExplodeSmokeGrenade, CGrenade::ExplodeBomb, ThrowHeGrenade, ThrowFlashbang, ThrowSmokeGrenade, PlantBomb
2018-01-27 19:31:30 +03:00
LINK_HOOK_CLASS_CHAIN ( bool , CBasePlayer , CanSwitchTeam , ( TeamName teamToSwap ) , teamToSwap )
bool CBasePlayer : : __API_HOOK ( CanSwitchTeam ) ( TeamName teamToSwap )
{
if ( m_iTeam ! = teamToSwap )
return false ;
// we won't VIP player to switch team
if ( CSGameRules ( ) - > m_pVIP = = this )
{
return false ;
}
return true ;
}
2018-02-18 14:31:24 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , SetSpawnProtection , ( float flProtectionTime ) , flProtectionTime )
void EXT_FUNC CBasePlayer : : __API_HOOK ( SetSpawnProtection ) ( float flProtectionTime )
{
2019-08-13 16:11:27 +03:00
# ifdef REGAMEDLL_ADD
if ( respawn_immunity_effects . value > 0 )
{
2022-12-15 16:04:34 +03:00
CSPlayer ( ) - > m_bSpawnProtectionEffects = true ;
2019-08-13 16:11:27 +03:00
pev - > rendermode = kRenderTransAdd ;
pev - > renderamt = 100.0f ;
2021-05-22 14:04:43 +03:00
2022-03-13 17:35:42 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pev ) ;
2021-05-22 14:04:43 +03:00
WRITE_BYTE ( STATUSICON_FLASH ) ;
WRITE_STRING ( " suithelmet_full " ) ;
WRITE_BYTE ( 0 ) ;
WRITE_BYTE ( 160 ) ;
WRITE_BYTE ( 0 ) ;
MESSAGE_END ( ) ;
2019-08-13 16:11:27 +03:00
}
2018-02-18 14:31:24 +03:00
CSPlayer ( ) - > m_flSpawnProtectionEndTime = gpGlobals - > time + flProtectionTime ;
2021-04-12 17:51:51 +03:00
# endif
2018-02-18 14:31:24 +03:00
}
LINK_HOOK_CLASS_VOID_CHAIN2 ( CBasePlayer , RemoveSpawnProtection )
void CBasePlayer : : __API_HOOK ( RemoveSpawnProtection ) ( )
{
2019-08-13 16:11:27 +03:00
# ifdef REGAMEDLL_ADD
2022-12-15 16:04:34 +03:00
if ( CSPlayer ( ) - > m_bSpawnProtectionEffects )
2019-08-13 16:11:27 +03:00
{
2022-12-15 16:04:34 +03:00
if ( pev - > rendermode = = kRenderTransAdd & & pev - > renderamt = = 100.0f )
2019-08-13 16:11:27 +03:00
{
2022-12-15 16:04:34 +03:00
pev - > renderamt = 255.0f ;
2019-08-13 16:11:27 +03:00
pev - > rendermode = kRenderNormal ;
}
2021-05-22 14:04:43 +03:00
MESSAGE_BEGIN ( MSG_ONE , gmsgStatusIcon , nullptr , pev ) ;
WRITE_BYTE ( STATUSICON_HIDE ) ;
WRITE_STRING ( " suithelmet_full " ) ;
MESSAGE_END ( ) ;
2022-12-15 16:04:34 +03:00
CSPlayer ( ) - > m_bSpawnProtectionEffects = false ;
2019-08-13 16:11:27 +03:00
}
2018-02-18 14:31:24 +03:00
CSPlayer ( ) - > m_flSpawnProtectionEndTime = 0.0f ;
2021-04-12 17:51:51 +03:00
# endif
2018-02-18 14:31:24 +03:00
}
2019-11-02 11:48:23 +03:00
LINK_HOOK_CLASS_VOID_CHAIN ( CBasePlayer , DropIdlePlayer , ( const char * reason ) , reason )
void EXT_FUNC CBasePlayer : : __API_HOOK ( DropIdlePlayer ) ( const char * reason )
{
if ( ! autokick . value )
return ;
edict_t * pEntity = edict ( ) ;
int iUserID = GETPLAYERUSERID ( pEntity ) ;
// Log the kick
UTIL_LogPrintf ( " \" %s<%i><%s><%s> \" triggered \" Game_idle_kick \" (auto) \n " , STRING ( pev - > netname ) , iUserID , GETPLAYERAUTHID ( pEntity ) , GetTeam ( m_iTeam ) ) ;
UTIL_ClientPrintAll ( HUD_PRINTCONSOLE , " #Game_idle_kick " , STRING ( pev - > netname ) ) ;
# ifdef REGAMEDLL_FIXES
if ( iUserID ! = - 1 )
{
SERVER_COMMAND ( UTIL_VarArgs ( " kick #%d \" %s \" \n " , iUserID , reason ) ) ;
}
# else
SERVER_COMMAND ( UTIL_VarArgs ( " kick \" %s \" \n " , STRING ( pev - > netname ) ) ) ;
# endif // #ifdef REGAMEDLL_FIXES
}
2022-12-17 19:45:04 +03:00
bool CBasePlayer : : Kill ( )
{
if ( GetObserverMode ( ) ! = OBS_NONE )
return false ;
2023-09-28 12:18:15 +03:00
2022-12-17 19:45:04 +03:00
if ( m_iJoiningState ! = JOINED )
return false ;
2023-09-28 12:18:15 +03:00
2022-12-17 19:45:04 +03:00
m_LastHitGroup = HITGROUP_GENERIC ;
// have the player kill himself
pev - > health = 0.0f ;
2024-04-04 15:31:27 +03:00
# ifdef REGAMEDLL_API
CSPlayer ( ) - > ResetAllStats ( ) ; // reset damage stats on killed himself or team change
# endif
2022-12-17 19:45:04 +03:00
Killed ( pev , GIB_NEVER ) ;
if ( CSGameRules ( ) - > m_pVIP = = this )
CSGameRules ( ) - > m_iConsecutiveVIP = 10 ;
2023-09-28 12:18:15 +03:00
2022-12-17 19:45:04 +03:00
return true ;
}