//----------------------------------------------------------------------------- // Purpose: Figure out if I should be using an attached item rather than this vehicle itself. //----------------------------------------------------------------------------- bool CBaseTFVehicle::UseAttachedItem( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { CBaseTFPlayer* pPlayer = dynamic_cast<CBaseTFPlayer*>(pActivator); if ( !pPlayer || !InSameTeam(pPlayer) ) return false; Vector vecPlayerOrigin = pPlayer->GetAbsOrigin(); int nBestBuildPoint = -1; float fBestDistance = FLT_MAX; // Get the closest regular entry point: int nRole = LocateEntryPoint( pPlayer, &fBestDistance ); // Iterate through each of the build points, if any, and see which we are closest to. int nBuildPoints = GetNumBuildPoints(); for( int i = 0; i < nBuildPoints; i++ ) { CBaseObject* pObject = GetBuildPointObject(i); // If there's something in the build point that isn't in the process of being built or placed: if( pObject && !pObject->IsPlacing() && !pObject->IsBuilding() ) { Vector vecOrigin; QAngle vecAngles; // If the build point is the default point for this role, just take it if (GetBuildPointPassenger(i) == nRole) { nBestBuildPoint = i; break; } // And I can get the build point. if( GetBuildPoint( i, vecOrigin, vecAngles ) ) { float fLength2dSqr = (vecOrigin - vecPlayerOrigin).AsVector2D().LengthSqr(); if( fLength2dSqr < fBestDistance ) { nBestBuildPoint = i; fBestDistance = fLength2dSqr; } } } } if( nBestBuildPoint >= 0 ) { // They're using an item on me, so push out the deterioration time ResetDeteriorationTime(); GetBuildPointObject(nBestBuildPoint)->Use( pActivator, pCaller, useType, value ); return true; } return false; }
//----------------------------------------------------------------------------- // Purpose: Returns an exit point for a vehicle built on a build point... //----------------------------------------------------------------------------- void CInfoBuildPoint::GetExitPoint( CBaseEntity *pPlayer, int iPoint, Vector *pAbsOrigin, QAngle *pAbsAngles ) { // FIXME: In future, we may well want to use specific exit attachments here... GetBuildPoint( iPoint, *pAbsOrigin, *pAbsAngles ); // Move back along the forward direction a bit... Vector vecForward; AngleVectors( *pAbsAngles, &vecForward ); *pAbsOrigin -= vecForward * 60; // Now select a good spot to drop onto Vector vNewPos; if ( !EntityPlacementTest(pPlayer, *pAbsOrigin, vNewPos, true) ) { Warning("Can't find valid place to exit object.\n"); return; } *pAbsOrigin = vNewPos; }
//----------------------------------------------------------------------------- // 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 ); } } }