Beispiel #1
0
// 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;
		}
	}
}