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.
376 lines
8.2 KiB
376 lines
8.2 KiB
4 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
//=============================================================================//
|
||
|
#include "cbase.h"
|
||
|
#include "filters.h"
|
||
|
#include "team_control_point.h"
|
||
|
#include "tf_gamerules.h"
|
||
|
#include "econ_wearable.h"
|
||
|
#include "bot/tf_bot.h"
|
||
|
|
||
|
// memdbgon must be the last include file in a .cpp file!!!
|
||
|
#include "tier0/memdbgon.h"
|
||
|
|
||
|
//=============================================================================
|
||
|
//
|
||
|
// Team Fortress Team Filter
|
||
|
//
|
||
|
class CFilterTFTeam : public CBaseFilter
|
||
|
{
|
||
|
DECLARE_CLASS( CFilterTFTeam, CBaseFilter );
|
||
|
|
||
|
public:
|
||
|
|
||
|
void InputRoundSpawn( inputdata_t &inputdata );
|
||
|
void InputRoundActivate( inputdata_t &inputdata );
|
||
|
|
||
|
inline bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity );
|
||
|
|
||
|
private:
|
||
|
|
||
|
string_t m_iszControlPointName;
|
||
|
|
||
|
DECLARE_DATADESC();
|
||
|
};
|
||
|
|
||
|
BEGIN_DATADESC( CFilterTFTeam )
|
||
|
|
||
|
DEFINE_KEYFIELD( m_iszControlPointName, FIELD_STRING, "controlpoint" ),
|
||
|
|
||
|
// Inputs.
|
||
|
DEFINE_INPUTFUNC( FIELD_VOID, "RoundSpawn", InputRoundSpawn ),
|
||
|
DEFINE_INPUTFUNC( FIELD_VOID, "RoundActivate", InputRoundActivate ),
|
||
|
|
||
|
END_DATADESC()
|
||
|
|
||
|
|
||
|
LINK_ENTITY_TO_CLASS( filter_activator_tfteam, CFilterTFTeam );
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool CFilterTFTeam::PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity )
|
||
|
{
|
||
|
// is the entity we're asking about on the winning
|
||
|
// team during the bonus time? (winners pass all filters)
|
||
|
if ( TFGameRules() &&
|
||
|
( TFGameRules()->State_Get() == GR_STATE_TEAM_WIN ) &&
|
||
|
( TFGameRules()->GetWinningTeam() == pEntity->GetTeamNumber() ) )
|
||
|
{
|
||
|
// this should open all doors for the winners
|
||
|
if ( m_bNegated )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ( pEntity->GetTeamNumber() == GetTeamNumber() );
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CFilterTFTeam::InputRoundSpawn( inputdata_t &input )
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose:
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void CFilterTFTeam::InputRoundActivate( inputdata_t &input )
|
||
|
{
|
||
|
if ( m_iszControlPointName != NULL_STRING )
|
||
|
{
|
||
|
CTeamControlPoint *pControlPoint = dynamic_cast<CTeamControlPoint*>( gEntList.FindEntityByName( NULL, m_iszControlPointName ) );
|
||
|
if ( pControlPoint )
|
||
|
{
|
||
|
ChangeTeam( pControlPoint->GetTeamNumber() );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Warning( "%s failed to find control point named '%s'\n", GetClassname(), STRING(m_iszControlPointName) );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/// filter the excludes people that can't cap
|
||
|
// has to be chained with a team filter
|
||
|
|
||
|
class CFilterTFCanCap : public CBaseFilter
|
||
|
{
|
||
|
DECLARE_CLASS( CFilterTFCanCap, CBaseFilter );
|
||
|
|
||
|
public:
|
||
|
|
||
|
inline bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity )
|
||
|
{
|
||
|
CTFPlayer *pPlayer = ToTFPlayer( pEntity );
|
||
|
|
||
|
if ( !pPlayer )
|
||
|
return false;
|
||
|
|
||
|
// No disguised spies
|
||
|
if ( pPlayer->m_Shared.InCond( TF_COND_DISGUISED ) || pPlayer->m_Shared.InCond( TF_COND_DISGUISING ) )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// No stealthed spies
|
||
|
if ( pPlayer->m_Shared.IsStealthed() )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// No invuln players
|
||
|
if ( pPlayer->m_Shared.IsInvulnerable() || pPlayer->m_Shared.InCond( TF_COND_INVULNERABLE_WEARINGOFF ) )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return ( GetTeamNumber() == TEAM_UNASSIGNED || ( pPlayer->GetTeamNumber() == GetTeamNumber() ) );
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
DECLARE_DATADESC();
|
||
|
};
|
||
|
|
||
|
BEGIN_DATADESC( CFilterTFCanCap )
|
||
|
END_DATADESC()
|
||
|
|
||
|
LINK_ENTITY_TO_CLASS( filter_tf_player_can_cap, CFilterTFCanCap );
|
||
|
|
||
|
|
||
|
// ###################################################################
|
||
|
// > FilterDamagedByWeaponInSlot
|
||
|
// ###################################################################
|
||
|
class FilterDamagedByWeaponInSlot : public CBaseFilter
|
||
|
{
|
||
|
DECLARE_CLASS( FilterDamagedByWeaponInSlot, CBaseFilter );
|
||
|
DECLARE_DATADESC();
|
||
|
|
||
|
protected:
|
||
|
|
||
|
bool PassesFilterImpl(CBaseEntity *pCaller, CBaseEntity *pEntity )
|
||
|
{
|
||
|
ASSERT( false );
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
bool PassesDamageFilterImpl(const CTakeDamageInfo &info)
|
||
|
{
|
||
|
if ( info.GetWeapon() )
|
||
|
{
|
||
|
CTFWeaponBase* pWeapon = dynamic_cast<CTFWeaponBase *>( info.GetWeapon() );
|
||
|
if ( pWeapon )
|
||
|
{
|
||
|
return pWeapon->GetSlot() == m_iWeaponSlot;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
int m_iWeaponSlot;
|
||
|
};
|
||
|
|
||
|
LINK_ENTITY_TO_CLASS( filter_tf_damaged_by_weapon_in_slot, FilterDamagedByWeaponInSlot );
|
||
|
|
||
|
BEGIN_DATADESC( FilterDamagedByWeaponInSlot )
|
||
|
|
||
|
// Keyfields
|
||
|
DEFINE_KEYFIELD( m_iWeaponSlot, FIELD_INTEGER, "weaponSlot" ),
|
||
|
|
||
|
END_DATADESC()
|
||
|
|
||
|
#ifdef STAGING_ONLY
|
||
|
|
||
|
class CFilterTFWearingItem : public CBaseFilter
|
||
|
{
|
||
|
DECLARE_CLASS( CFilterTFWearingItem, CBaseFilter );
|
||
|
|
||
|
public:
|
||
|
|
||
|
inline bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity )
|
||
|
{
|
||
|
CTFPlayer *pPlayer = ToTFPlayer( pEntity );
|
||
|
|
||
|
if ( !pPlayer )
|
||
|
return false;
|
||
|
|
||
|
// Are they wearing the item we're looking for?
|
||
|
for ( int i=0; i<pPlayer->GetNumWearables(); ++i )
|
||
|
{
|
||
|
CEconWearable *pWearable = pPlayer->GetWearable( i );
|
||
|
if ( pWearable && pWearable->GetAttributeContainer() )
|
||
|
{
|
||
|
CEconItemView *pItem = pWearable->GetAttributeContainer()->GetItem();
|
||
|
if ( pItem && pItem->IsValid() )
|
||
|
{
|
||
|
if ( pItem->GetItemDefIndex() == m_nItemIndex )
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
DECLARE_DATADESC();
|
||
|
|
||
|
int m_nItemIndex;
|
||
|
};
|
||
|
|
||
|
BEGIN_DATADESC( CFilterTFWearingItem )
|
||
|
|
||
|
DEFINE_KEYFIELD( m_nItemIndex, FIELD_INTEGER, "econ_item_index" ),
|
||
|
|
||
|
END_DATADESC()
|
||
|
|
||
|
LINK_ENTITY_TO_CLASS( filter_tf_player_wearing_item, CFilterTFWearingItem );
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
// Only include bots with specific tags
|
||
|
class CFilterTFBotHasTag : public CBaseFilter
|
||
|
{
|
||
|
DECLARE_CLASS( CFilterTFBotHasTag, CBaseFilter );
|
||
|
DECLARE_DATADESC();
|
||
|
public:
|
||
|
|
||
|
inline virtual void Spawn()
|
||
|
{
|
||
|
BaseClass::Spawn();
|
||
|
|
||
|
const char* tags = STRING( m_iszTags );
|
||
|
CSplitString splitTags( tags, " " );
|
||
|
for ( int i=0; i<splitTags.Count(); ++i )
|
||
|
{
|
||
|
m_tags.CopyAndAddToTail( splitTags[i] );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
inline bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity )
|
||
|
{
|
||
|
CTFBot *pBot = ToTFBot( pEntity );
|
||
|
|
||
|
if ( !pBot )
|
||
|
return false;
|
||
|
|
||
|
bool bPasses = false;
|
||
|
for ( int i=0; i<m_tags.Count(); ++i )
|
||
|
{
|
||
|
const char* pszTag = m_tags[i];
|
||
|
if ( pBot->HasTag( pszTag ) )
|
||
|
{
|
||
|
bPasses = true;
|
||
|
if ( !m_bRequireAllTags )
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
else if ( m_bRequireAllTags )
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return bPasses;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
CUtlStringList m_tags;
|
||
|
string_t m_iszTags;
|
||
|
bool m_bRequireAllTags;
|
||
|
};
|
||
|
|
||
|
BEGIN_DATADESC( CFilterTFBotHasTag )
|
||
|
|
||
|
DEFINE_KEYFIELD( m_iszTags, FIELD_STRING, "tags" ),
|
||
|
DEFINE_KEYFIELD( m_bRequireAllTags, FIELD_BOOLEAN, "require_all_tags" ),
|
||
|
|
||
|
END_DATADESC()
|
||
|
|
||
|
LINK_ENTITY_TO_CLASS( filter_tf_bot_has_tag, CFilterTFBotHasTag );
|
||
|
|
||
|
|
||
|
//=============================================================================
|
||
|
//
|
||
|
// Team Fortress Condition Filter
|
||
|
//
|
||
|
class CFilterTFCondition : public CBaseFilter
|
||
|
{
|
||
|
DECLARE_CLASS( CFilterTFCondition, CBaseFilter );
|
||
|
|
||
|
public:
|
||
|
|
||
|
bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity )
|
||
|
{
|
||
|
if ( !pEntity->IsPlayer() )
|
||
|
return false;
|
||
|
|
||
|
CTFPlayer *pTFPlayer = ToTFPlayer( pEntity );
|
||
|
return pTFPlayer && pTFPlayer->m_Shared.InCond( (ETFCond)m_nCondition );
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
int m_nCondition;
|
||
|
|
||
|
DECLARE_DATADESC();
|
||
|
};
|
||
|
|
||
|
BEGIN_DATADESC( CFilterTFCondition )
|
||
|
DEFINE_KEYFIELD( m_nCondition, FIELD_INTEGER, "condition" ),
|
||
|
END_DATADESC()
|
||
|
|
||
|
|
||
|
LINK_ENTITY_TO_CLASS( filter_tf_condition, CFilterTFCondition );
|
||
|
|
||
|
//=============================================================================
|
||
|
//
|
||
|
// Team Fortress Class Filter
|
||
|
//
|
||
|
class CFilterTFClass : public CBaseFilter
|
||
|
{
|
||
|
DECLARE_CLASS( CFilterTFClass, CBaseFilter );
|
||
|
|
||
|
public:
|
||
|
|
||
|
bool PassesFilterImpl( CBaseEntity *pCaller, CBaseEntity *pEntity )
|
||
|
{
|
||
|
if ( !pEntity->IsPlayer() )
|
||
|
return false;
|
||
|
|
||
|
CTFPlayer *pTFPlayer = ToTFPlayer( pEntity );
|
||
|
return pTFPlayer
|
||
|
&& !pTFPlayer->IsObserver()
|
||
|
&& pTFPlayer->IsPlayerClass(m_nClass);
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
int m_nClass;
|
||
|
|
||
|
DECLARE_DATADESC();
|
||
|
};
|
||
|
|
||
|
BEGIN_DATADESC( CFilterTFClass )
|
||
|
DEFINE_KEYFIELD( m_nClass, FIELD_INTEGER, "tfclass" ),
|
||
|
END_DATADESC()
|
||
|
|
||
|
LINK_ENTITY_TO_CLASS( filter_tf_class, CFilterTFClass );
|