// Player has become a spectator. Set it up. // This was moved from player.cpp. void CBasePlayer::StartObserver( Vector vecPosition, Vector vecViewAngle ) { if( pev->iuser1 ) return; // clear any clientside entities attached to this player MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin ); WRITE_BYTE( TE_KILLPLAYERATTACHMENTS ); WRITE_BYTE( (BYTE)entindex() ); MESSAGE_END(); // Holster weapon immediately, to allow it to cleanup if (m_pActiveItem) m_pActiveItem->Holster( ); if ( m_pTank != NULL ) { m_pTank->Use( this, this, USE_OFF, 0 ); m_pTank = NULL; } // clear out the suit message cache so we don't keep chattering SetSuitUpdate(NULL, FALSE, 0); // Tell Ammo Hud that the player is dead MESSAGE_BEGIN( MSG_ONE, gmsgCurWeapon, NULL, pev ); WRITE_BYTE(0); WRITE_BYTE(0XFF); WRITE_BYTE(0xFF); MESSAGE_END(); // reset FOV and scope m_iFOV = m_iClientFOV = 0; pev->fov = m_iFOV; MESSAGE_BEGIN( MSG_ONE, gmsgSetFOV, NULL, pev ); WRITE_BYTE(0); MESSAGE_END(); MESSAGE_BEGIN( MSG_ONE, gmsgScopeToggle, NULL, pev ); WRITE_BYTE( 0 ); MESSAGE_END(); // Setup flags m_iHideHUD = (HIDEHUD_HEALTH | HIDEHUD_WEAPONS); m_afPhysicsFlags |= PFLAG_OBSERVER; pev->effects = EF_NODRAW; pev->view_ofs = g_vecZero; pev->angles = pev->v_angle = vecViewAngle; pev->fixangle = TRUE; pev->solid = SOLID_NOT; pev->takedamage = DAMAGE_NO; pev->movetype = MOVETYPE_NONE; ClearBits( m_afPhysicsFlags, PFLAG_DUCKING ); ClearBits( pev->flags, FL_DUCKING ); pev->deadflag = DEAD_RESPAWNABLE; pev->health = 1; // Clear out the status bar m_fInitHUD = TRUE; // Remove all the player's stuff RemoveAllItems( FALSE ); // Move them to the new position UTIL_SetOrigin( pev, vecPosition ); // Find a player to watch m_flNextObserverInput = 0; Observer_SetMode(OBS_CHASE_LOCKED); // Tell all clients this player is now a spectator // Update Team Status pev->team = 0; MESSAGE_BEGIN( MSG_ALL, gmsgScoreInfo ); WRITE_BYTE( ENTINDEX( edict() ) ); // client number WRITE_SHORT( pev->frags ); WRITE_SHORT( m_iDeaths ); WRITE_SHORT( 1 ); WRITE_SHORT( pev->team ); MESSAGE_END(); }
void CBasePlayer::CheckTimeBasedDamage() { byte bDuration = 0; if( !( m_bitsDamageType & DMG_TIMEBASED ) ) return; // only check for time based damage approx. every 2 seconds if( fabs( gpGlobals->time - m_tbdPrev ) < 2.0 ) return; m_tbdPrev = gpGlobals->time; for( int i = 0; i < CDMG_TIMEBASED; ++i ) { // make sure bit is set for damage type if( m_bitsDamageType & ( DMG_PARALYZE << i ) ) { switch( i ) { case itbd_Paralyze: // UNDONE - flag movement as half-speed bDuration = PARALYZE_DURATION; break; case itbd_NerveGas: //TakeDamage( this, this, NERVEGAS_DAMAGE, DMG_GENERIC ); bDuration = NERVEGAS_DURATION; break; case itbd_Poison: TakeDamage( this, this, POISON_DAMAGE, DMG_GENERIC ); bDuration = POISON_DURATION; break; case itbd_Radiation: //TakeDamage( this, this, RADIATION_DAMAGE, DMG_GENERIC ); bDuration = RADIATION_DURATION; break; case itbd_DrownRecover: // NOTE: this hack is actually used to RESTORE health // after the player has been drowning and finally takes a breath if( m_idrowndmg > m_idrownrestored ) { int idif = min( m_idrowndmg - m_idrownrestored, 10 ); GiveHealth( idif, DMG_GENERIC ); m_idrownrestored += idif; } bDuration = 4; // get up to 5*10 = 50 points back break; case itbd_Acid: //TakeDamage(pev, pev, ACID_DAMAGE, DMG_GENERIC); bDuration = ACID_DURATION; break; case itbd_SlowBurn: //TakeDamage(pev, pev, SLOWBURN_DAMAGE, DMG_GENERIC); bDuration = SLOWBURN_DURATION; break; case itbd_SlowFreeze: //TakeDamage(pev, pev, SLOWFREEZE_DAMAGE, DMG_GENERIC); bDuration = SLOWFREEZE_DURATION; break; default: bDuration = 0; } if( m_rgbTimeBasedDamage[ i ] ) { // use up an antitoxin on poison or nervegas after a few seconds of damage if( ( ( i == itbd_NerveGas ) && ( m_rgbTimeBasedDamage[ i ] < NERVEGAS_DURATION ) ) || ( ( i == itbd_Poison ) && ( m_rgbTimeBasedDamage[ i ] < POISON_DURATION ) ) ) { if( m_rgItems[ ITEM_ANTIDOTE ] ) { m_rgbTimeBasedDamage[ i ] = 0; m_rgItems[ ITEM_ANTIDOTE ]--; SetSuitUpdate( "!HEV_HEAL4", SUIT_SENTENCE, SUIT_REPEAT_OK ); } } // 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; } } }