//----------------------------------------------------------------------------- // Purpose: Can I build the specified object on the specified build point? //----------------------------------------------------------------------------- bool CInfoBuildPoint::CanBuildObjectOnBuildPoint( int iPoint, int iObjectType ) { ASSERT( iPoint <= GetNumBuildPoints() ); if ( m_hObjectBuiltOnMe ) return false; // Manned guns? if ( m_spawnflags & SF_BUILDPOINT_ALLOW_ALL_GUNS ) { if ( (iObjectType == OBJ_MANNED_PLASMAGUN) || (iObjectType == OBJ_MANNED_MISSILELAUNCHER) || (iObjectType == OBJ_MANNED_SHIELD) || (iObjectType == OBJ_SENTRYGUN_PLASMA) ) return true; } // Vehicles if ( m_spawnflags & SF_BUILDPOINT_ALLOW_VEHICLES ) { if ( IsObjectAVehicle(iObjectType) ) return true; } // Check our unique if ( m_iAllowedObjectType >= 0 && m_iAllowedObjectType == iObjectType ) return true; return false; }
//----------------------------------------------------------------------------- // Purpose: Give me the origin & angles of the specified build point //----------------------------------------------------------------------------- bool CInfoBuildPoint::GetBuildPoint( int iPoint, Vector &vecOrigin, QAngle &vecAngles ) { ASSERT( iPoint <= GetNumBuildPoints() ); vecOrigin = GetAbsOrigin(); vecAngles = GetAbsAngles(); return true; }
//----------------------------------------------------------------------------- // 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: Return true if the specified object type can be built on this point //----------------------------------------------------------------------------- bool CBaseObject::CanBuildObjectOnBuildPoint( int iPoint, int iObjectType ) { Assert( iPoint >= 0 && iPoint <= GetNumBuildPoints() ); // Allowed to build here? if ( !m_BuildPoints[iPoint].m_bValidObjects[ iObjectType ] ) return false; // Buildpoint empty? return ( m_BuildPoints[iPoint].m_hObject == NULL ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CBaseObject::RemoveAllObjects( void ) { for ( int i = 0; i < GetNumBuildPoints(); i++ ) { if ( m_BuildPoints[i].m_hObject ) { #ifndef CLIENT_DLL UTIL_Remove( m_BuildPoints[i].m_hObject ); #endif } } }
//----------------------------------------------------------------------------- // Purpose: Return the number of objects on my build points //----------------------------------------------------------------------------- int CBaseObject::GetNumObjectsOnMe( void ) { int iObjects = 0; for ( int i = 0; i < GetNumBuildPoints(); i++ ) { if ( m_BuildPoints[i].m_hObject ) { iObjects++; } } return iObjects; }
int CBaseObject::GetBuildPointAttachmentIndex( int iPoint ) const { Assert( iPoint >= 0 && iPoint <= GetNumBuildPoints() ); if ( m_BuildPoints[iPoint].m_bPutInAttachmentSpace ) { return m_BuildPoints[iPoint].m_iAttachmentNum; } else { return 0; } }
//----------------------------------------------------------------------------- // Figure out which role of a vehicle a child vehicle is sitting in.. //----------------------------------------------------------------------------- int CBaseTFVehicle::GetChildVehicleRole( CBaseTFVehicle *pChild ) { int nBuildPoints = GetNumBuildPoints(); for( int i = 0; i < nBuildPoints; i++ ) { CBaseObject* pObject = GetBuildPointObject(i); if (pObject == pChild) { return GetBuildPointPassenger(i); } } return -1; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CBaseObject::GetBuildPoint( int iPoint, Vector &vecOrigin, QAngle &vecAngles ) { Assert( iPoint >= 0 && iPoint <= GetNumBuildPoints() ); int iAttachmentNum = m_BuildPoints[iPoint].m_iAttachmentNum; if ( iAttachmentNum == -1 ) { vecOrigin = GetAbsOrigin(); vecAngles = GetAbsAngles(); return true; } else { return GetAttachment( m_BuildPoints[iPoint].m_iAttachmentNum, vecOrigin, vecAngles ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CBaseObject::SetObjectOnBuildPoint( int iPoint, CBaseObject *pObject ) { Assert( iPoint >= 0 && iPoint <= GetNumBuildPoints() ); m_BuildPoints[iPoint].m_hObject = pObject; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- CBaseObject* CBaseObject::GetBuildPointObject( int iPoint ) { Assert( iPoint >= 0 && iPoint <= GetNumBuildPoints() ); return m_BuildPoints[iPoint].m_hObject; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CBaseObject::AddValidObjectToBuildPoint( int iPoint, int iObjectType ) { Assert( iPoint <= GetNumBuildPoints() ); m_BuildPoints[iPoint].m_bValidObjects[ iObjectType ] = true; }
//----------------------------------------------------------------------------- // Purpose: I've finished building the specified object on the specified build point //----------------------------------------------------------------------------- void CInfoBuildPoint::SetObjectOnBuildPoint( int iPoint, CBaseObject *pObject ) { ASSERT( iPoint <= GetNumBuildPoints() ); m_hObjectBuiltOnMe = pObject; }
//----------------------------------------------------------------------------- // 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 ); } } }