You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
217 lines
6.9 KiB
217 lines
6.9 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: Map entity that allows players to build objects on it |
|
// |
|
// $NoKeywords: $ |
|
//=============================================================================// |
|
#include "cbase.h" |
|
#include "EntityOutput.h" |
|
#include "EntityList.h" |
|
#include "tf_team.h" |
|
#include "baseentity.h" |
|
#include "info_buildpoint.h" |
|
#include "tf_gamerules.h" |
|
|
|
// Spawnflags |
|
const int SF_BUILDPOINT_ALLOW_ALL_GUNS = 0x01; // Allow all manned guns to be built on this point |
|
const int SF_BUILDPOINT_ALLOW_VEHICLES = 0x02; // Allow all vehicles to be built on this point |
|
|
|
BEGIN_DATADESC( CInfoBuildPoint ) |
|
|
|
// keys |
|
DEFINE_KEYFIELD_NOT_SAVED( m_iszAllowedObject, FIELD_STRING, "AllowedObject" ), |
|
|
|
END_DATADESC() |
|
|
|
LINK_ENTITY_TO_CLASS( info_buildpoint, CInfoBuildPoint ); |
|
|
|
// List of buildpoints |
|
CUtlVector<CInfoBuildPoint*> g_MapDefinedBuildPoints; |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CInfoBuildPoint::Spawn( void ) |
|
{ |
|
g_MapDefinedBuildPoints.AddToTail( this ); |
|
|
|
m_iAllowedObjectType = -1; |
|
if ( m_iszAllowedObject != NULL_STRING ) |
|
{ |
|
for ( int i = 0; i < OBJ_LAST; i++ ) |
|
{ |
|
if ( !Q_strcmp( STRING(m_iszAllowedObject), GetObjectInfo(i)->m_pClassName ) ) |
|
{ |
|
m_iAllowedObjectType = i; |
|
break; |
|
} |
|
} |
|
} |
|
|
|
BaseClass::Spawn(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: |
|
//----------------------------------------------------------------------------- |
|
void CInfoBuildPoint::UpdateOnRemove( void ) |
|
{ |
|
g_MapDefinedBuildPoints.FindAndRemove( this ); |
|
BaseClass::UpdateOnRemove(); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Tell me how many build points you have |
|
//----------------------------------------------------------------------------- |
|
int CInfoBuildPoint::GetNumBuildPoints( void ) const |
|
{ |
|
return 1; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// 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; |
|
} |
|
|
|
int CInfoBuildPoint::GetBuildPointAttachmentIndex( int iPoint ) const |
|
{ |
|
return 0; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// 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: 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: Get the number of objects build on this entity |
|
//----------------------------------------------------------------------------- |
|
int CInfoBuildPoint::GetNumObjectsOnMe( void ) |
|
{ |
|
if ( m_hObjectBuiltOnMe ) |
|
return 1; |
|
|
|
return 0; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get the first object that's built on me |
|
//----------------------------------------------------------------------------- |
|
CBaseEntity *CInfoBuildPoint::GetFirstObjectOnMe( void ) |
|
{ |
|
return m_hObjectBuiltOnMe; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Get the first object of type, return NULL if no such type available |
|
//----------------------------------------------------------------------------- |
|
CBaseObject *CInfoBuildPoint::GetObjectOfTypeOnMe( int iObjectType ) |
|
{ |
|
if ( m_hObjectBuiltOnMe ) |
|
{ |
|
if ( m_hObjectBuiltOnMe->ObjectType() == iObjectType ) |
|
return m_hObjectBuiltOnMe; |
|
} |
|
|
|
return NULL; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Remove all objects built on me |
|
//----------------------------------------------------------------------------- |
|
void CInfoBuildPoint::RemoveAllObjects( void ) |
|
{ |
|
UTIL_Remove( m_hObjectBuiltOnMe ); |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Return the maximum distance that this entity's build points can be snapped to |
|
//----------------------------------------------------------------------------- |
|
float CInfoBuildPoint::GetMaxSnapDistance( int iPoint ) |
|
{ |
|
return 64; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Return true if it's possible that build points on this entity may move in local space (i.e. due to animation) |
|
//----------------------------------------------------------------------------- |
|
bool CInfoBuildPoint::ShouldCheckForMovement( void ) |
|
{ |
|
return false; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: I've finished building the specified object on the specified build point |
|
//----------------------------------------------------------------------------- |
|
int CInfoBuildPoint::FindObjectOnBuildPoint( CBaseObject *pObject ) |
|
{ |
|
return 1; |
|
} |
|
|
|
//----------------------------------------------------------------------------- |
|
// 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; |
|
}
|
|
|