Exemplo n.º 1
0
void CSDKPlayer::CheckBallShield(const Vector &oldPos, Vector &newPos, const Vector &oldVel, Vector &newVel, const QAngle &oldAng, QAngle &newAng)
{
	bool stopPlayer = false;
	const float border = (GetFlags() & FL_SHIELD_KEEP_IN) ? -mp_shield_border.GetInt() : mp_shield_border.GetInt();

	int forward;
#ifdef CLIENT_DLL
	forward = GetPlayersTeam(this)->m_nForward;
#else
	forward = GetTeam()->m_nForward;
#endif

	if (SDKGameRules()->m_nShieldType != SHIELD_NONE)
	{
		if (SDKGameRules()->m_nShieldType == SHIELD_GOALKICK || 
			SDKGameRules()->m_nShieldType == SHIELD_PENALTY ||
			SDKGameRules()->m_nShieldType == SHIELD_FREEKICK ||
			(SDKGameRules()->m_nShieldType == SHIELD_KICKOFF && !SDKGameRules()->IsIntermissionState()) ||
			SDKGameRules()->m_nShieldType == SHIELD_CORNER)
		{
			const float radius = mp_shield_ball_radius.GetFloat();
			Vector dir = newPos - SDKGameRules()->m_vShieldPos;

			if (dir.Length2DSqr() < pow(radius, 2))
			{
				dir.z = 0;
				dir.NormalizeInPlace();
				newPos = SDKGameRules()->m_vShieldPos + dir * radius;
				stopPlayer = true;
			}
		}

		if (SDKGameRules()->m_nShieldType == SHIELD_GOALKICK || 
			SDKGameRules()->m_nShieldType == SHIELD_PENALTY ||
			SDKGameRules()->m_nShieldType == SHIELD_KEEPERHANDS)
		{
			int side = (SDKGameRules()->m_nShieldType == SHIELD_PENALTY ? GetGlobalTeam(SDKGameRules()->m_nShieldTeam)->GetOppTeamNumber() : SDKGameRules()->m_nShieldTeam);
			Vector min = GetGlobalTeam(side)->m_vPenBoxMin - border;
			Vector max = GetGlobalTeam(side)->m_vPenBoxMax + border;

			if (GetFlags() & FL_SHIELD_KEEP_OUT || SDKGameRules()->m_nShieldType == SHIELD_PENALTY)
			{
				if (SDKGameRules()->m_vKickOff.GetY() > min.y)
					min.y -= 500;
				else
					max.y += 500;
			}

			bool isInsideBox = newPos.x > min.x && newPos.y > min.y && newPos.x < max.x && newPos.y < max.y; 
			Vector boxCenter = (min + max) / 2;

			if (GetFlags() & FL_SHIELD_KEEP_OUT && isInsideBox)
			{
				bool oldPosInBox = true;

				if (newPos.x > min.x && oldPos.x <= min.x && newPos.x < boxCenter.x)
				{
					newPos.x = min.x;
					oldPosInBox = false; 
				}
				else if (newPos.x < max.x && oldPos.x >= max.x && newPos.x > boxCenter.x)
				{
					newPos.x = max.x;
					oldPosInBox = false; 
				}

				if (newPos.y > min.y && oldPos.y <= min.y && newPos.y < boxCenter.y)
				{
					newPos.y = min.y;
					oldPosInBox = false; 
				}
				else if (newPos.y < max.y && oldPos.y >= max.y && newPos.y > boxCenter.y)
				{
					newPos.y = max.y;
					oldPosInBox = false; 
				}

				stopPlayer = true;

				if (SDKGameRules()->m_nShieldType == SHIELD_KEEPERHANDS && oldPosInBox)
				{
					Vector goalCenter = GetGlobalTeam(SDKGameRules()->m_nShieldTeam)->m_vGoalCenter;
					goalCenter.y -= GetGlobalTeam(SDKGameRules()->m_nShieldTeam)->m_nForward * 500;

					if ((goalCenter - newPos).Length2DSqr() < (goalCenter - oldPos).Length2DSqr())
					{
						newPos.x = oldPos.x;
						newPos.y = oldPos.y;
						stopPlayer = true;
					}
					else
						stopPlayer = false;
				}
			}
			else if (GetFlags() & FL_SHIELD_KEEP_IN && !isInsideBox)
			{
				if (newPos.x < min.x)
					newPos.x = min.x;
				else if (newPos.x > max.x)
					newPos.x = max.x;

				if (newPos.y < min.y)
					newPos.y = min.y;
				else if (newPos.y > max.y)
					newPos.y = max.y;

				stopPlayer = true;
			}
		}

		if (SDKGameRules()->m_nShieldType == SHIELD_THROWIN && GetFlags() & FL_SHIELD_KEEP_OUT ||
			SDKGameRules()->m_nShieldType == SHIELD_FREEKICK || 
			SDKGameRules()->m_nShieldType == SHIELD_CORNER ||  
			SDKGameRules()->m_nShieldType == SHIELD_KICKOFF ||
			SDKGameRules()->m_nShieldType == SHIELD_PENALTY && (GetFlags() & FL_SHIELD_KEEP_OUT))
		{
			float radius = SDKGameRules()->GetShieldRadius(GetTeamNumber(), GetFlags() & FL_SHIELD_KEEP_IN) + border;
			Vector dir = newPos - SDKGameRules()->m_vShieldPos;

			if (!SDKGameRules()->IsIntermissionState() &&
				((GetFlags() & FL_SHIELD_KEEP_OUT) && dir.Length2D() < radius ||
				(GetFlags() & FL_SHIELD_KEEP_IN) && dir.Length2D() > radius))
			{
				dir.z = 0;
				dir.NormalizeInPlace();
				newPos = SDKGameRules()->m_vShieldPos + dir * radius;
				stopPlayer = true;
			}

			if (SDKGameRules()->m_nShieldType == SHIELD_KICKOFF && (GetFlags() & FL_SHIELD_KEEP_OUT)
				&& (!SDKGameRules()->IsIntermissionState() || SDKGameRules()->State_Get() == MATCH_PERIOD_WARMUP && mp_shield_block_opponent_half.GetBool()))
			{
				int forward;
				#ifdef CLIENT_DLL
					forward = GetPlayersTeam(this)->m_nForward;
				#else
					forward = GetTeam()->m_nForward;
				#endif
				float yBorder = SDKGameRules()->m_vKickOff.GetY() - abs(border) * forward;
				if (ZeroSign(newPos.y - yBorder) == forward)
				{
					newPos.y = yBorder;
					stopPlayer = true;
				}
			}

			if (SDKGameRules()->m_nShieldType == SHIELD_FREEKICK && mp_shield_block_sixyardbox.GetBool())
			{
				int teamPosType;
				#ifdef CLIENT_DLL
					teamPosType = GameResources()->GetTeamPosType(entindex());
				#else
					teamPosType = GetTeamPosType();
				#endif
				if (teamPosType != POS_GK || GetTeamNumber() != GetGlobalTeam(SDKGameRules()->m_nShieldTeam)->GetOppTeamNumber())
				{
					int side = GetGlobalTeam(SDKGameRules()->m_nShieldTeam)->GetOppTeamNumber();
					Vector min = GetGlobalTeam(side)->m_vSixYardBoxMin - border;
					Vector max = GetGlobalTeam(side)->m_vSixYardBoxMax + border;

					if (GetGlobalTeam(side)->m_nForward == 1)
						min.y -= 500;
					else
						max.y += 500;

					bool isInsideBox = newPos.x > min.x && newPos.y > min.y && newPos.x < max.x && newPos.y < max.y; 
					Vector boxCenter = (min + max) / 2;

					if (isInsideBox)
					{
						if (newPos.x > min.x && oldPos.x <= min.x && newPos.x < boxCenter.x)
							newPos.x = min.x;
						else if (newPos.x < max.x && oldPos.x >= max.x && newPos.x > boxCenter.x)
							newPos.x = max.x;

						if (newPos.y > min.y && oldPos.y <= min.y && newPos.y < boxCenter.y)
							newPos.y = min.y;
						else if (newPos.y < max.y && oldPos.y >= max.y && newPos.y > boxCenter.y)
							newPos.y = max.y;

						stopPlayer = true;
					}
				}
			}
		}

		if (SDKGameRules()->m_nShieldType == SHIELD_THROWIN && GetFlags() & FL_SHIELD_KEEP_IN)
		{
			const int xLength = mp_shield_throwin_movement_x.GetInt();
			const int yLength = mp_shield_throwin_movement_y.GetInt();
			Vector xSign = SDKGameRules()->m_vShieldPos.GetX() > SDKGameRules()->m_vKickOff.GetX() ? 1 : -1;
			Vector min = SDKGameRules()->m_vShieldPos + Vector(xSign == -1 ? -xLength : 0, -yLength / 2, 0);
			Vector max = SDKGameRules()->m_vShieldPos + Vector(xSign == -1 ? 0 : xLength, yLength / 2, 0);

			bool isInsideBox = newPos.x > min.x && newPos.y > min.y && newPos.x < max.x && newPos.y < max.y;

			if (!isInsideBox)
			{
				if (newPos.x < min.x)
					newPos.x = min.x;
				else if (newPos.x > max.x)
					newPos.x = max.x;

				if (newPos.y < min.y)
					newPos.y = min.y;
				else if (newPos.y > max.y)
					newPos.y = max.y;

				stopPlayer = true;
			}
		}
	}

	if (!SDKGameRules()->IsIntermissionState() && mp_field_padding_enabled.GetBool())
	{
		float border = mp_field_padding.GetInt();
		Vector min = SDKGameRules()->m_vFieldMin - border;
		Vector max = SDKGameRules()->m_vFieldMax + border;

		if (newPos.x < min.x || newPos.y < min.y || newPos.x > max.x || newPos.y > max.y)
		{
			if (newPos.x < min.x)
				newPos.x = min.x;
			else if (newPos.x > max.x)
				newPos.x = max.x;

			if (newPos.y < min.y)
				newPos.y = min.y;
			else if (newPos.y > max.y)
				newPos.y = max.y;

			stopPlayer = true;
		}
	}

	if (stopPlayer)
	{
		//newVel = oldVel;
		trace_t	trace;
		UTIL_TraceHull(newPos, newPos, GetPlayerMins(), GetPlayerMaxs(), MASK_PLAYERSOLID, this, COLLISION_GROUP_PLAYER, &trace);

		if (trace.startsolid)
		{
			// Stay at the old pos since the new pos is taken
			newPos = oldPos;
		}

		Vector dir = newPos - oldPos;
		dir.z = 0;
		float speed = dir.NormalizeInPlace();
		newVel = dir * min(speed * 100, mp_runspeed.GetInt());
		//newVel.x = (newPos - oldPos).x * 100;
		//newVel.y = (newPos - oldPos).y * 100;
		//newPos = pos;
	}
}
Exemplo n.º 2
0
//-----------------------------------------------------------------------------
// 
//-----------------------------------------------------------------------------
void CObjectTeleporter::TeleporterThink( void )
{
	SetContextThink( &CObjectTeleporter::TeleporterThink, gpGlobals->curtime + BUILD_TELEPORTER_NEXT_THINK, TELEPORTER_THINK_CONTEXT );

	// At any point, if our match is not ready, revert to IDLE
	if ( IsDisabled() || IsRedeploying() || IsMatchingTeleporterReady() == false )
	{
		ShowDirectionArrow( false );

		if ( GetState() != TELEPORTER_STATE_IDLE && !IsUpgrading() )
		{
			SetState( TELEPORTER_STATE_IDLE );

			CObjectTeleporter *pMatch = GetMatchingTeleporter();
			if ( !pMatch )
			{
				// The other end has been destroyed. Revert back to L1.
				m_iUpgradeLevel = 1;

				// We need to adjust for any damage received if we downgraded
				float flHealthPercentage = GetHealth() / GetMaxHealthForCurrentLevel();
				SetMaxHealth( GetMaxHealthForCurrentLevel() );
				SetHealth( (int)( GetMaxHealthForCurrentLevel() * flHealthPercentage ) );
				m_iUpgradeMetal = 0;
			}
		}
		return;
	}

	if ( m_flMyNextThink && m_flMyNextThink > gpGlobals->curtime )
		return;

	// pMatch is not NULL and is not building
	CObjectTeleporter *pMatch = GetMatchingTeleporter();

	Assert( pMatch );
	Assert( pMatch->m_iState != TELEPORTER_STATE_BUILDING );

	switch ( m_iState )
	{
	// Teleporter is not yet active, do nothing
	case TELEPORTER_STATE_BUILDING:
	case TELEPORTER_STATE_UPGRADING:
		ShowDirectionArrow( false );
		break;

	default:
	case TELEPORTER_STATE_IDLE:
		// Do we have a match that is active?
		// Make sure both ends wait through full recharge time in case they get upgraded while recharging.
		if ( IsMatchingTeleporterReady() && !IsUpgrading() && gpGlobals->curtime > m_flRechargeTime )
		{
			SetState( TELEPORTER_STATE_READY );
			EmitSound( "Building_Teleporter.Ready" );

			if ( GetObjectMode() == TELEPORTER_TYPE_ENTRANCE )
			{
				ShowDirectionArrow( true );
			}
		}
		break;

	case TELEPORTER_STATE_READY:
		break;

	case TELEPORTER_STATE_SENDING:
		{
			pMatch->TeleporterReceive( m_hTeleportingPlayer, 1.0 );

			m_flRechargeTime = gpGlobals->curtime + ( BUILD_TELEPORTER_FADEOUT_TIME + BUILD_TELEPORTER_FADEIN_TIME + g_flTeleporterRechargeTimes[ GetUpgradeLevel() - 1] );
		
			// change state to recharging...
			SetState( TELEPORTER_STATE_RECHARGING );
		}
		break;

	case TELEPORTER_STATE_RECEIVING:
		{
			// get the position we'll move the player to
			Vector newPosition = GetAbsOrigin();
			newPosition.z += TELEPORTER_MAXS.z + 1;

			// Telefrag anyone in the way
			CBaseEntity *pEnts[256];
			Vector mins, maxs;
			Vector expand( 4, 4, 4 );

			mins = newPosition + VEC_HULL_MIN - expand;
			maxs = newPosition + VEC_HULL_MAX + expand;

			CTFPlayer *pTeleportingPlayer = m_hTeleportingPlayer.Get();

			// move the player
			if ( pTeleportingPlayer )
			{
				CUtlVector<CBaseEntity*> hPlayersToKill;
				bool bClear = true;

				// Telefrag any players in the way
				int numEnts = UTIL_EntitiesInBox( pEnts, 256, mins,	maxs, 0 );
				if ( numEnts )
				{
					//Iterate through the list and check the results
					for ( int i = 0; i < numEnts && bClear; i++ )
					{
						if ( pEnts[i] == NULL )
							continue;

						if ( pEnts[i] == this )
							continue;

						// kill players
						if ( pEnts[i]->IsPlayer() )
						{
							if ( !pTeleportingPlayer->InSameTeam(pEnts[i]) )
							{
								hPlayersToKill.AddToTail( pEnts[i] );
							}
							continue;
						}

						if ( pEnts[i]->IsBaseObject() )
							continue;

						// Solid entities will prevent a teleport
						if ( pEnts[i]->IsSolid() && pEnts[i]->ShouldCollide( pTeleportingPlayer->GetCollisionGroup(), MASK_ALL ) &&
							 g_pGameRules->ShouldCollide( pTeleportingPlayer->GetCollisionGroup(), pEnts[i]->GetCollisionGroup() ) )
						{
							// We're going to teleport into something solid. Abort & destroy this exit.
							bClear = false;
						}
					}
				}

				if ( bClear )
				{
					// Telefrag all enemy players we've found
					for ( int player = 0; player < hPlayersToKill.Count(); player++ )
					{
						CTakeDamageInfo info( this, pTeleportingPlayer, 1000, DMG_CRUSH, TF_DMG_TELEFRAG );
						hPlayersToKill[player]->TakeDamage( info );
					}

					pTeleportingPlayer->Teleport( &newPosition, &(GetAbsAngles()), &vec3_origin );

					// Unzoom if we are a sniper zoomed!
					if ( ( pTeleportingPlayer->GetPlayerClass()->GetClassIndex() == TF_CLASS_SNIPER ) &&
						pTeleportingPlayer->m_Shared.InCond( TF_COND_AIMING ) )
					{
						CTFWeaponBase *pWpn = pTeleportingPlayer->GetActiveTFWeapon();

						if ( pWpn && pWpn->GetWeaponID() == TF_WEAPON_SNIPERRIFLE )
						{
							CTFSniperRifle *pRifle = static_cast<CTFSniperRifle*>( pWpn );
							pRifle->ToggleZoom();
						}
					}

					pTeleportingPlayer->SetFOV( pTeleportingPlayer, 0, tf_teleporter_fov_time.GetFloat(), tf_teleporter_fov_start.GetInt() );

					color32 fadeColor = {255,255,255,100};
					UTIL_ScreenFade( pTeleportingPlayer, fadeColor, 0.25, 0.4, FFADE_IN );
				}
				else
				{
					DetonateObject();
				}
			}			

			SetState( TELEPORTER_STATE_RECEIVING_RELEASE );

			m_flMyNextThink = gpGlobals->curtime + ( BUILD_TELEPORTER_FADEIN_TIME );
		}
		break;

	case TELEPORTER_STATE_RECEIVING_RELEASE:
		{
			CTFPlayer *pTeleportingPlayer = m_hTeleportingPlayer.Get();

			if ( pTeleportingPlayer )
			{
				int iTeam = GetBuilder() ? GetBuilder()->GetTeamNumber() : GetTeamNumber();
				pTeleportingPlayer->m_Shared.SetTeleporterEffectColor( iTeam );
				pTeleportingPlayer->TeleportEffect();

				pTeleportingPlayer->m_Shared.RemoveCond( TF_COND_SELECTED_TO_TELEPORT );

				if ( !m_bWasMapPlaced && GetBuilder() )
					CTF_GameStats.Event_PlayerUsedTeleport( GetBuilder(), pTeleportingPlayer );

				IGameEvent * event = gameeventmanager->CreateEvent( "player_teleported" );
				if ( event )
				{
					event->SetInt( "userid", pTeleportingPlayer->GetUserID() );

					if ( GetBuilder() )
						event->SetInt( "builderid", GetBuilder()->GetUserID() );

					Vector vecOrigin = GetAbsOrigin();
					Vector vecDestinationOrigin = GetMatchingTeleporter()->GetAbsOrigin();
					Vector vecDifference = Vector( vecOrigin.x - vecDestinationOrigin.x, vecOrigin.y - vecDestinationOrigin.y, vecOrigin.z - vecDestinationOrigin.z );
					
					float flDist = sqrtf( pow( vecDifference.x, 2 ) + pow( vecDifference.y, 2 ) + pow( vecDifference.z, 2 ) );

					event->SetFloat( "dist", flDist );	

					gameeventmanager->FireEvent( event, true );
				}

				// Don't thank ourselves.
				if ( pTeleportingPlayer != GetBuilder() )
					pTeleportingPlayer->SpeakConceptIfAllowed( MP_CONCEPT_TELEPORTED );
			}

			// reset the pointers to the player now that we're done teleporting
			SetTeleportingPlayer( NULL );
			pMatch->SetTeleportingPlayer( NULL );

			SetState( TELEPORTER_STATE_RECHARGING );

			m_flMyNextThink = gpGlobals->curtime + ( g_flTeleporterRechargeTimes[ GetUpgradeLevel() - 1 ] );
		}
		break;

	case TELEPORTER_STATE_RECHARGING:
		// If we are finished recharging, go active
		if ( gpGlobals->curtime > m_flRechargeTime )
		{
			SetState( TELEPORTER_STATE_READY );
			EmitSound( "Building_Teleporter.Ready" );
		}
		break;
	}
}
Exemplo n.º 3
0
CBaseEntity* CHL2MP_Player::EntSelectSpawnPoint( void )
{
	CBaseEntity *pSpot = NULL;
	CBaseEntity *pLastSpawnPoint = g_pLastSpawn;
	edict_t		*player = edict();
	const char *pSpawnpointName = "info_player_deathmatch";

	if ( HL2MPRules()->IsTeamplay() == true )
	{
		if ( GetTeamNumber() == TEAM_COMBINE )
		{
			pSpawnpointName = "info_player_combine";
			pLastSpawnPoint = g_pLastCombineSpawn;
		}
		else if ( GetTeamNumber() == TEAM_REBELS )
		{
			pSpawnpointName = "info_player_rebel";
			pLastSpawnPoint = g_pLastRebelSpawn;
		}

		if ( gEntList.FindEntityByClassname( NULL, pSpawnpointName ) == NULL )
		{
			pSpawnpointName = "info_player_deathmatch";
			pLastSpawnPoint = g_pLastSpawn;
		}
	}

	pSpot = pLastSpawnPoint;
	// Randomize the start spot
	for ( int i = random->RandomInt(1,5); i > 0; i-- )
		pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName );
	if ( !pSpot )  // skip over the null point
		pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName );

	CBaseEntity *pFirstSpot = pSpot;

	do 
	{
		if ( pSpot )
		{
			// check if pSpot is valid
			if ( g_pGameRules->IsSpawnPointValid( pSpot, this ) )
			{
				if ( pSpot->GetLocalOrigin() == vec3_origin )
				{
					pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName );
					continue;
				}

				// if so, go to pSpot
				goto ReturnSpot;
			}
		}
		// increment pSpot
		pSpot = gEntList.FindEntityByClassname( pSpot, pSpawnpointName );
	} while ( pSpot != pFirstSpot ); // loop if we're not back to the start

	// we haven't found a place to spawn yet,  so kill any guy at the first spawn point and spawn there
	if ( pSpot )
	{
		CBaseEntity *ent = NULL;
		for ( CEntitySphereQuery sphere( pSpot->GetAbsOrigin(), 128 ); (ent = sphere.GetCurrentEntity()) != NULL; sphere.NextEntity() )
		{
			// if ent is a client, kill em (unless they are ourselves)
			if ( ent->IsPlayer() && !(ent->edict() == player) )
				ent->TakeDamage( CTakeDamageInfo( GetContainingEntity(INDEXENT(0)), GetContainingEntity(INDEXENT(0)), 300, DMG_GENERIC ) );
		}
		goto ReturnSpot;
	}

	if ( !pSpot  )
	{
		pSpot = gEntList.FindEntityByClassname( pSpot, "info_player_start" );

		if ( pSpot )
			goto ReturnSpot;
	}

ReturnSpot:

	if ( HL2MPRules()->IsTeamplay() == true )
	{
		if ( GetTeamNumber() == TEAM_COMBINE )
		{
			g_pLastCombineSpawn = pSpot;
		}
		else if ( GetTeamNumber() == TEAM_REBELS ) 
		{
			g_pLastRebelSpawn = pSpot;
		}
	}

	g_pLastSpawn = pSpot;

	m_flSlamProtectTime = gpGlobals->curtime + 0.5;

	return pSpot;
} 
Exemplo n.º 4
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CTFBaseRocket::Explode( trace_t *pTrace, CBaseEntity *pOther )
{
    // Save this entity as enemy, they will take 100% damage.
    m_hEnemy = pOther;

    // Invisible.
    SetModelName( NULL_STRING );
    AddSolidFlags( FSOLID_NOT_SOLID );
    m_takedamage = DAMAGE_NO;

    // Figure out Econ ID.
    int iItemID = -1;
    if ( m_hLauncher.Get() )
    {
        CTFWeaponBase *pWeapon = dynamic_cast<CTFWeaponBase *>( m_hLauncher.Get() );
        if ( pWeapon )
        {
            iItemID = pWeapon->GetItemID();
        }
    }

    // Pull out a bit.
    if ( pTrace->fraction != 1.0 )
    {
        SetAbsOrigin( pTrace->endpos + ( pTrace->plane.normal * 1.0f ) );
    }

    CBaseEntity *pAttacker = GetOwnerEntity();
    IScorer *pScorerInterface = dynamic_cast<IScorer*>( pAttacker );
    if ( pScorerInterface )
    {
        pAttacker = pScorerInterface->GetScorer();
    }

    // Play explosion sound and effect.
    Vector vecOrigin = GetAbsOrigin();
    CPVSFilter filter( vecOrigin );
    bool bCrit = ( GetDamageType() & DMG_CRITICAL ) != 0;
    TE_TFExplosion( filter, 0.0f, vecOrigin, pTrace->plane.normal, GetWeaponID(), pOther->entindex(), ToBasePlayer( pAttacker ), GetTeamNumber(), bCrit, iItemID );
    CSoundEnt::InsertSound( SOUND_COMBAT, vecOrigin, 1024, 3.0 );

    // Damage.
    float flRadius = GetRadius();

    CTFRadiusDamageInfo radiusInfo;
    radiusInfo.info.Set( this, pAttacker, m_hLauncher, vec3_origin, vecOrigin, GetDamage(), GetDamageType() );
    radiusInfo.m_vecSrc = vecOrigin;
    radiusInfo.m_flRadius = flRadius;
    radiusInfo.m_flSelfDamageRadius = 121.0f; // Original rocket radius?

    TFGameRules()->RadiusDamage( radiusInfo );

    // Debug!
    if ( tf_rocket_show_radius.GetBool() )
    {
        DrawRadius( flRadius );
    }

    // Don't decal players with scorch.
    if ( !pOther->IsPlayer() )
    {
        UTIL_DecalTrace( pTrace, "Scorch" );
    }

    // Remove the rocket.
    UTIL_Remove( this );
}
Exemplo n.º 5
0
void CSDKPlayer::FireBullet( 
						   Vector vecSrc,	// shooting postion
						   const QAngle &shootAngles,  //shooting angle
						   float vecSpread, // spread vector
						   SDKWeaponID eWeaponID,	// weapon that fired this shot
						   int iDamage, // base damage
						   int iBulletType, // ammo type
						   CBaseEntity *pevAttacker, // shooter
						   bool bDoEffects,	// create impact effect ?
						   float x,	// spread x factor
						   float y	// spread y factor
						   )
{
	float flCurrentDistance = 0.0;  //distance that the bullet has traveled so far

	Vector vecDirShooting, vecRight, vecUp;
	AngleVectors( shootAngles, &vecDirShooting, &vecRight, &vecUp );

	if ( !pevAttacker )
		pevAttacker = this;  // the default attacker is ourselves

	// add the spray 
	Vector vecDir = vecDirShooting +
		x * vecSpread * vecRight +
		y * vecSpread * vecUp;

	VectorNormalize( vecDir );

	float flMaxRange = 8000;

	Vector vecEnd = vecSrc + vecDir * flMaxRange; // max bullet range is 10000 units
	CBaseEntity* pIgnore = this;

	// initialize these before the penetration loop, we'll need them to make our tracer after
	Vector vecTracerSrc = vecSrc;
	trace_t tr; // main enter bullet trace

	for (size_t i = 0; i < 5; i++)
	{
		CTraceFilterSimpleList tf(COLLISION_GROUP_NONE);
		tf.AddEntityToIgnore(this);
		tf.AddEntityToIgnore(pIgnore);

		UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID|CONTENTS_DEBRIS|CONTENTS_HITBOX, &tf, &tr );

		if ( tr.fraction == 1.0f )
			break; // we didn't hit anything, stop tracing shoot

		if ( sv_showimpacts.GetBool() )
		{
#ifdef CLIENT_DLL
			// draw red client impact markers
			debugoverlay->AddBoxOverlay( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), QAngle( 0, 0, 0), 255,0,0,127, 4 );

			if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
			{
				C_BasePlayer *player = ToBasePlayer( tr.m_pEnt );
				player->DrawClientHitboxes( 4, true );
			}
#else
			// draw blue server impact markers
			NDebugOverlay::Box( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), 0,0,255,127, 4 );

			if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
			{
				CBasePlayer *player = ToBasePlayer( tr.m_pEnt );
				player->DrawServerHitboxes( 4, true );
			}
#endif
		}

		weapontype_t eWeaponType = WT_NONE;

		CSDKWeaponInfo *pWeaponInfo = CSDKWeaponInfo::GetWeaponInfo(eWeaponID);
		Assert(pWeaponInfo);
		if (pWeaponInfo)
			eWeaponType = pWeaponInfo->m_eWeaponType;

		float flDamageMultiplier = 1;
		float flMaxRange = 3000;

		// Power formula works like so:
		// pow( x, distance/y )
		// The damage will be at 1 when the distance is 0 units, and at
		// x% when the distance is y units, with a gradual decay approaching zero
		switch (eWeaponType)
		{
		case WT_RIFLE:
			flDamageMultiplier = 0.75f;
			flMaxRange = 3000;
			break;

		case WT_SHOTGUN:
			flDamageMultiplier = 0.40f;
			flMaxRange = 500;
			break;

		case WT_SMG:
			flDamageMultiplier = 0.50f;
			flMaxRange = 1000;
			break;

		case WT_PISTOL:
		default:
			flDamageMultiplier = 0.55f;
			flMaxRange = 1500;
			break;
		}

		//calculate the damage based on the distance the bullet travelled.
		flCurrentDistance += tr.fraction * flMaxRange;

		// First 500 units, no decrease in damage.
		if (eWeaponType == WT_SHOTGUN)
			flCurrentDistance -= 350;
		else
			flCurrentDistance -= 500;

		if (flCurrentDistance < 0)
			flCurrentDistance = 0;

		if (flCurrentDistance > flMaxRange)
			flCurrentDistance = flMaxRange;

		float flDistanceMultiplier = pow(flDamageMultiplier, (flCurrentDistance / flMaxRange));

		int iDamageType = DMG_BULLET | DMG_NEVERGIB | GetAmmoDef()->DamageType(iBulletType);

		if (i == 0)
			iDamageType |= DMG_DIRECT;

		if( bDoEffects )
		{
			// See if the bullet ended up underwater + started out of the water
			if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) )
			{	
				trace_t waterTrace;
				UTIL_TraceLine( vecSrc, tr.endpos, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), pIgnore, COLLISION_GROUP_NONE, &waterTrace );

				if( waterTrace.allsolid != 1 )
				{
					CEffectData	data;
					data.m_vOrigin = waterTrace.endpos;
					data.m_vNormal = waterTrace.plane.normal;
					data.m_flScale = random->RandomFloat( 8, 12 );

					if ( waterTrace.contents & CONTENTS_SLIME )
					{
						data.m_fFlags |= FX_WATER_IN_SLIME;
					}

					DispatchEffect( "gunshotsplash", data );
				}
			}
			else
			{
				//Do Regular hit effects

				// Don't decal nodraw surfaces
				if ( !( tr.surface.flags & (SURF_SKY|SURF_NODRAW|SURF_HINT|SURF_SKIP) ) )
				{
					CBaseEntity *pEntity = tr.m_pEnt;
					//Tony; only while using teams do we check for friendly fire.
					if ( pEntity && pEntity->IsPlayer() && (pEntity->GetBaseAnimating() && !pEntity->GetBaseAnimating()->IsRagdoll()) )
					{
#if defined ( SDK_USE_TEAMS )
						if ( pEntity->GetTeamNumber() == GetTeamNumber() )
						{
							if ( !friendlyfire.GetBool() )
								UTIL_ImpactTrace( &tr, iDamageType );
						}
#else
						UTIL_ImpactTrace( &tr, iDamageType );
#endif
					}
					//Tony; non player, just go nuts,
					else
					{
						UTIL_ImpactTrace( &tr, iDamageType );
					}
				}
			}
		} // bDoEffects

		// add damage to entity that we hit

#ifdef GAME_DLL
		float flBulletDamage = iDamage * flDistanceMultiplier / (i+1);	// Each iteration the bullet drops in strength

		ClearMultiDamage();

		CTakeDamageInfo info( pevAttacker, pevAttacker, flBulletDamage, iDamageType );
		CalculateBulletDamageForce( &info, iBulletType, vecDir, tr.endpos );
		tr.m_pEnt->DispatchTraceAttack( info, vecDir, &tr );

		TraceAttackToTriggers( info, tr.startpos, tr.endpos, vecDir );

		ApplyMultiDamage();
#else
		flDistanceMultiplier = flDistanceMultiplier; // Silence warning.
#endif

		pIgnore = tr.m_pEnt;

		float flPenetrationDistance;
		switch (eWeaponType)
		{
		case WT_RIFLE:
			flPenetrationDistance = 25;
			break;

		case WT_SHOTGUN:
			flPenetrationDistance = 5;
			break;

		case WT_SMG:
			flPenetrationDistance = 15;
			break;

		case WT_PISTOL:
		default:
			flPenetrationDistance = 15;
			break;
		}

		Vector vecBackwards = tr.endpos + vecDir * flPenetrationDistance;
		if (tr.m_pEnt->IsBSPModel())
			UTIL_TraceLine( vecBackwards, tr.endpos, CONTENTS_SOLID|CONTENTS_MOVEABLE, NULL, COLLISION_GROUP_NONE, &tr );
		else
			UTIL_TraceLine( vecBackwards, tr.endpos, CONTENTS_HITBOX, NULL, COLLISION_GROUP_NONE, &tr );

		if (tr.startsolid)
			break;
		
		if (tr.m_pEnt)
		{
			// let's have a bullet exit effect if we penetrated a solid surface
			if (tr.m_pEnt->IsBSPModel())
				UTIL_ImpactTrace( &tr, iDamageType );

			// ignore the entity we just hit for the next trace to avoid weird impact behaviors
			pIgnore = tr.m_pEnt;
		}

		// Set up the next trace.
		vecSrc = tr.endpos + vecDir;	// One unit in the direction of fire so that we firmly embed ourselves in whatever solid was hit.
	}
	
	// the bullet's done penetrating, let's spawn our particle system
	if (bDoEffects && (pevAttacker == this))
		MakeTracer( vecTracerSrc, tr, TRACER_TYPE_DEFAULT );
}
Exemplo n.º 6
0
//-----------------------------------------------------------------------------
// Purpose: Checks to see if it's time to change controllers
//-----------------------------------------------------------------------------
void CControlZone::ReevaluateControllingTeam( void )
{
	// Count the number of players in each team
	int i;
	memset( m_iPlayersInZone, 0, sizeof( m_iPlayersInZone ) );
	for ( i = 0; i < m_ZonePlayerList.Size(); i++ )
	{
		if ( m_ZonePlayerList[i] != NULL && (m_ZonePlayerList[i]->GetTeamNumber() > 0) )
		{
			m_iPlayersInZone[ m_ZonePlayerList[i]->GetTeamNumber() ] += 1;
		}
	}

	// Abort immediately if we're not using touches to changes teams
	if ( HasSpawnFlags( CZF_DONT_USE_TOUCHES ) )
		return;

	// if we're locked in place, no changes can occur to controlling team except through an explicit map ResetTeam
	if ( m_iLocked )
		return;

	bool foundAnyTeam = false;
	int teamFound = 0;

	// check to see if any teams have no players
	for ( i = 1; i <= GetNumberOfTeams(); i++ )
	{
		if ( m_iPlayersInZone[i] )
		{
			if ( foundAnyTeam )
			{
				// we've already found a team, so it's being contested;
				teamFound = ZONE_CONTESTED;
				break;
			}

			foundAnyTeam = true;
			teamFound = i;			
		}
	}

	// no one in the area!
	if ( teamFound == 0 )
	{
		// just leave it as it is, let it continue to change team
		// exception: if the zone state is contested, and there aren't any players in the zone,
		// just return to the team who used to own the zone.
		if ( GetTeamNumber() == ZONE_CONTESTED )
		{
			ChangeTeam(m_iDefendingTeam);
			SetControllingTeam( this, m_iDefendingTeam );
		}

		return;
	}

	// if it's the same controlling team, don't worry about it
	if ( teamFound == GetTeamNumber() )
	{
		// the right team is in control, don't even think of switching
		m_iTryingToChangeToTeam = 0;
		SetNextThink( TICK_NEVER_THINK );
		return;
	}

	// Find out if the zone isn't owned by anyone at all (hasn't been touched since the map started, and it started un-owned)
	bool bHasBeenOwned = true;
	if ( m_iDefendingTeam == 0 && GetTeamNumber() == 0 ) 
		bHasBeenOwned = false;

	// if it's not contested, always go to contested mode 
	if ( GetTeamNumber() != ZONE_CONTESTED && teamFound != GetTeamNumber() )
	{
		// Unowned zones are captured immediately (no contesting stage)
		if ( bHasBeenOwned )
			teamFound = ZONE_CONTESTED;
	}

	// if it's the team we're trying to change to, don't worry about it
	if ( teamFound == m_iTryingToChangeToTeam )
		return;

	// set up the time to change to the new team soon
	m_iTryingToChangeToTeam = teamFound;

	// changing from contested->uncontested and visa-versa have different delays
	if ( m_iTryingToChangeToTeam != ZONE_CONTESTED )
	{
		if ( !bHasBeenOwned )
		{
			DevMsg( 1, "trigger_controlzone: (%s) changing team to %d NOW\n", GetDebugName(), m_iTryingToChangeToTeam );
			SetNextThink( gpGlobals->curtime + 0.1f );
		}
		else
		{
			DevMsg( 1, "trigger_controlzone: (%s) changing team to %d in %.2f seconds\n", GetDebugName(), m_iTryingToChangeToTeam, m_flTimeTillCaptured );
			SetNextThink( gpGlobals->curtime + m_flTimeTillCaptured );
		}
	}
	else
	{
		DevMsg( 1, "trigger_controlzone: (%s) changing to contested in %f seconds\n", GetDebugName(), m_flTimeTillContested );
		SetNextThink( gpGlobals->curtime + m_flTimeTillContested );
	}
}
Exemplo n.º 7
0
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CObjectSentrygun::ValidTargetPlayer( CTFPlayer *pPlayer, const Vector &vecStart, const Vector &vecEnd )
{
	// Keep shooting at spies that go invisible after we acquire them as a target.
	if ( pPlayer->m_Shared.GetPercentInvisible() > 0.5 )
		return false;

	// Keep shooting at spies that disguise after we acquire them as at a target.
	if ( pPlayer->m_Shared.InCond( TF_COND_DISGUISED ) && pPlayer->m_Shared.GetDisguiseTeam() == GetTeamNumber() && pPlayer != m_hEnemy )
		return false;

	// Not across water boundary.
	if ( ( GetWaterLevel() == 0 && pPlayer->GetWaterLevel() >= 3 ) || ( GetWaterLevel() == 3 && pPlayer->GetWaterLevel() <= 0 ) )
		return false;

	// Ray trace!!!
	return FVisible( pPlayer, MASK_SHOT | CONTENTS_GRATE );
}
Exemplo n.º 8
0
bool CSDKPlayer::ClientCommand( const CCommand &args )
{
	const char *pcmd = args[0];
	if ( FStrEq( pcmd, "jointeam" ) ) 
	{
		if ( args.ArgC() < 2 )
		{
			Warning( "Player sent bad jointeam syntax\n" );
		}

		int iTeam = atoi( args[1] );
		HandleCommand_JoinTeam( iTeam );
		return true;
	}
	else if( !Q_strncmp( pcmd, "cls_", 4 ) )
	{
#if defined ( SDK_USE_PLAYERCLASSES )
		CSDKTeam *pTeam = GetGlobalSDKTeam( GetTeamNumber() );

		Assert( pTeam );

		int iClassIndex = PLAYERCLASS_UNDEFINED;

		if( pTeam->IsClassOnTeam( pcmd, iClassIndex ) )
		{
			HandleCommand_JoinClass( iClassIndex );
		}
		else
		{
			DevMsg( "player tried to join a class that isn't on this team ( %s )\n", pcmd );
			ShowClassSelectMenu();
		}
#endif
		return true;
	}
	else if ( FStrEq( pcmd, "spectate" ) )
	{
		// instantly join spectators
		HandleCommand_JoinTeam( TEAM_SPECTATOR );
		return true;
	}
	else if ( FStrEq( pcmd, "joingame" ) )
	{
		// player just closed MOTD dialog
		if ( m_iPlayerState == STATE_WELCOME )
		{
//Tony; using teams, go to picking team.
#if defined( SDK_USE_TEAMS )
			State_Transition( STATE_PICKINGTEAM );
//Tony; not using teams, but we are using classes, so go straight to class picking.
#elif !defined ( SDK_USE_TEAMS ) && defined ( SDK_USE_PLAYERCLASSES )
			State_Transition( STATE_PICKINGCLASS );
//Tony; not using teams or classes, go straight to active.
#else
			State_Transition( STATE_ACTIVE );
#endif
		}
		
		return true;
	}
	else if ( FStrEq( pcmd, "joinclass" ) ) 
	{
#if defined ( SDK_USE_PLAYERCLASSES )
		if ( args.ArgC() < 2 )
		{
			Warning( "Player sent bad joinclass syntax\n" );
		}

		int iClass = atoi( args[1] );
		HandleCommand_JoinClass( iClass );
#endif
		return true;
	}
	else if ( FStrEq( pcmd, "menuopen" ) )
	{
#if defined ( SDK_USE_PLAYERCLASSES )
		SetClassMenuOpen( true );
#endif
		return true;
	}
	else if ( FStrEq( pcmd, "menuclosed" ) )
	{
#if defined ( SDK_USE_PLAYERCLASSES )
		SetClassMenuOpen( false );
#endif
		return true;
	}
	else if ( FStrEq( pcmd, "droptest" ) )
	{
		ThrowActiveWeapon();
		return true;
	}

	return BaseClass::ClientCommand( args );
}
Exemplo n.º 9
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void C_BaseObject::HighlightBuildPoints( int flags )
{
	C_TFPlayer *pLocal = C_TFPlayer::GetLocalTFPlayer();
	if ( !pLocal )
		return;

	if ( !GetNumBuildPoints() || !InLocalTeam() )
		return;

	C_TFWeaponBuilder *pBuilderWpn = dynamic_cast< C_TFWeaponBuilder * >( pLocal->GetActiveWeaponForSelection() );
	if ( !pBuilderWpn )
		return;
	if ( !pBuilderWpn->IsPlacingObject() )
		return;
	C_BaseObject *pPlacementObj = pBuilderWpn->GetPlacementModel();
	if ( !pPlacementObj || pPlacementObj == this )
		return;

	// Near enough?
	if ( (GetAbsOrigin() - pLocal->GetAbsOrigin()).LengthSqr() < MAX_VISIBLE_BUILDPOINT_DISTANCE )
	{
		bool bRestoreModel = false;
		Vector vecPrevAbsOrigin = pPlacementObj->GetAbsOrigin();
		QAngle vecPrevAbsAngles = pPlacementObj->GetAbsAngles();

		Vector orgColor;
		render->GetColorModulation( orgColor.Base() );
		float orgBlend = render->GetBlend();

		bool bSameTeam = ( pPlacementObj->GetTeamNumber() == GetTeamNumber() );

		if ( pPlacementObj->IsHostileUpgrade() && bSameTeam )
		{
			// Don't hilight hostile upgrades on friendly objects
			return;
		}
		else if ( !bSameTeam )
		{
			// Don't hilight upgrades on enemy objects
			return;
		}

		// Any empty buildpoints?
		for ( int i = 0; i < GetNumBuildPoints(); i++ )
		{
			// Can this object build on this point?
			if ( CanBuildObjectOnBuildPoint( i, pPlacementObj->GetType() ) )
			{
				Vector vecBPOrigin;
				QAngle vecBPAngles;
				if ( GetBuildPoint(i, vecBPOrigin, vecBPAngles) )
				{
					pPlacementObj->InvalidateBoneCaches();

					Vector color( 0, 255, 0 );
					render->SetColorModulation(	color.Base() );
					float frac = fmod( gpGlobals->curtime, 3 );
					frac *= 2 * M_PI;
					frac = cos( frac );
					render->SetBlend( (175 + (int)( frac * 75.0f )) / 255.0 );

					// FIXME: This truly sucks! The bone cache should use
					// render location for this computation instead of directly accessing AbsAngles
					// Necessary for bone cache computations to work
					pPlacementObj->SetAbsOrigin( vecBPOrigin );
					pPlacementObj->SetAbsAngles( vecBPAngles );

					modelrender->DrawModel( 
						flags, 
						pPlacementObj,
						pPlacementObj->GetModelInstance(),
						pPlacementObj->index, 
						pPlacementObj->GetModel(),
						vecBPOrigin,
						vecBPAngles,
						pPlacementObj->m_nSkin,
						pPlacementObj->m_nBody,
						pPlacementObj->m_nHitboxSet
						);

					bRestoreModel = true;
				}
			}
		}

		if ( bRestoreModel )
		{
			pPlacementObj->SetAbsOrigin(vecPrevAbsOrigin);
			pPlacementObj->SetAbsAngles(vecPrevAbsAngles);
			pPlacementObj->InvalidateBoneCaches();

			render->SetColorModulation( orgColor.Base() );
			render->SetBlend( orgBlend );
		}
	}
}
Exemplo n.º 10
0
//Tony; we don't have to check anything special for SDK_USE_TEAMS here; it's all pretty generic, except for the one assert.
bool CSDKPlayer::HandleCommand_JoinClass( int iClass )
{
	Assert( GetTeamNumber() != TEAM_SPECTATOR );
#if defined ( SDK_USE_TEAMS )
	Assert( GetTeamNumber() != TEAM_UNASSIGNED );
#endif

	if( GetTeamNumber() == TEAM_SPECTATOR )
		return false;

	if( iClass == PLAYERCLASS_UNDEFINED )
		return false;	//they typed in something weird

	int iOldPlayerClass = m_Shared.DesiredPlayerClass();

	// See if we're joining the class we already are
	if( iClass == iOldPlayerClass )
		return true;

	if( !SDKGameRules()->IsPlayerClassOnTeam( iClass, GetTeamNumber() ) )
		return false;

	const char *classname = SDKGameRules()->GetPlayerClassName( iClass, GetTeamNumber() );

	if( SDKGameRules()->CanPlayerJoinClass( this, iClass ) )
	{
		m_Shared.SetDesiredPlayerClass( iClass );	//real class value is set when the player spawns

//Tony; don't do this until we have a spawn timer!!
//		if( State_Get() == STATE_PICKINGCLASS )
//			State_Transition( STATE_OBSERVER_MODE );

		if( iClass == PLAYERCLASS_RANDOM )
		{
			if( IsAlive() )
			{
				ClientPrint(this, HUD_PRINTTALK, "#game_respawn_asrandom" );
			}
			else
			{
				ClientPrint(this, HUD_PRINTTALK, "#game_spawn_asrandom" );
			}
		}
		else
		{
			if( IsAlive() )
			{
				ClientPrint(this, HUD_PRINTTALK, "#game_respawn_as", classname );
			}
			else
			{
				ClientPrint(this, HUD_PRINTTALK, "#game_spawn_as", classname );
			}
		}

		IGameEvent * event = gameeventmanager->CreateEvent( "player_changeclass" );
		if ( event )
		{
			event->SetInt( "userid", GetUserID() );
			event->SetInt( "class", iClass );

			gameeventmanager->FireEvent( event );
		}
	}
	else
	{
		ClientPrint(this, HUD_PRINTTALK, "#game_class_limit", classname );
		ShowClassSelectMenu();
	}

	// Incase we don't get the class menu message before the spawn timer
	// comes up, fake that we've closed the menu.
	SetClassMenuOpen( false );

	//Tony; TODO; this is temp, I may integrate with the teamplayroundrules; If I do, there will be wavespawn too.
	if ( State_Get() == STATE_PICKINGCLASS /*|| IsDead()*/ )	//Tony; undone, don't transition if dead; only go into active state at this point if we were picking class.
		State_Transition( STATE_ACTIVE ); //Done picking stuff and we're in the pickingclass state, or dead, so we can spawn now.

	return true;
}
Exemplo n.º 11
0
int CSDKPlayer::OnTakeDamage( const CTakeDamageInfo &inputInfo )
{
	CTakeDamageInfo info = inputInfo;

	CBaseEntity *pInflictor = info.GetInflictor();

	if ( !pInflictor )
		return 0;

	if ( GetMoveType() == MOVETYPE_NOCLIP || GetMoveType() == MOVETYPE_OBSERVER )
		return 0;

	float flArmorBonus = 0.5f;
	float flArmorRatio = 0.5f;
	float flDamage = info.GetDamage();

	bool bCheckFriendlyFire = false;
	bool bFriendlyFire = friendlyfire.GetBool();
	//Tony; only check teams in teamplay
	if ( gpGlobals->teamplay )
		bCheckFriendlyFire = true;

	if ( bFriendlyFire || ( bCheckFriendlyFire && pInflictor->GetTeamNumber() != GetTeamNumber() ) || pInflictor == this ||	info.GetAttacker() == this )
	{
		if ( bFriendlyFire && (info.GetDamageType() & DMG_BLAST) == 0 )
		{
			if ( pInflictor->GetTeamNumber() == GetTeamNumber() && bCheckFriendlyFire)
			{
				flDamage *= 0.35; // bullets hurt teammates less
			}
		}

		// keep track of amount of damage last sustained
		m_lastDamageAmount = flDamage;
		// Deal with Armour
		if ( ArmorValue() && !( info.GetDamageType() & (DMG_FALL | DMG_DROWN)) )
		{
			float flNew = flDamage * flArmorRatio;
			float flArmor = (flDamage - flNew) * flArmorBonus;

			// Does this use more armor than we have?
			if (flArmor > ArmorValue() )
			{
				//armorHit = (int)(flArmor);

				flArmor = ArmorValue();
				flArmor *= (1/flArmorBonus);
				flNew = flDamage - flArmor;
				SetArmorValue( 0 );
			}
			else
			{
				int oldValue = (int)(ArmorValue());
			
				if ( flArmor < 0 )
					 flArmor = 1;

				SetArmorValue( oldValue - flArmor );
				//armorHit = oldValue - (int)(pev->armorvalue);
			}
			
			flDamage = flNew;
			
			info.SetDamage( flDamage );
		}

		// round damage to integer
		info.SetDamage( (int)flDamage );

		if ( info.GetDamage() <= 0 )
			return 0;

		CSingleUserRecipientFilter user( this );
		user.MakeReliable();
		UserMessageBegin( user, "Damage" );
			WRITE_BYTE( (int)info.GetDamage() );
			WRITE_VEC3COORD( info.GetInflictor()->WorldSpaceCenter() );
		MessageEnd();

		// Do special explosion damage effect
		if ( info.GetDamageType() & DMG_BLAST )
		{
			OnDamagedByExplosion( info );
		}

		gamestats->Event_PlayerDamage( this, info );

		return CBaseCombatCharacter::OnTakeDamage( info );
	}
	else
	{
		return 0;
	}
}
Exemplo n.º 12
0
// returns true if the selection has been handled and the player's menu 
// can be closed...false if the menu should be displayed again
bool CSDKPlayer::HandleCommand_JoinTeam( int team )
{
	CSDKGameRules *mp = SDKGameRules();
	int iOldTeam = GetTeamNumber();
	if ( !GetGlobalTeam( team ) )
	{
		Warning( "HandleCommand_JoinTeam( %d ) - invalid team index.\n", team );
		return false;
	}

#if defined ( SDK_USE_TEAMS )
	// If we already died and changed teams once, deny
	if( m_bTeamChanged && team != TEAM_SPECTATOR && iOldTeam != TEAM_SPECTATOR )
	{
		ClientPrint( this, HUD_PRINTCENTER, "game_switch_teams_once" );
		return true;
	}
#endif
	if ( team == TEAM_UNASSIGNED )
	{
		// Attempt to auto-select a team, may set team to T, CT or SPEC
		team = mp->SelectDefaultTeam();

		if ( team == TEAM_UNASSIGNED )
		{
			// still team unassigned, try to kick a bot if possible	
			 
			ClientPrint( this, HUD_PRINTTALK, "#All_Teams_Full" );

			team = TEAM_SPECTATOR;
		}
	}

	if ( team == iOldTeam )
		return true;	// we wouldn't change the team

#if defined ( SDK_USE_TEAMS )
	if ( mp->TeamFull( team ) )
	{
		if ( team == SDK_TEAM_BLUE )
		{
			ClientPrint( this, HUD_PRINTTALK, "#BlueTeam_Full" );
		}
		else if ( team == SDK_TEAM_RED )
		{
			ClientPrint( this, HUD_PRINTTALK, "#RedTeam_Full" );
		}
		ShowViewPortPanel( PANEL_TEAM );
		return false;
	}
#endif

	if ( team == TEAM_SPECTATOR )
	{
		// Prevent this if the cvar is set
		if ( !mp_allowspectators.GetInt() && !IsHLTV() )
		{
			ClientPrint( this, HUD_PRINTTALK, "#Cannot_Be_Spectator" );
			ShowViewPortPanel( PANEL_TEAM );
			return false;
		}

		ChangeTeam( TEAM_SPECTATOR );

		return true;
	}
	
	// If the code gets this far, the team is not TEAM_UNASSIGNED

	// Player is switching to a new team (It is possible to switch to the
	// same team just to choose a new appearance)
#if defined ( SDK_USE_TEAMS )
	if (mp->TeamStacked( team, GetTeamNumber() ))//players are allowed to change to their own team so they can just change their model
	{
		// The specified team is full
		ClientPrint( 
			this,
			HUD_PRINTCENTER,
			( team == SDK_TEAM_BLUE ) ?	"#BlueTeam_full" : "#RedTeam_full" );

		ShowViewPortPanel( PANEL_TEAM );
		return false;
	}
#endif
	// Switch their actual team...
	ChangeTeam( team );

#if defined ( SDK_USE_PLAYERCLASSES )
	// Force them to choose a new class
	m_Shared.SetDesiredPlayerClass( PLAYERCLASS_UNDEFINED );
	m_Shared.SetPlayerClass( PLAYERCLASS_UNDEFINED );
#endif
	return true;
}
Exemplo n.º 13
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CWeaponKritzkrieg::UpdateEffects( void )
{
	CTFPlayer *pFiringPlayer = ToTFPlayer( GetOwnerEntity() );
	if ( !pFiringPlayer )
		return;

	C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer();
	C_BaseEntity *pEffectOwner = this;
	if ( pLocalPlayer == pFiringPlayer )
	{
		pEffectOwner = pLocalPlayer->GetViewModel();
		if ( !pEffectOwner )
			return;
	}

	// Remove all the effects
	if ( pEffectOwner )
	{
		pEffectOwner->ParticleProp()->StopEmission( m_hHealingTargetEffect.pEffect );
	}
	else
	{
		m_hHealingTargetEffect.pEffect->StopEmission();
	}
	m_hHealingTargetEffect.pTarget = NULL;
	m_hHealingTargetEffect.pEffect = NULL;

	// Don't add targets if the medic is dead
	if ( !pEffectOwner || pFiringPlayer->IsPlayerDead() || !pFiringPlayer->IsPlayerClass( TF_CLASS_MEDIC ) )
		return;

	// Add our targets
	// Loops through the healing targets, and make sure we have an effect for each of them
	if ( m_hHealingTarget )
	{
		if ( m_hHealingTargetEffect.pTarget == m_hHealingTarget )
			return;

		const char *pszEffectName;
		if (m_bChargeRelease)
		{
			switch (GetTeamNumber())
			{
			case TF_TEAM_BLUE:
				pszEffectName = "kritz_beam_blue_invun";
				break;
			case TF_TEAM_RED:
				pszEffectName = "kritz_beam_red_invun";
				break;
			case TF_TEAM_GREEN:
				pszEffectName = "kritz_beam_green_invun";
				break;
			case TF_TEAM_YELLOW:
				pszEffectName = "kritz_beam_yellow_invun";
				break;
			default:
				pszEffectName = "kritz_beam_blue";
				break;
			}
		}
		else
		{
			switch (GetTeamNumber())
			{
			case TF_TEAM_BLUE:
				pszEffectName = "kritz_beam_blue";
				break;
			case TF_TEAM_RED:
				pszEffectName = "kritz_beam_red";
				break;
			case TF_TEAM_GREEN:
				pszEffectName = "kritz_beam_green";
				break;
			case TF_TEAM_YELLOW:
				pszEffectName = "kritz_beam_yellow";
				break;
			default:
				pszEffectName = "kritz_beam_blue";
				break;
			}
		}


		CNewParticleEffect *pEffect = pEffectOwner->ParticleProp()->Create( pszEffectName, PATTACH_POINT_FOLLOW, "muzzle" );
		pEffectOwner->ParticleProp()->AddControlPoint( pEffect, 1, m_hHealingTarget, PATTACH_ABSORIGIN_FOLLOW, NULL, Vector(0,0,50) );

		m_hHealingTargetEffect.pTarget = m_hHealingTarget;
		m_hHealingTargetEffect.pEffect = pEffect;
	}
}
Exemplo n.º 14
0
void C_CFPlayer::Spawn()
{
	BaseClass::Spawn();

	if (GetTeamNumber() == TEAM_SPECTATOR || GetTeamNumber() == TEAM_UNASSIGNED)
		cfgui::CRootPanel::SetArmament(m_pArmament);
	else
		cfgui::CRootPanel::SetArmament(m_pCurrentArmament);

	if (IsLocalPlayer())
	{
		switch (cvar->FindVar("cl_thirdperson")->GetInt())
		{
		case 0:
			CFInput()->CAM_ToFirstPerson();
			break;
		case 1:
			CFInput()->CAM_ToThirdPerson();
			break;
		case 2:
			if (GetActiveArmament()->GetWeaponData(0) && GetActiveArmament()->GetWeaponData(0)->m_eWeaponType == WEAPONTYPE_MELEE)
				CFInput()->CAM_ToThirdPerson();
			else
				CFInput()->CAM_ToFirstPerson();
			break;
		}
	}

	m_flLastRespawn = gpGlobals->curtime;
	m_flLastEnemySeen = 0;

	m_flLastCameraTargetTime = 0;

	Instructor_Respawn();

	m_hDrawingDirectTarget = NULL;
	m_hDrawingRecursedTarget = NULL;
	m_flReceivedDirectTarget = 0;
	m_flReceivedRecursedTarget = 0;

	m_eLHEffectElementsOld = ELEMENT_TYPELESS;
	m_eRHEffectElementsOld = ELEMENT_TYPELESS;
	m_iLastCombo = 0;

	m_pLHChargeEffect = m_pRHChargeEffect = NULL;

	for (int i = 0; i < m_apLHComboEffects.Count(); i++)
	{
		ParticleProp()->StopEmission(m_apLHComboEffects[i]);
		ParticleProp()->StopEmission(m_apRHComboEffects[i]);
	}
	m_apLHComboEffects.RemoveAll();
	m_apRHComboEffects.RemoveAll();

	if (!m_pBarrier)
	{
		m_pBarrier = new C_BaseAnimatingOverlay();
		m_pBarrier->InitializeAsClientEntity( "models/magic/barrier.mdl", RENDER_GROUP_OPAQUE_ENTITY );
		m_pBarrier->UseClientSideAnimation();
		m_pBarrier->SetModel("models/magic/barrier.mdl");
		m_pBarrier->AddEffects( EF_NODRAW ); // don't let the renderer draw the model normally
		m_pBarrier->SetOwnerEntity(this);
	}

	m_flShieldTime = 0;
	m_flShieldStrength = 0;
}
void CDODPlayer::FireBullets( const FireBulletsInfo_t &info )
{
	trace_t			tr;								
	trace_t			reverseTr;						//Used to find exit points
	static int		iMaxPenetrations	= 6;
	int				iPenetrations		= 0;
	float			flDamage			= info.m_iDamage;		//Remaining damage in the bullet
	Vector			vecSrc				= info.m_vecSrc;
	Vector			vecEnd				= vecSrc + info.m_vecDirShooting * info.m_flDistance;

	static int		iTraceMask = ( ( MASK_SOLID | CONTENTS_DEBRIS | CONTENTS_HITBOX | CONTENTS_PRONE_HELPER ) & ~CONTENTS_GRATE );
	 
	CBaseEntity		*pLastHitEntity		= this;	// start with us so we don't trace ourselves
		
	int iDamageType = GetAmmoDef()->DamageType( info.m_iAmmoType );
	int iCollisionGroup = COLLISION_GROUP_NONE;

#ifdef GAME_DLL
	bool iNumHeadshots = 0;
#endif

	while ( flDamage > 0 && iPenetrations < iMaxPenetrations )
	{
		//DevMsg( 2, "penetration: %d, starting dmg: %.1f\n", iPenetrations, flDamage );

		CBaseEntity *pPreviousHit = pLastHitEntity;

		// skip the shooter always
		CTraceFilterSkipTwoEntities ignoreShooterAndPrevious( this, pPreviousHit, iCollisionGroup );
		UTIL_TraceLine( vecSrc, vecEnd, iTraceMask, &ignoreShooterAndPrevious, &tr );

		const float rayExtension = 40.0f;
		UTIL_ClipTraceToPlayers( vecSrc, vecEnd + info.m_vecDirShooting * rayExtension, iTraceMask, &ignoreShooterAndPrevious, &tr );

		if ( tr.fraction == 1.0f )
			break; // we didn't hit anything, stop tracing shoot

		// New hitbox code that uses hitbox groups instead of trying to trace
		// through the player
		if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
		{
			switch( tr.hitgroup )
			{
#ifdef GAME_DLL
			case HITGROUP_HEAD:
				{
					if ( tr.m_pEnt->GetTeamNumber() != GetTeamNumber() )
					{
						iNumHeadshots++;
					}
				}
				break;
#endif

			case HITGROUP_LEFTARM:
			case HITGROUP_RIGHTARM:
				{
					//DevMsg( 2, "Hit arms, tracing against alt hitboxes.. \n" );

					CDODPlayer *pPlayer = ToDODPlayer( tr.m_pEnt );

					// set hitbox set to "dod_no_arms"
					pPlayer->SetHitboxSet( 1 );

					trace_t newTr;

					// re-fire the trace
					UTIL_TraceLine( vecSrc, vecEnd, iTraceMask, &ignoreShooterAndPrevious, &newTr );

					// if we hit the same player in the chest
					if ( tr.m_pEnt == newTr.m_pEnt )
					{
						//DevMsg( 2, ".. and we hit the chest.\n" );

						Assert( tr.hitgroup != newTr.hitgroup );	// If we hit this, hitbox sets are broken

						// use that damage instead
						tr = newTr;
					}

					// set hitboxes back to "dod"
					pPlayer->SetHitboxSet( 0 );
				}
				break;

			default:
				break;
			}			
		}
			
		pLastHitEntity = tr.m_pEnt;

		if ( sv_showimpacts.GetBool() )
		{
#ifdef CLIENT_DLL
			// draw red client impact markers
			debugoverlay->AddBoxOverlay( tr.endpos, Vector(-1,-1,-1), Vector(1,1,1), QAngle(0,0,0), 255, 0, 0, 127, 4 );

			if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
			{
				C_BasePlayer *player = ToBasePlayer( tr.m_pEnt );
				player->DrawClientHitboxes( 4, true );
			}
#else
			// draw blue server impact markers
			NDebugOverlay::Box( tr.endpos, Vector(-1,-1,-1), Vector(1,1,1), 0,0,255,127, 4 );

			if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
			{
				CBasePlayer *player = ToBasePlayer( tr.m_pEnt );
				player->DrawServerHitboxes( 4, true );
			}
#endif
		}

#ifdef CLIENT_DLL
		// See if the bullet ended up underwater + started out of the water
		if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) )
		{	
			trace_t waterTrace;
			UTIL_TraceLine( vecSrc, tr.endpos, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), this, iCollisionGroup, &waterTrace );
			
			if( waterTrace.allsolid != 1 )
			{
				CEffectData	data;
 				data.m_vOrigin = waterTrace.endpos;
				data.m_vNormal = waterTrace.plane.normal;
				data.m_flScale = random->RandomFloat( 8, 12 );

				if ( waterTrace.contents & CONTENTS_SLIME )
				{
					data.m_fFlags |= FX_WATER_IN_SLIME;
				}

				DispatchEffect( "gunshotsplash", data );
			}
		}
		else
		{
			//Do Regular hit effects

			// Don't decal nodraw surfaces
			if ( !( tr.surface.flags & (SURF_SKY|SURF_NODRAW|SURF_HINT|SURF_SKIP) ) )
			{
				CBaseEntity *pEntity = tr.m_pEnt;
				if ( !( !friendlyfire.GetBool() && pEntity && pEntity->GetTeamNumber() == GetTeamNumber() ) )
				{
					UTIL_ImpactTrace( &tr, iDamageType );
				}
			}
		}
#endif

		// Get surface where the bullet entered ( if it had different surfaces on enter and exit )
		surfacedata_t *pSurfaceData = physprops->GetSurfaceData( tr.surface.surfaceProps );
		Assert( pSurfaceData );
		
		float flMaterialMod = GetDensityFromMaterial(pSurfaceData);

		if ( iDamageType & DMG_MACHINEGUN )
		{
			flMaterialMod *= 0.65;
		}

		// try to penetrate object
		Vector penetrationEnd;
		float flMaxDistance = flDamage / flMaterialMod;

#ifndef CLIENT_DLL
		ClearMultiDamage();

		float flActualDamage = flDamage;

		CTakeDamageInfo dmgInfo( info.m_pAttacker, info.m_pAttacker, flActualDamage, iDamageType );
		CalculateBulletDamageForce( &dmgInfo, info.m_iAmmoType, info.m_vecDirShooting, tr.endpos );
		tr.m_pEnt->DispatchTraceAttack( dmgInfo, info.m_vecDirShooting, &tr );

		DevMsg( 2, "Giving damage ( %.1f ) to entity of type %s\n", flActualDamage, tr.m_pEnt->GetClassname() );

		TraceAttackToTriggers( dmgInfo, tr.startpos, tr.endpos, info.m_vecDirShooting );
#endif

		int stepsize = 16;

		// displacement always stops the bullet
		if ( tr.IsDispSurface() )
		{
			DevMsg( 2, "bullet was stopped by displacement\n" );
			ApplyMultiDamage();
			break;
		}

		// trace through the solid to find the exit point and how much material we went through
		if ( !TraceToExit( tr.endpos, info.m_vecDirShooting, penetrationEnd, stepsize, flMaxDistance ) )
		{
			DevMsg( 2, "bullet was stopped\n" );
			ApplyMultiDamage();
			break;
		}

		// find exact penetration exit
		CTraceFilterSimple ignoreShooter( this, iCollisionGroup );
		UTIL_TraceLine( penetrationEnd, tr.endpos, iTraceMask, &ignoreShooter, &reverseTr );

		// Now we can apply the damage, after we have traced the entity
		// so it doesn't break or die before we have a change to test against it
#ifndef CLIENT_DLL
		ApplyMultiDamage();
#endif

		// Continue looking for the exit point
		if( reverseTr.m_pEnt != tr.m_pEnt && reverseTr.m_pEnt != NULL )
		{
			// something was blocking, trace again
			CTraceFilterSkipTwoEntities ignoreShooterAndBlocker( this, reverseTr.m_pEnt, iCollisionGroup );
			UTIL_TraceLine( penetrationEnd, tr.endpos, iTraceMask, &ignoreShooterAndBlocker, &reverseTr );
		}

		if ( sv_showimpacts.GetBool() )
		{
			debugoverlay->AddLineOverlay( penetrationEnd, reverseTr.endpos, 255, 0, 0, true, 3.0 );
		}

		// penetration was successful

#ifdef CLIENT_DLL
		// bullet did penetrate object, exit Decal
		if ( !( reverseTr.surface.flags & (SURF_SKY|SURF_NODRAW|SURF_HINT|SURF_SKIP) ) )
		{
			CBaseEntity *pEntity = reverseTr.m_pEnt;
			if ( !( !friendlyfire.GetBool() && pEntity && pEntity->GetTeamNumber() == GetTeamNumber() ) )
			{
				UTIL_ImpactTrace( &reverseTr, iDamageType );
			}
		}
#endif

		//setup new start end parameters for successive trace

		// New start point is our last exit point
		vecSrc = reverseTr.endpos + /* 1.0 * */ info.m_vecDirShooting;

		// Reduce bullet damage by material and distanced travelled through that material
		// if it is < 0 we won't go through the loop again
		float flTraceDistance = VectorLength( reverseTr.endpos - tr.endpos );
		
		flDamage -= flMaterialMod * flTraceDistance;

		if( flDamage > 0 )
		{
			DevMsg( 2, "Completed penetration, new damage is %.1f\n", flDamage );
		}
		else
		{
			DevMsg( 2, "bullet was stopped\n" );
		}

		iPenetrations++;
	}

#ifdef GAME_DLL
	HandleHeadshotAchievement( iNumHeadshots );
#endif
}
Exemplo n.º 16
0
void CTeamTrainWatcher::WatcherThink( void )
{
	if ( m_bWaitingToRecede )
	{
		if ( m_flRecedeTime < gpGlobals->curtime )
		{
			m_bWaitingToRecede = false;

			// don't actually recede in overtime
			if ( TeamplayRoundBasedRules() && !TeamplayRoundBasedRules()->InOvertime() )
			{
				// fire recede output
				m_OnTrainStartRecede.FireOutput( this, this );
				HandleTrainMovement( true );
			}
		}
	}

	bool bDisableAlarm = (TeamplayRoundBasedRules() && TeamplayRoundBasedRules()->State_Get() != GR_STATE_RND_RUNNING);
	if ( bDisableAlarm )
	{
		StopCaptureAlarm();
	}

	// given its next node, we can walk the nodes and find the linear
	// distance to the next cp node, or to the goal node

	CFuncTrackTrain *pTrain = m_hTrain;
	if ( pTrain )
	{
		int iOldTrainSpeedLevel = m_iTrainSpeedLevel;

		// how fast is the train moving?
		float flSpeed = pTrain->GetDesiredSpeed();

		// divide speed into regions
		// anything negative is -1

		if ( flSpeed < 0 )
		{
			m_iTrainSpeedLevel = -1;

			// even though our desired speed might be negative,
			// our actual speed might be zero if we're at a dead end...
			// this will turn off the < image when the train is done moving backwards
			if ( pTrain->GetCurrentSpeed() == 0 )
			{
				m_iTrainSpeedLevel = 0;
			}
		}
		else if ( flSpeed > m_flSpeedLevels[2] )
		{
			m_iTrainSpeedLevel = 3;
		}
		else if ( flSpeed > m_flSpeedLevels[1] )
		{
			m_iTrainSpeedLevel = 2;
		}
		else if ( flSpeed > m_flSpeedLevels[0] )
		{
			m_iTrainSpeedLevel = 1;
		}
		else
		{
			m_iTrainSpeedLevel = 0;
		}

		if ( m_iTrainSpeedLevel != iOldTrainSpeedLevel )
		{
			// make sure the sparks are off if we're not moving backwards anymore
			if ( m_bHandleTrainMovement )
			{
				if ( m_iTrainSpeedLevel == 0 && iOldTrainSpeedLevel != 0 )
				{
					HandleSparks( false );
				}
			}

			// play any concepts that we might need to play		
			if ( TeamplayRoundBasedRules() )
			{
				if ( m_iTrainSpeedLevel == 0 && iOldTrainSpeedLevel != 0 )
				{
					TeamplayRoundBasedRules()->HaveAllPlayersSpeakConceptIfAllowed( MP_CONCEPT_CART_STOP );
					m_flNextSpeakForwardConceptTime = 0;
				}
				else if ( m_iTrainSpeedLevel < 0 && iOldTrainSpeedLevel == 0 )
				{
					TeamplayRoundBasedRules()->HaveAllPlayersSpeakConceptIfAllowed( MP_CONCEPT_CART_MOVING_BACKWARD );
					m_flNextSpeakForwardConceptTime = 0;
				}
			}
		}

		if ( m_iTrainSpeedLevel > 0 && m_flNextSpeakForwardConceptTime < gpGlobals->curtime )
		{
			if ( m_hAreaCap.Get() )
			{
				for ( int i = 1; i <= gpGlobals->maxClients; i++ )
				{
					CBaseMultiplayerPlayer *pPlayer = ToBaseMultiplayerPlayer( UTIL_PlayerByIndex( i ) );
					if ( pPlayer )
					{
						if ( m_hAreaCap->IsTouching( pPlayer ) )
						{
							pPlayer->SpeakConceptIfAllowed( MP_CONCEPT_CART_MOVING_FORWARD );
						}
					}
				}
			}

			m_flNextSpeakForwardConceptTime = gpGlobals->curtime + 3.0;
		}

		// what percent progress are we at?
		CPathTrack *pNode = ( pTrain->m_ppath ) ? pTrain->m_ppath->GetNext() : NULL;

		// if we're moving backwards, GetNext is going to be wrong
		if ( flSpeed < 0 )
		{
			pNode = pTrain->m_ppath;
		}

		if ( pNode )
		{
			float flDistanceToGoal = 0;

			// distance to next node
			Vector vecDir = pNode->GetLocalOrigin() - pTrain->GetLocalOrigin();
			flDistanceToGoal = vecDir.Length();

			// distance of next node to goal node
			if ( pNode && pNode != m_hGoalNode )
			{
				// walk this until we get to goal node, or a dead end
				CPathTrack *pPrev = pNode;
				pNode = pNode->GetNext();
				while ( pNode )
				{
					vecDir = pNode->GetLocalOrigin() - pPrev->GetLocalOrigin();
					flDistanceToGoal += vecDir.Length();

					if ( pNode == m_hGoalNode )
						break;

					pPrev = pNode;
					pNode = pNode->GetNext();
				}
			}

			if ( m_flTotalPathDistance <= 0 )
			{
				Assert( !"No path distance in team_train_watcher\n" );
				m_flTotalPathDistance = 1;
			}

			m_flTotalProgress = clamp( 1.0 - ( flDistanceToGoal / m_flTotalPathDistance ), 0.0, 1.0 );

			m_flTrainDistanceFromStart = m_flTotalPathDistance - flDistanceToGoal;

			// play alert sounds if necessary
			for ( int iCount = 0 ; iCount < m_iNumCPLinks ; iCount++ )
			{
				if ( m_flTrainDistanceFromStart < m_CPLinks[iCount].flDistanceFromStart - TEAM_TRAIN_ALERT_DISTANCE )
				{
					// back up twice the alert distance before resetting our flag to play the warning again
					if ( ( m_flTrainDistanceFromStart < m_CPLinks[iCount].flDistanceFromStart - ( TEAM_TRAIN_ALERT_DISTANCE * 2 ) ) || // has receded back twice the alert distance or...
						 ( !m_bTrainCanRecede ) ) // used to catch the case where the train doesn't normally recede but has rolled back down a hill away from the CP
					{
						// reset our alert flag
						m_CPLinks[iCount].bAlertPlayed = false;
					}
				}
				else
				{
					if ( m_flTrainDistanceFromStart < m_CPLinks[iCount].flDistanceFromStart && !m_CPLinks[iCount].bAlertPlayed )
					{
						m_CPLinks[iCount].bAlertPlayed = true;
						bool bFinalPointInMap = false;

						CTeamControlPoint *pCurrentPoint = m_CPLinks[iCount].hCP.Get();
						CTeamControlPointMaster *pMaster = g_hControlPointMasters.Count() ? g_hControlPointMasters[0] : NULL;
						if ( pMaster )
						{
							// if we're not playing mini-rounds 
							if ( !pMaster->PlayingMiniRounds() )  
							{
								for ( int i = FIRST_GAME_TEAM ; i < MAX_CONTROL_POINT_TEAMS ; i++ )
								{
									if ( ObjectiveResource() && ObjectiveResource()->TeamCanCapPoint( pCurrentPoint->GetPointIndex(), i ) )
									{
										if ( pMaster->WouldNewCPOwnerWinGame( pCurrentPoint, i ) )
										{
											bFinalPointInMap = true;
										}
									}
								}
							}
							else 
							{
								// or this is the last round
								if ( pMaster->NumPlayableControlPointRounds() == 1 )
								{
									CTeamControlPointRound *pRound = pMaster->GetCurrentRound();
									if ( pRound )
									{
										for ( int i = FIRST_GAME_TEAM ; i < MAX_CONTROL_POINT_TEAMS ; i++ )
										{
											if ( ObjectiveResource() && ObjectiveResource()->TeamCanCapPoint( pCurrentPoint->GetPointIndex(), i ) )
											{
												if ( pRound->WouldNewCPOwnerWinGame( pCurrentPoint, i ) )
												{
													bFinalPointInMap = true;
												}
											}
										}
									}
								}
							}
						}

						PlayCaptureAlert( pCurrentPoint, bFinalPointInMap );
					}
				}
			}

			// check to see if we need to start or stop the alarm
			if ( flDistanceToGoal <= TEAM_TRAIN_ALARM_DISTANCE )
			{
				if ( ObjectiveResource() )
				{
					ObjectiveResource()->SetTrackAlarm( GetTeamNumber(), true );
				}

				if ( !bDisableAlarm )
				{
					if ( !m_pAlarm )
					{
						if ( m_iNumCPLinks > 0 && !m_bAlarmPlayed )
						{
							// start the alarm at the final point
							StartCaptureAlarm( m_CPLinks[m_iNumCPLinks-1].hCP.Get() );
							m_bAlarmPlayed = true; // used to prevent the alarm from starting again on maps where the train doesn't recede (alarm loops for short time then only plays singles)
						}
					}
					else
					{
						if ( !m_bTrainCanRecede ) // if the train won't recede, we only want to play the alarm for a short time
						{
							if ( m_flAlarmEndTime > 0 && m_flAlarmEndTime < gpGlobals->curtime )
							{
								StopCaptureAlarm();
								SetContextThink( &CTeamTrainWatcher::WatcherAlarmThink, gpGlobals->curtime + TW_ALARM_THINK_INTERVAL, TW_ALARM_THINK );
							}
						}
					}
				}
			}
			else
			{
				if ( ObjectiveResource() )
				{
					ObjectiveResource()->SetTrackAlarm( GetTeamNumber(), false );
				}

				StopCaptureAlarm();
				m_bAlarmPlayed = false;
			}
		}

		if ( tf_show_train_path.GetBool() )
		{
			CPathTrack *nextNode = NULL;
			CPathTrack *node = m_hStartNode;

			CPathTrack::BeginIteration();
			while( node )
			{
				node->Visit();
				nextNode = node->GetNext();

				if ( !nextNode || nextNode->HasBeenVisited() )
					break;

				NDebugOverlay::Line( node->GetAbsOrigin(), nextNode->GetAbsOrigin(), 255, 255, 0, true, NDEBUG_PERSIST_TILL_NEXT_SERVER );

				node = nextNode;
			}
			CPathTrack::EndIteration();

			// show segment of path train is actually on
			node = pTrain->m_ppath;
			if ( node && node->GetNext() )
			{
				NDebugOverlay::HorzArrow( node->GetAbsOrigin(), node->GetNext()->GetAbsOrigin(), 5.0f, 255, 0, 0, 255, true, NDEBUG_PERSIST_TILL_NEXT_SERVER );
			}
		}
	}

	SetContextThink( &CTeamTrainWatcher::WatcherThink, gpGlobals->curtime + 0.1, TW_THINK );
}
//-----------------------------------------------------------------------------
// Purpose: Render a tesla beam in the veiw model.
//
// NOTE: This is a big ugly mess that will get cleaned up when I nail down
//       the effect.
//-----------------------------------------------------------------------------
void CWeaponCombatShield::DrawBeams( C_BaseViewModel *pViewModel )
{
	// Verify data.
	if ( !pViewModel )
		return;

	// Only humans have the tesla effects
	if ( GetTeamNumber() == TEAM_ALIENS )
		return;

	// Init
	if ( !m_pTeslaBeam ) 
	{ 
		InitTeslaBeam(); 
	}
	if ( !m_pShieldBeam ) 
	{ 
		InitShieldBeam(); 
	}

	if ( !m_pShieldBeam || !m_pTeslaBeam )
		return;

	// Variables
	BeamInfo_t beamInfo;
	QAngle vecAngle;
	int iAttachment;

	// Setup a color reflecting the health
	float flShieldHealth = GetShieldHealth();
	color32 color;
	color.r = 206;
	color.g = flShieldHealth * 182;
	color.b = flShieldHealth * 127;
	color.a = 255;

	// Tesla Effect
	Vector vecRightTop, vecRightBottom;
	Vector vecLeftTop, vecLeftBottom;
	iAttachment = pViewModel->LookupAttachment( "LeftBottom" );
	pViewModel->GetAttachment( iAttachment, vecLeftBottom, vecAngle );
	pViewModel->UncorrectViewModelAttachment( vecLeftBottom );

	iAttachment = pViewModel->LookupAttachment( "LeftTip" );
	pViewModel->GetAttachment( iAttachment, vecLeftTop, vecAngle );
	pViewModel->UncorrectViewModelAttachment( vecLeftTop );

	iAttachment = pViewModel->LookupAttachment( "RightBottom" );
	pViewModel->GetAttachment( iAttachment, vecRightBottom, vecAngle );
	pViewModel->UncorrectViewModelAttachment( vecRightBottom );

	iAttachment = pViewModel->LookupAttachment( "RightTip" );
	pViewModel->GetAttachment( iAttachment, vecRightTop, vecAngle );
	pViewModel->UncorrectViewModelAttachment( vecRightTop );

	m_flTeslaLeftInc += weapon_combat_shield_teslaspeed.GetFloat();
	m_flTeslaRightInc += weapon_combat_shield_teslaspeed.GetFloat();
	if ( m_flTeslaLeftInc > 1.0f ) { m_flTeslaLeftInc = 0.0f; }
	if ( m_flTeslaRightInc > 1.0f ) { m_flTeslaRightInc = 0.0f; }

	Vector vecLeft = vecLeftTop - vecLeftBottom;
	Vector vecRight = vecRightTop - vecRightBottom;
	Vector vecStart = vecLeftBottom + ( m_flTeslaLeftInc * vecLeft );
	Vector vecEnd = vecRightBottom + ( m_flTeslaRightInc * vecRight );

	beamInfo.m_vecStart = vecStart;
	beamInfo.m_vecEnd = vecEnd;
	beamInfo.m_flRed = color.r;
	beamInfo.m_flGreen = color.g;
	beamInfo.m_flBlue = color.b;
	beams->UpdateBeamInfo( m_pTeslaBeam, beamInfo );	
	beams->UpdateBeamInfo( m_pTeslaBeam2, beamInfo );	
	beams->DrawBeam( m_pTeslaBeam );
	beams->DrawBeam( m_pTeslaBeam2 );

	// Draw a sprite at the tip of the tesla coil.
	float flSize = 4.0f;

	materials->Bind( m_hShieldSpriteMaterial, this );
	DrawSprite( vecStart, flSize, flSize, color );
	DrawSprite( vecEnd, flSize, flSize, color );

	// Shield Effect
	float flPercentage = random->RandomFloat( 0.0f, 1.0f );
	if ( flPercentage < weapon_combat_shield_teslaskitter.GetFloat() )
	{
		char szShieldJoint[16];
		int nJoint = random->RandomInt( 1, 8 );
		Q_snprintf( szShieldJoint, 16, "Shield%d", nJoint );

		Vector vecJoint;
		int iAttachment = pViewModel->LookupAttachment( &szShieldJoint[0] );
		pViewModel->GetAttachment( iAttachment, vecJoint, vecAngle );
		pViewModel->UncorrectViewModelAttachment( vecJoint );	

		if ( nJoint < 5 )
		{
			beamInfo.m_vecStart = vecLeftTop;
		}
		else
		{
			beamInfo.m_vecStart = vecRightTop;
		}
		beamInfo.m_vecEnd = vecJoint;
		beams->UpdateBeamInfo( m_pTeslaBeam, beamInfo );	
		beams->UpdateBeamInfo( m_pTeslaBeam2, beamInfo );	
		beams->DrawBeam( m_pTeslaBeam );
		beams->DrawBeam( m_pTeslaBeam2 );

		float flSize = 7.0f; 
		color32 color = { 206, 181, 127, 255 };
		materials->Bind( m_hShieldSpriteMaterial, this );
		DrawSprite( beamInfo.m_vecStart, flSize, flSize, color );
	}

#if 0
	// Shield Effect
	char szShieldJoint[16];
	Vector vecShieldJoints[8];
	for( int iJoint = 0; iJoint < 8; ++iJoint )
	{
		Q_snprintf( szShieldJoint, 16, "Shield%d", iJoint+1 );
		iAttachment = pViewModel->LookupAttachment( &szShieldJoint[0] );
		pViewModel->GetAttachment( iAttachment, vecShieldJoints[iJoint], vecAngle );
		pViewModel->UncorrectViewModelAttachment( vecShieldJoints[iJoint] );	
	}

	// Shield Internal
	if ( m_flShieldInc < 1.0f )
	{
		Vector vecEdge, vecEnd;
		if ( m_bLeftToRight )
		{
			vecEdge = vecShieldJoints[((m_nShieldEdge+1)%8)] - vecShieldJoints[m_nShieldEdge];
			vecEnd = vecShieldJoints[m_nShieldEdge] + ( m_flShieldInc * vecEdge );
		}
		else
		{
			vecEdge = vecShieldJoints[m_nShieldEdge] - vecShieldJoints[((m_nShieldEdge+1)%8)];
			vecEnd = vecShieldJoints[((m_nShieldEdge+1)%8)] + ( m_flShieldInc * vecEdge );
		}

		if ( m_nShieldEdge < 5 )
		{
			beamInfo.m_vecStart = vecLeftTop;
		}
		else
		{
			beamInfo.m_vecStart = vecRightTop;
		}

		beamInfo.m_vecEnd = vecEnd;
		beams->UpdateBeamPoints( m_pShieldBeam2, beamInfo );
		beams->UpdateBeamPoints( m_pShieldBeam3, beamInfo );
		beams->DrawBeam( m_pShieldBeam2 );
		beams->DrawBeam( m_pShieldBeam3 );

		m_flShieldInc += m_flShieldSpeed;
	}
	else
	{
		m_flShieldInc = 0.0f;
		m_flShieldSpeed = random->RandomFloat( 0.015f, 0.15f );
		m_nShieldEdge = random->RandomInt( 0, 7 );

		float flSide = random->RandomFloat( 0.0f, 1.0f );
		m_bLeftToRight = ( flSide < 0.5f );
	}

	// Shield Outline
	for( iJoint = 0; iJoint < 8; ++iJoint )
	{
		beamInfo.m_vecStart = vecShieldJoints[iJoint];
		beamInfo.m_vecEnd = vecShieldJoints[(iJoint+1)%8];
		beams->UpdateBeamPoints( m_pShieldBeam, beamInfo );
		beams->UpdateBeamPoints( m_pShieldBeam2, beamInfo );
		beams->DrawBeam( m_pShieldBeam );
		beams->DrawBeam( m_pShieldBeam2 );

		// Draw a sprite at the tip of the tesla coil.
		float flSize = 3.0f;
		color32 color = { 255, 255, 0, 255 };
		materials->Bind( m_hShieldSpriteMaterial, this );
		DrawSprite( vecShieldJoints[iJoint], flSize, flSize, color );
	}
#endif
}
Exemplo n.º 18
0
// ==========================================================
// given a start node and a list of goal nodes
// calculate the distance between each
// ==========================================================
void CTeamTrainWatcher::WatcherActivate( void )
{		
	m_flRecedeTime = 0;
	m_bWaitingToRecede = false;
	m_bCapBlocked = false;
	m_flNextSpeakForwardConceptTime = 0;
	m_hAreaCap = NULL;
	m_flTrainDistanceFromStart = 0.0f;

	m_bAlarmPlayed = false;

	m_Sparks.Purge();

	StopCaptureAlarm();

	// init our train
	m_hTrain = dynamic_cast<CFuncTrackTrain*>( gEntList.FindEntityByName( NULL, m_iszTrain ) );
	if ( !m_hTrain )
	{
		Warning("%s failed to find train named '%s'\n", GetClassname(), STRING( m_iszTrain ) );
	}

	// find the trigger area that will give us movement updates and find the sparks (if we're going to handle the train movement)
	if ( m_bHandleTrainMovement )
	{
		if ( m_hTrain )
		{
			CTriggerAreaCapture *pArea = dynamic_cast<CTriggerAreaCapture *>( gEntList.FindEntityByClassname( NULL, "trigger_capture_area" ) );
			while( pArea )
			{
				if ( pArea->GetParent() == m_hTrain.Get() )
				{
					// this is the capture area we care about, so let it know that we want updates on the capture numbers
					pArea->SetTrainWatcher( this );
					break;
				}

				pArea = dynamic_cast<CTriggerAreaCapture *>( gEntList.FindEntityByClassname( pArea, "trigger_capture_area" ) );
			}
		}

		// init the sprites (if any)
		CEnvSpark *pSpark = dynamic_cast<CEnvSpark*>( gEntList.FindEntityByName( NULL, m_iszSparkName ) );
		while ( pSpark )
		{
			m_Sparks.AddToTail( pSpark );
			pSpark = dynamic_cast<CEnvSpark*>( gEntList.FindEntityByName( pSpark, m_iszSparkName ) );
		}
	}

	// init our array of path_tracks linked to control points
	m_iNumCPLinks = 0;

	int i;
	for ( i = 0 ; i < MAX_CONTROL_POINTS ; i++ )
	{
		CPathTrack *pPathTrack = dynamic_cast<CPathTrack*>( gEntList.FindEntityByName( NULL, m_iszLinkedPathTracks[i] ) );
		CTeamControlPoint *pCP = dynamic_cast<CTeamControlPoint*>( gEntList.FindEntityByName( NULL, m_iszLinkedCPs[i] ) );
		if ( pPathTrack && pCP )
		{
			m_CPLinks[m_iNumCPLinks].hPathTrack = pPathTrack;
			m_CPLinks[m_iNumCPLinks].hCP = pCP;
			m_CPLinks[m_iNumCPLinks].flDistanceFromStart = 0;	// filled in when we parse the nodes
			m_CPLinks[m_iNumCPLinks].bAlertPlayed = false;
			m_iNumCPLinks++;
		}
	}

	// init our start and goal nodes
	m_hStartNode = dynamic_cast<CPathTrack*>( gEntList.FindEntityByName( NULL, m_iszStartNode ) );
	if ( !m_hStartNode )
	{
		Warning("%s failed to find path_track named '%s'\n", GetClassname(), STRING(m_iszStartNode) );
	}

	m_hGoalNode = dynamic_cast<CPathTrack*>( gEntList.FindEntityByName( NULL, m_iszGoalNode ) );
	if ( !m_hGoalNode )
	{
		Warning("%s failed to find path_track named '%s'\n", GetClassname(), STRING(m_iszGoalNode) );
	}

	m_flTotalPathDistance = 0.0f;

	CUtlVector< float > hillData;
	bool bOnHill = false;

	bool bDownHillData[TEAM_TRAIN_MAX_HILLS];
	Q_memset( bDownHillData, 0, sizeof( bDownHillData ) );
	int iHillCount = 0;

	if( m_hStartNode.Get() && m_hGoalNode.Get() )
	{
		CPathTrack *pNode = m_hStartNode;
		CPathTrack *pPrev = pNode;
		CPathTrack *pHillStart = NULL;
		pNode = pNode->GetNext();
		int iHillType = HILL_TYPE_NONE;

		// don't check the start node for links. If it's linked, it will have 0 distance anyway
		while ( pNode )
		{
			Vector dir = pNode->GetLocalOrigin() - pPrev->GetLocalOrigin();
			float length = dir.Length();

			m_flTotalPathDistance += length;

			// gather our hill data for the HUD
			if ( pNode->GetHillType() != iHillType )
			{
				if ( !bOnHill ) // we're at the start of a hill
				{
					hillData.AddToTail( m_flTotalPathDistance );
					bOnHill = true;
					pHillStart = pNode;

					if ( iHillCount < TEAM_TRAIN_MAX_HILLS )
					{
						bDownHillData[iHillCount] = pNode->IsDownHill() ? true : false;
						iHillCount++;
					}
				}
				else // we're at the end of a hill
				{
					float flDistance = m_flTotalPathDistance - length; // subtract length because the prev node was the end of the hill (not this one)

					if ( pHillStart && ( pHillStart == pPrev ) )
					{
						flDistance = m_flTotalPathDistance; // we had a single node marked as a hill, so we'll use the current distance as the next marker
					}

					hillData.AddToTail( flDistance ); 

					// is our current node the start of another hill?
					if ( pNode->GetHillType() != HILL_TYPE_NONE )
					{
						hillData.AddToTail( m_flTotalPathDistance );
						bOnHill = true;
						pHillStart = pNode;

						if ( iHillCount < TEAM_TRAIN_MAX_HILLS )
						{
							bDownHillData[iHillCount] = pNode->IsDownHill() ? true : false;
							iHillCount++;
						}
					}
					else
					{
						bOnHill = false;
						pHillStart = NULL;
					}
				}

				iHillType = pNode->GetHillType();
			}

			// if pNode is one of our cp nodes, store its distance from m_hStartNode
			for ( i = 0 ; i < m_iNumCPLinks ; i++ )
			{
				if ( m_CPLinks[i].hPathTrack == pNode )
				{
					m_CPLinks[i].flDistanceFromStart = m_flTotalPathDistance;
					break;
				}
			}

			if ( pNode == m_hGoalNode )
				break;

			pPrev = pNode;
			pNode = pNode->GetNext();
		}
	}

	// if we don't have an even number of entries in our hill data (beginning/end) add the final distance
	if ( ( hillData.Count() % 2 ) != 0 )
	{
		hillData.AddToTail( m_flTotalPathDistance );
	}

	if ( ObjectiveResource() )
	{
		ObjectiveResource()->ResetHillData( GetTeamNumber() );

		// convert our hill data into 0-1 percentages for networking
		if ( m_flTotalPathDistance > 0 && hillData.Count() > 0 )
		{
			i = 0;
	 		while ( i < hillData.Count() )
			{
				if ( i < TEAM_TRAIN_HILLS_ARRAY_SIZE - 1 ) // - 1 because we want to use 2 entries
				{
					// add/subtract to the hill start/end to fix rounding errors in the HUD when the train
					// stops at the bottom/top of a hill but the HUD thinks the train is still on the hill
					ObjectiveResource()->SetHillData( GetTeamNumber(), (hillData[i] / m_flTotalPathDistance) + 0.005f, (hillData[i+1] / m_flTotalPathDistance) - 0.005f, bDownHillData[i/2] );
				}
				i = i + 2;
			}
		}
	}
 
	// We have total distance and increments in our links array
	for ( i=0;i<m_iNumCPLinks;i++ )
	{
		int iCPIndex = m_CPLinks[i].hCP.Get()->GetPointIndex();
// This can be pulled once DoD includes team_objectiveresource.* and c_team_objectiveresource.*
#ifndef DOD_DLL 
		ObjectiveResource()->SetTrainPathDistance( iCPIndex, m_CPLinks[i].flDistanceFromStart / m_flTotalPathDistance );
#endif
	}

#ifdef GLOWS_ENABLE
	FindGlowEntity();
#endif // GLOWS_ENABLE

	InternalSetSpeedForwardModifier( m_flSpeedForwardModifier );

	SetContextThink( &CTeamTrainWatcher::WatcherThink, gpGlobals->curtime + 0.1, TW_THINK );
}
Exemplo n.º 19
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CBasePlasmaProjectile::Start(CParticleMgr *pParticleMgr, IPrototypeArgAccess *pArgs)
{
	m_pParticleMgr = pParticleMgr;
	m_pParticleMgr->AddEffect( &m_ParticleEffect, this );

	PMaterialHandle	HeadMaterial, TrailMaterial;

	// Load the projectile material
	if ( GetTeamNumber() == TEAM_HUMANS )
	{
		HeadMaterial = m_ParticleEffect.FindOrAddMaterial( "effects/human_tracers/human_sparksprite_A1" );
		TrailMaterial = m_ParticleEffect.FindOrAddMaterial( "effects/human_tracers/human_sparktracer_A_" );
	}
	else
	{
		HeadMaterial = m_ParticleEffect.FindOrAddMaterial( "effects/alien_tracers/alien_pbsprite_A1" );
		TrailMaterial = m_ParticleEffect.FindOrAddMaterial( "effects/alien_tracers/alien_pbtracer_A_" );
	}

	// Create the head & trail
	m_pHeadParticle = (SimpleParticle *)m_ParticleEffect.AddParticle(sizeof(SimpleParticle), HeadMaterial );
	m_pTrailParticle = (TrailParticle *)m_ParticleEffect.AddParticle(sizeof(TrailParticle), TrailMaterial );
	if ( !m_pHeadParticle || !m_pTrailParticle )
		return;

	// 3rd person particles are larger
	bool bFirst = (GetOwnerEntity() == C_BasePlayer::GetLocalPlayer());

	m_pHeadParticle->m_Pos = GetRenderOrigin();
	m_pHeadParticle->m_uchColor[0] = 255;
	m_pHeadParticle->m_uchColor[1] = 255;
	m_pHeadParticle->m_uchColor[2] = 255;
	if ( bFirst )
	{
		m_pHeadParticle->m_uchStartSize = 6;
	}
	else
	{
		m_pHeadParticle->m_uchStartSize = shot_head_size.GetInt();
	}
	m_pHeadParticle->m_uchEndSize	= m_pHeadParticle->m_uchStartSize;
	m_pHeadParticle->m_uchStartAlpha = 255;
	m_pHeadParticle->m_uchEndAlpha = 255;
	m_pHeadParticle->m_flRoll = 0;
	m_pHeadParticle->m_flRollDelta = 10;
	m_pHeadParticle->m_iFlags = 0;

	m_pTrailParticle->m_flLifetime = 0;
	m_pTrailParticle->m_Pos = GetRenderOrigin();
	if ( bFirst )
	{
		m_pTrailParticle->m_flWidth = 25;
		m_pTrailParticle->m_flLength = 140;
	}
	else
	{
		m_pTrailParticle->m_flWidth = shot_width.GetFloat();
		m_pTrailParticle->m_flLength = shot_length.GetFloat();
	}
	Color32Init( m_pTrailParticle->m_color, 255, 255, 255, 255 );

	m_flNextSparkEffect = gpGlobals->curtime + RandomFloat( 0.05, 0.4 );
}
Exemplo n.º 20
0
void CSDKPlayer::FireBullet( 
						   Vector vecSrc,	// shooting postion
						   const QAngle &shootAngles,  //shooting angle
						   float vecSpread, // spread vector
						   int iDamage, // base damage
						   int iBulletType, // ammo type
						   CBaseEntity *pevAttacker, // shooter
						   bool bDoEffects,	// create impact effect ?
						   float x,	// spread x factor
						   float y	// spread y factor
						   )
{
	float fCurrentDamage = iDamage;   // damage of the bullet at it's current trajectory
	float flCurrentDistance = 0.0;  //distance that the bullet has traveled so far

	Vector vecDirShooting, vecRight, vecUp;
	AngleVectors( shootAngles, &vecDirShooting, &vecRight, &vecUp );

	if ( !pevAttacker )
		pevAttacker = this;  // the default attacker is ourselves

	// add the spray 
	Vector vecDir = vecDirShooting +
		x * vecSpread * vecRight +
		y * vecSpread * vecUp;

	VectorNormalize( vecDir );

	float flMaxRange = 8000;

	Vector vecEnd = vecSrc + vecDir * flMaxRange; // max bullet range is 10000 units

	trace_t tr; // main enter bullet trace

	UTIL_TraceLine( vecSrc, vecEnd, MASK_SOLID|CONTENTS_DEBRIS|CONTENTS_HITBOX, this, COLLISION_GROUP_NONE, &tr );

	if ( tr.fraction == 1.0f )
		return; // we didn't hit anything, stop tracing shoot

	if ( sv_showimpacts.GetBool() )
	{
#ifdef CLIENT_DLL
		// draw red client impact markers
		debugoverlay->AddBoxOverlay( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), QAngle( 0, 0, 0), 255,0,0,127, 4 );

		if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
		{
			C_BasePlayer *player = ToBasePlayer( tr.m_pEnt );
			player->DrawClientHitboxes( 4, true );
		}
#else
		// draw blue server impact markers
		NDebugOverlay::Box( tr.endpos, Vector(-2,-2,-2), Vector(2,2,2), 0,0,255,127, 4 );

		if ( tr.m_pEnt && tr.m_pEnt->IsPlayer() )
		{
			CBasePlayer *player = ToBasePlayer( tr.m_pEnt );
			player->DrawServerHitboxes( 4, true );
		}
#endif
	}

		//calculate the damage based on the distance the bullet travelled.
		flCurrentDistance += tr.fraction * flMaxRange;

		// damage get weaker of distance
		fCurrentDamage *= pow ( 0.85f, (flCurrentDistance / 500));

		int iDamageType = DMG_BULLET | DMG_NEVERGIB;

		if( bDoEffects )
		{
			// See if the bullet ended up underwater + started out of the water
			if ( enginetrace->GetPointContents( tr.endpos ) & (CONTENTS_WATER|CONTENTS_SLIME) )
			{	
				trace_t waterTrace;
				UTIL_TraceLine( vecSrc, tr.endpos, (MASK_SHOT|CONTENTS_WATER|CONTENTS_SLIME), this, COLLISION_GROUP_NONE, &waterTrace );

				if( waterTrace.allsolid != 1 )
				{
					CEffectData	data;
					data.m_vOrigin = waterTrace.endpos;
					data.m_vNormal = waterTrace.plane.normal;
					data.m_flScale = random->RandomFloat( 8, 12 );

					if ( waterTrace.contents & CONTENTS_SLIME )
					{
						data.m_fFlags |= FX_WATER_IN_SLIME;
					}

					DispatchEffect( "gunshotsplash", data );
				}
			}
			else
			{
				//Do Regular hit effects

				// Don't decal nodraw surfaces
				if ( !( tr.surface.flags & (SURF_SKY|SURF_NODRAW|SURF_HINT|SURF_SKIP) ) )
				{
					CBaseEntity *pEntity = tr.m_pEnt;
					//Tony; only while using teams do we check for friendly fire.
					if ( pEntity && pEntity->IsPlayer() && (pEntity->GetBaseAnimating() && !pEntity->GetBaseAnimating()->IsRagdoll()) )
					{
#if defined ( SDK_USE_TEAMS )
						if ( pEntity->GetTeamNumber() == GetTeamNumber() )
						{
							if ( !friendlyfire.GetBool() )
								UTIL_ImpactTrace( &tr, iDamageType );
						}
#else
						UTIL_ImpactTrace( &tr, iDamageType );
#endif
					}
					//Tony; non player, just go nuts,
					else
					{
						UTIL_ImpactTrace( &tr, iDamageType );
					}
				}
			}
		} // bDoEffects

		// add damage to entity that we hit

#ifdef GAME_DLL
		ClearMultiDamage();

		CTakeDamageInfo info( pevAttacker, pevAttacker, fCurrentDamage, iDamageType );
		CalculateBulletDamageForce( &info, iBulletType, vecDir, tr.endpos );
		tr.m_pEnt->DispatchTraceAttack( info, vecDir, &tr );

		TraceAttackToTriggers( info, tr.startpos, tr.endpos, vecDir );

		ApplyMultiDamage();
#endif
}
Exemplo n.º 21
0
	//-----------------------------------------------------------------------------
	// This is called by the base object when it's time to spawn the control panels
	//-----------------------------------------------------------------------------
	void CPlantedC4::SpawnControlPanels()
	{
		char buf[64];

		// FIXME: Deal with dynamically resizing control panels?

		// If we're attached to an entity, spawn control panels on it instead of use
		CBaseAnimating *pEntityToSpawnOn = this;
		char *pOrgLL = "controlpanel%d_ll";
		char *pOrgUR = "controlpanel%d_ur";
		char *pAttachmentNameLL = pOrgLL;
		char *pAttachmentNameUR = pOrgUR;

		Assert( pEntityToSpawnOn );

		// Lookup the attachment point...
		int nPanel;
		for ( nPanel = 0; true; ++nPanel )
		{
			Q_snprintf( buf, sizeof( buf ), pAttachmentNameLL, nPanel );
			int nLLAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
			if (nLLAttachmentIndex <= 0)
			{
				// Try and use my panels then
				pEntityToSpawnOn = this;
				Q_snprintf( buf, sizeof( buf ), pOrgLL, nPanel );
				nLLAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
				if (nLLAttachmentIndex <= 0)
					return;
			}

			Q_snprintf( buf, sizeof( buf ), pAttachmentNameUR, nPanel );
			int nURAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
			if (nURAttachmentIndex <= 0)
			{
				// Try and use my panels then
				Q_snprintf( buf, sizeof( buf ), pOrgUR, nPanel );
				nURAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
				if (nURAttachmentIndex <= 0)
					return;
			}

			const char *pScreenName;
			GetControlPanelInfo( nPanel, pScreenName );
			if (!pScreenName)
				continue;

			const char *pScreenClassname;
			GetControlPanelClassName( nPanel, pScreenClassname );
			if ( !pScreenClassname )
				continue;

			// Compute the screen size from the attachment points...
			matrix3x4_t	panelToWorld;
			pEntityToSpawnOn->GetAttachment( nLLAttachmentIndex, panelToWorld );

			matrix3x4_t	worldToPanel;
			MatrixInvert( panelToWorld, worldToPanel );

			// Now get the lower right position + transform into panel space
			Vector lr, lrlocal;
			pEntityToSpawnOn->GetAttachment( nURAttachmentIndex, panelToWorld );
			MatrixGetColumn( panelToWorld, 3, lr );
			VectorTransform( lr, worldToPanel, lrlocal );

			float flWidth = lrlocal.x;
			float flHeight = lrlocal.y;

			CVGuiScreen *pScreen = CreateVGuiScreen( pScreenClassname, pScreenName, pEntityToSpawnOn, this, nLLAttachmentIndex );
			pScreen->ChangeTeam( GetTeamNumber() );
			pScreen->SetActualSize( flWidth, flHeight );
			pScreen->SetActive( true );
			pScreen->MakeVisibleOnlyToTeammates( false );
			int nScreen = m_hScreens.AddToTail( );
			m_hScreens[nScreen].Set( pScreen );			
		}
	}
//-----------------------------------------------------------------------------
// Purpose: Plasma sentrygun's fire
//-----------------------------------------------------------------------------
void CObjectMannedPlasmagun::Fire( )
{
    if (m_flNextAttack > gpGlobals->curtime)
        return;

    // Because the plasma sentrygun always thinks it has ammo (see below)
    // we might not have ammo here, in which case we should just abort.
    if ( !m_nAmmoCount )
        return;

    // Make sure we think soon enough in case of firing...
    float flNextRecharge = gpGlobals->curtime + (HasPowerup(POWERUP_EMP) ? MANNED_PLASMAGUN_RECHARGE_TIME * 1.5 : MANNED_PLASMAGUN_RECHARGE_TIME);
    SetNextThink( gpGlobals->curtime + flNextRecharge );

    // We have to flush the bone cache because it's possible that only the bone controllers
    // have changed since the bonecache was generated, and bone controllers aren't checked.
    InvalidateBoneCache();

    QAngle vecAng;
    Vector vecSrc, vecAim;

    // Alternate barrels when firing
    if ( m_bFiringLeft )
    {
        // Aliens permanently fire left barrel because they have no right
        if ( GetTeamNumber() == TEAM_HUMANS )
        {
            m_bFiringLeft = false;
        }
        GetAttachment( m_nBarrelAttachment, vecSrc, vecAng );
        SetActivity( ACT_VM_PRIMARYATTACK );
    }
    else
    {
        m_bFiringLeft = true;
        GetAttachment( m_nRightBarrelAttachment, vecSrc, vecAng );
        SetActivity( ACT_VM_SECONDARYATTACK );
    }

    // Get the distance to the target
    AngleVectors( vecAng, &vecAim, 0, 0 );

    int damageType = GetAmmoDef()->DamageType( m_nAmmoType );
    CBasePlasmaProjectile *pPlasma = CBasePlasmaProjectile::CreatePredicted( vecSrc, vecAim, Vector( 0, 0, 0 ), damageType, GetDriverPlayer() );
    if ( pPlasma )
    {
        pPlasma->SetDamage( obj_manned_plasmagun_damage.GetFloat() );
        pPlasma->m_hOwner = GetDriverPlayer();
        //pPlasma->SetOwnerEntity( this );
        pPlasma->SetMaxRange( m_flMaxRange );
        if ( obj_manned_plasmagun_radius.GetFloat() )
        {
            pPlasma->SetExplosive( obj_manned_plasmagun_radius.GetFloat() );
        }
    }

    CSoundParameters params;
    if ( GetParametersForSound( "ObjectMannedPlasmagun.Fire", params, NULL ) )
    {
        CPASAttenuationFilter filter( this, params.soundlevel );
        if ( IsPredicted() )
        {
            filter.UsePredictionRules();
        }
        EmitSound( filter, entindex(), "ObjectMannedPlasmagun.Fire" );
    }
//	SetSentryAnim( TFTURRET_ANIM_FIRE );
    DoMuzzleFlash();

    --m_nAmmoCount;

    m_flNextIdleTime = gpGlobals->curtime + MANNED_PLASMAGUN_IDLE_TIME;

    // If I'm EMPed, slow the firing rate down
    m_flNextAttack = gpGlobals->curtime + ( HasPowerup(POWERUP_EMP) ? 0.3f : 0.1f );
}
Exemplo n.º 23
0
void CTFBaseRocket::FlyThink( void )
{
    if ( gpGlobals->curtime > m_flCollideWithTeammatesTime && m_bCollideWithTeammates == false )
    {
        m_bCollideWithTeammates = true;
    }

    if ( tf2c_homing_rockets.GetBool() || ( tf2c_homing_deflected_rockets.GetBool() && m_iDeflected ) )
    {
        // Find the closest visible enemy player.
        CUtlVector<CTFPlayer *> vecPlayers;
        int count = CollectPlayers( &vecPlayers, TEAM_ANY, true );
        float flClosest = FLT_MAX;
        Vector vecClosestTarget = vec3_origin;

        for ( int i = 0; i < count; i++ )
        {
            CTFPlayer *pPlayer = vecPlayers[i];
            if ( pPlayer == GetOwnerEntity() )
                continue;

            if ( pPlayer->GetTeamNumber() == GetTeamNumber() && !TFGameRules()->IsDeathmatch() )
                continue;

            Vector vecTarget;
            QAngle angTarget;
            if ( GetWeaponID() == TF_WEAPON_COMPOUND_BOW )
            {
                int iBone = pPlayer->LookupBone( "bip_head" );
                pPlayer->GetBonePosition( iBone, vecTarget, angTarget );;
            }
            else
            {
                vecTarget = pPlayer->EyePosition();
            }

            if ( FVisible( vecTarget ) )
            {
                float flDistSqr = ( vecTarget - GetAbsOrigin() ).LengthSqr();
                if ( flDistSqr < flClosest )
                {
                    flClosest = flDistSqr;
                    vecClosestTarget = vecTarget;
                }
            }
        }

        // Head towards him.
        if ( vecClosestTarget != vec3_origin )
        {
            Vector vecTarget = vecClosestTarget;
            Vector vecDir = vecTarget - GetAbsOrigin();
            VectorNormalize( vecDir );

            float flSpeed = GetAbsVelocity().Length();
            QAngle angForward;
            VectorAngles( vecDir, angForward );
            SetAbsAngles( angForward );
            SetAbsVelocity( vecDir * flSpeed );
        }
    }

    SetNextThink( gpGlobals->curtime + 0.1f );
}
void CObjectMannedPlasmagun::PreDataUpdate( DataUpdateType_t updateType )
{
    BaseClass::PreDataUpdate( updateType );

    m_nPreviousTeam = GetTeamNumber();
}
Exemplo n.º 25
0
//-----------------------------------------------------------------------------
// This is called by the base object when it's time to spawn the control panels
//-----------------------------------------------------------------------------
void CBaseViewModel::SpawnControlPanels()
{
#if defined( VGUI_CONTROL_PANELS )
	char buf[64];

	// Destroy existing panels
	DestroyControlPanels();

	CBaseCombatWeapon *weapon = m_hWeapon.Get();

	if ( weapon == NULL )
	{
		return;
	}

	MDLCACHE_CRITICAL_SECTION();

	// FIXME: Deal with dynamically resizing control panels?

	// If we're attached to an entity, spawn control panels on it instead of use
	CBaseAnimating *pEntityToSpawnOn = this;
	char *pOrgLL = "controlpanel%d_ll";
	char *pOrgUR = "controlpanel%d_ur";
	char *pAttachmentNameLL = pOrgLL;
	char *pAttachmentNameUR = pOrgUR;
	/*
	if ( IsBuiltOnAttachment() )
	{
		pEntityToSpawnOn = dynamic_cast<CBaseAnimating*>((CBaseEntity*)m_hBuiltOnEntity.Get());
		if ( pEntityToSpawnOn )
		{
			char sBuildPointLL[64];
			char sBuildPointUR[64];
			Q_snprintf( sBuildPointLL, sizeof( sBuildPointLL ), "bp%d_controlpanel%%d_ll", m_iBuiltOnPoint );
			Q_snprintf( sBuildPointUR, sizeof( sBuildPointUR ), "bp%d_controlpanel%%d_ur", m_iBuiltOnPoint );
			pAttachmentNameLL = sBuildPointLL;
			pAttachmentNameUR = sBuildPointUR;
		}
		else
		{
			pEntityToSpawnOn = this;
		}
	}
	*/

	Assert( pEntityToSpawnOn );

	// Lookup the attachment point...
	int nPanel;
	for ( nPanel = 0; true; ++nPanel )
	{
		Q_snprintf( buf, sizeof( buf ), pAttachmentNameLL, nPanel );
		int nLLAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
		if (nLLAttachmentIndex <= 0)
		{
			// Try and use my panels then
			pEntityToSpawnOn = this;
			Q_snprintf( buf, sizeof( buf ), pOrgLL, nPanel );
			nLLAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
			if (nLLAttachmentIndex <= 0)
				return;
		}

		Q_snprintf( buf, sizeof( buf ), pAttachmentNameUR, nPanel );
		int nURAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
		if (nURAttachmentIndex <= 0)
		{
			// Try and use my panels then
			Q_snprintf( buf, sizeof( buf ), pOrgUR, nPanel );
			nURAttachmentIndex = pEntityToSpawnOn->LookupAttachment(buf);
			if (nURAttachmentIndex <= 0)
				return;
		}

		const char *pScreenName;
		weapon->GetControlPanelInfo( nPanel, pScreenName );
		if (!pScreenName)
			continue;

		const char *pScreenClassname;
		weapon->GetControlPanelClassName( nPanel, pScreenClassname );
		if ( !pScreenClassname )
			continue;

		// Compute the screen size from the attachment points...
		matrix3x4_t	panelToWorld;
		pEntityToSpawnOn->GetAttachment( nLLAttachmentIndex, panelToWorld );

		matrix3x4_t	worldToPanel;
		MatrixInvert( panelToWorld, worldToPanel );

		// Now get the lower right position + transform into panel space
		Vector lr, lrlocal;
		pEntityToSpawnOn->GetAttachment( nURAttachmentIndex, panelToWorld );
		MatrixGetColumn( panelToWorld, 3, lr );
		VectorTransform( lr, worldToPanel, lrlocal );

		float flWidth = lrlocal.x;
		float flHeight = lrlocal.y;

		CVGuiScreen *pScreen = CreateVGuiScreen( pScreenClassname, pScreenName, pEntityToSpawnOn, this, nLLAttachmentIndex );
		pScreen->ChangeTeam( GetTeamNumber() );
		pScreen->SetActualSize( flWidth, flHeight );
		pScreen->SetActive( false );
		pScreen->MakeVisibleOnlyToTeammates( false );
	
		pScreen->SetAttachedToViewModel( true );
		int nScreen = m_hScreens.AddToTail( );
		m_hScreens[nScreen].Set( pScreen );
	}
#endif
}
Exemplo n.º 26
0
void CHL2MP_Player::SetPlayerModel( void )
{
	const char *szModelName = NULL;
	const char *pszCurrentModelName = modelinfo->GetModelName( GetModel());

	szModelName = engine->GetClientConVarValue( engine->IndexOfEdict( edict() ), "cl_playermodel" );

	if ( ValidatePlayerModel( szModelName ) == false )
	{
		char szReturnString[512];

		if ( ValidatePlayerModel( pszCurrentModelName ) == false )
			pszCurrentModelName = "models/player/carebear.mdl";

		Q_snprintf( szReturnString, sizeof (szReturnString ), "cl_playermodel %s\n", pszCurrentModelName );
		engine->ClientCommand ( edict(), szReturnString );

		szModelName = pszCurrentModelName;
	}

	if ( GetTeamNumber() == TEAM_PINK )
	{
		m_nSkin = 0;
		m_iModelType = TEAM_PINK;
		szModelName = g_ppszRandomCitizenModels[0];
	}
	else if ( GetTeamNumber() == TEAM_GREEN )
	{
		m_nSkin = 2;
		m_iModelType = TEAM_GREEN;
		szModelName = g_ppszRandomCitizenModels[0];
	}
	else
	{
		if ( Q_strlen( szModelName ) == 0 ) 
			szModelName = g_ppszRandomCitizenModels[0];

		if ( m_nSkin == 2 )
			m_iModelType = TEAM_GREEN;
		else
			m_iModelType = TEAM_PINK;
	}

	int modelIndex = modelinfo->GetModelIndex( szModelName );

	if ( modelIndex == -1 )
	{
		szModelName = "models/player/carebear.mdl";
		m_iModelType = TEAM_PINK;
		m_nSkin = 0;

		char szReturnString[512];

		Q_snprintf( szReturnString, sizeof (szReturnString ), "cl_playermodel %s\n", szModelName );
		engine->ClientCommand ( edict(), szReturnString );
	}

	SetModel( szModelName );
	SetupPlayerSoundsByModel( szModelName );

	m_flNextModelChangeTime = gpGlobals->curtime + MODEL_CHANGE_INTERVAL;
}
Exemplo n.º 27
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CFuncRespawnRoom::Activate( void )
{
	BaseClass::Activate();
	m_iOriginalTeam = GetTeamNumber();
	SetActive( true );
}
Exemplo n.º 28
0
void CHL2MP_Player::SetPlayerModel( void )
{
	const char *szModelName = NULL;
	const char *pszCurrentModelName = modelinfo->GetModelName( GetModel());

	szModelName = engine->GetClientConVarValue( engine->IndexOfEdict( edict() ), "cl_playermodel" );

	if ( ValidatePlayerModel( szModelName ) == false )
	{
		char szReturnString[512];

		if ( ValidatePlayerModel( pszCurrentModelName ) == false )
		{
			pszCurrentModelName = "models/Combine_Soldier.mdl";
		}

		Q_snprintf( szReturnString, sizeof (szReturnString ), "cl_playermodel %s\n", pszCurrentModelName );
		engine->ClientCommand ( edict(), szReturnString );

		szModelName = pszCurrentModelName;
	}

	if ( GetTeamNumber() == TEAM_COMBINE )
	{
		int nHeads = ARRAYSIZE( g_ppszRandomCombineModels );
		
		g_iLastCombineModel = ( g_iLastCombineModel + 1 ) % nHeads;
		szModelName = g_ppszRandomCombineModels[g_iLastCombineModel];

		m_iModelType = TEAM_COMBINE;
	}
	else if ( GetTeamNumber() == TEAM_REBELS )
	{
		int nHeads = ARRAYSIZE( g_ppszRandomCitizenModels );

		g_iLastCitizenModel = ( g_iLastCitizenModel + 1 ) % nHeads;
		szModelName = g_ppszRandomCitizenModels[g_iLastCitizenModel];

		m_iModelType = TEAM_REBELS;
	}
	else
	{
		if ( Q_strlen( szModelName ) == 0 ) 
		{
			szModelName = g_ppszRandomCitizenModels[0];
		}

		if ( Q_stristr( szModelName, "models/human") )
		{
			m_iModelType = TEAM_REBELS;
		}
		else
		{
			m_iModelType = TEAM_COMBINE;
		}
	}

	int modelIndex = modelinfo->GetModelIndex( szModelName );

	if ( modelIndex == -1 )
	{
		szModelName = "models/Combine_Soldier.mdl";
		m_iModelType = TEAM_COMBINE;

		char szReturnString[512];

		Q_snprintf( szReturnString, sizeof (szReturnString ), "cl_playermodel %s\n", szModelName );
		engine->ClientCommand ( edict(), szReturnString );
	}

	SetModel( szModelName );
	SetupPlayerSoundsByModel( szModelName );

	m_flNextModelChangeTime = gpGlobals->curtime + MODEL_CHANGE_INTERVAL;
}
Exemplo n.º 29
0
void CHL2MP_Player::SetPlayerTeamModel( void )
{
	const char *szModelName = NULL;
	szModelName = engine->GetClientConVarValue( engine->IndexOfEdict( edict() ), "cl_playermodel" );

	int modelIndex = modelinfo->GetModelIndex( szModelName );

	if ( modelIndex == -1 || ValidatePlayerModel( szModelName ) == false )
	{
		//DHL - Skillet - Changed from combine soldier
		szModelName = DHL_DEFAULTMODEL;
		m_iModelType = TEAM_PROS;

		char szReturnString[512];

		Q_snprintf( szReturnString, sizeof (szReturnString ), "cl_playermodel %s\n", szModelName );
		engine->ClientCommand ( edict(), szReturnString );
	}

	//DHL - Skillet
	if ( GetTeamNumber() == TEAM_MOBSTERS )
	{
		if ( !Q_stristr( szModelName, "models/player/dhl/mobsters" ) )
			szModelName = DHL_DEFAULTMODEL_MOB;
	}
	if ( GetTeamNumber() == TEAM_PROS )
	{
		if ( !Q_stristr( szModelName, "models/player/dhl/professionals" ) )
			szModelName = DHL_DEFAULTMODEL_PRO;
	}

	//DHL - Skillet - Obselete
	//if ( GetTeamNumber() == TEAM_COMBINE )
	//{
	//	if ( Q_stristr( szModelName, "models/human") )
	//	{
	//		int nHeads = ARRAYSIZE( g_ppszRandomCombineModels );
	//	
	//		g_iLastCombineModel = ( g_iLastCombineModel + 1 ) % nHeads;
	//		szModelName = g_ppszRandomCombineModels[g_iLastCombineModel];
	//	}

	//	m_iModelType = TEAM_COMBINE;
	//}
	//else if ( GetTeamNumber() == TEAM_REBELS )
	//{
	//	if ( !Q_stristr( szModelName, "models/human") )
	//	{
	//		int nHeads = ARRAYSIZE( g_ppszRandomCitizenModels );

	//		g_iLastCitizenModel = ( g_iLastCitizenModel + 1 ) % nHeads;
	//		szModelName = g_ppszRandomCitizenModels[g_iLastCitizenModel];
	//	}

	//	m_iModelType = TEAM_REBELS;
	//}
	
	SetModel( szModelName );
	SetupPlayerSoundsByModel( szModelName );

	m_flNextModelChangeTime = gpGlobals->curtime + MODEL_CHANGE_INTERVAL;
}
Exemplo n.º 30
0
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CObjectResupply::CalculatePlacement( CBaseTFPlayer *pPlayer )
{
	trace_t tr;
	Vector vecAiming;
	// Get an aim vector. Don't use GetAimVector() because we don't want autoaiming.
	Vector vecSrc = pPlayer->Weapon_ShootPosition( );
	pPlayer->EyeVectors( &vecAiming );
	Vector vecTarget;
	VectorMA( vecSrc, 90, vecAiming, vecTarget );
	m_vecBuildOrigin = vecTarget;

	// Angle it towards me
	Vector vecForward = pPlayer->WorldSpaceCenter() - m_vecBuildOrigin;
	SetLocalAngles( QAngle( 0, UTIL_VecToYaw( vecForward ), 0 ) );

	// Is there something to attach to? 
	// Use my bounding box, not the build box, so I fit to the wall
	UTIL_TraceLine( vecSrc, vecTarget, MASK_SOLID, pPlayer, COLLISION_GROUP_PLAYER_MOVEMENT, &tr);
	//UTIL_TraceHull( vecSrc, vecTarget, WorldAlignMins(), WorldAlignMaxs(), MASK_SOLID, pPlayer, TFCOLLISION_GROUP_OBJECT, &tr );
	m_vecBuildOrigin = tr.endpos;
	bool bTryToPlaceGroundVersion = false;
	if ( tr.allsolid || (tr.fraction == 1.0) )
	{
		bTryToPlaceGroundVersion = true;
	}
	else 
	{
		// Make sure we're planting on the world
		CBaseEntity *pEntity = tr.m_pEnt;
		if ( pEntity != GetWorldEntity() )
		{
			bTryToPlaceGroundVersion = true;
		}
	}

	// Make sure the wall we've touched is vertical
	if ( !bTryToPlaceGroundVersion && fabs(tr.plane.normal.z) > 0.3 )
	{
		bTryToPlaceGroundVersion = true;
	}

	// Aborting?
	if ( bTryToPlaceGroundVersion )
	{
		// We couldn't find a wall, so try and place a ground version instead
		if ( GetTeamNumber() == TEAM_HUMANS )
		{
			SetModel( RESUPPLY_GROUND_MODEL_HUMAN );
		}
		else
		{
			SetModel( RESUPPLY_GROUND_MODEL );
		}
		UTIL_SetSize(this, RESUPPLY_GROUND_MINS, RESUPPLY_GROUND_MAXS);
		m_vecBuildMins = WorldAlignMins() - Vector( 4,4,0 );
		m_vecBuildMaxs = WorldAlignMaxs() + Vector( 4,4,0 );
		return BaseClass::CalculatePlacement( pPlayer );
	}

	SetupAttachedVersion();
	m_vecBuildMins = WorldAlignMins() - Vector( 4,4,0 );
	m_vecBuildMaxs = WorldAlignMaxs() + Vector( 4,4,0 );

	// Set the angles
	vecForward = tr.plane.normal;
	SetLocalAngles( QAngle( 0, UTIL_VecToYaw( vecForward ), 0 ) );

	// Trace back from the corners
	Vector vecMins, vecMaxs, vecModelMins, vecModelMaxs;
	const model_t *pModel = GetModel();
	modelinfo->GetModelBounds( pModel, vecModelMins, vecModelMaxs );

	// Check the four build points
	Vector vecPointCheck = (vecForward * 32);
	Vector vecUp = Vector(0,0,1);
	Vector vecRight;
	CrossProduct( vecUp, vecForward, vecRight );
	float flWidth = fabs(vecModelMaxs.y - vecModelMins.y) * 0.5;
	float flHeight = fabs(vecModelMaxs.z - vecModelMins.z) * 0.5;

	bool bResult = true;
	if ( bResult )
	{
		bResult = CheckBuildPoint( m_vecBuildOrigin + (vecRight * flWidth) + (vecUp * flHeight), vecPointCheck );
	}
	if ( bResult )
	{
		bResult = CheckBuildPoint( m_vecBuildOrigin + (vecRight * flWidth) - (vecUp * flHeight), vecPointCheck );
	}
	if ( bResult )
	{
		bResult = CheckBuildPoint( m_vecBuildOrigin - (vecRight * flWidth) + (vecUp * flHeight), vecPointCheck );
	}
	if ( bResult )
	{
		bResult = CheckBuildPoint( m_vecBuildOrigin - (vecRight * flWidth) - (vecUp * flHeight), vecPointCheck );
	}

	AttemptToFindPower();

	return bResult;
}