Start of the entity goal system. Powerful and awesome stuff!

This commit is contained in:
hlstriker 2013-12-02 05:53:27 +00:00 committed by squeek
parent b2240d15dc
commit 93dba7191b
24 changed files with 1445 additions and 26 deletions

View file

@ -26,6 +26,7 @@
#include "ragdoll_shared.h" #include "ragdoll_shared.h"
#include "tier0/threadtools.h" #include "tier0/threadtools.h"
#include "datacache/idatacache.h" #include "datacache/idatacache.h"
#include "ff_sh_base_ff_goal.h" // FF: --> hlstriker: Added
#define LIPSYNC_POSEPARAM_NAME "mouth" #define LIPSYNC_POSEPARAM_NAME "mouth"
#define NUM_HITBOX_FIRES 10 #define NUM_HITBOX_FIRES 10
@ -88,10 +89,12 @@ typedef unsigned int ClientSideAnimationListHandle_t;
#define INVALID_CLIENTSIDEANIMATION_LIST_HANDLE (ClientSideAnimationListHandle_t)~0 #define INVALID_CLIENTSIDEANIMATION_LIST_HANDLE (ClientSideAnimationListHandle_t)~0
class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback class C_BaseAnimating : public CFF_SH_BaseFFGoal, private IModelLoadCallback // FF: --> hlstriker: Changed to derive from CFF_SH_BaseFFGoal. It was C_BaseEntity.
//class C_BaseAnimating : public C_BaseEntity, private IModelLoadCallback
{ {
public: public:
DECLARE_CLASS( C_BaseAnimating, C_BaseEntity ); DECLARE_CLASS( C_BaseAnimating, CFF_SH_BaseFFGoal ); // FF: --> hlstriker: Changed to derive from CFF_SH_BaseFFGoal. It was C_BaseEntity.
//DECLARE_CLASS( C_BaseAnimating, C_BaseEntity );
DECLARE_CLIENTCLASS(); DECLARE_CLIENTCLASS();
DECLARE_PREDICTABLE(); DECLARE_PREDICTABLE();
DECLARE_INTERPOLATION(); DECLARE_INTERPOLATION();

View file

@ -11,15 +11,18 @@
#endif #endif
#include "c_baseentity.h" #include "c_baseentity.h"
#include "ff_sh_base_ff_goal.h" // FF: --> hlstriker: Added
#if defined( CLIENT_DLL ) #if defined( CLIENT_DLL )
#define CBaseDoor C_BaseDoor #define CBaseDoor C_BaseDoor
#endif #endif
class C_BaseDoor : public C_BaseEntity class C_BaseDoor : public CFF_SH_BaseFFGoal // FF: --> hlstriker: Changed to derive from CFF_SH_BaseFFGoal. It was C_BaseEntity.
//class C_BaseDoor : public C_BaseEntity
{ {
public: public:
DECLARE_CLASS( C_BaseDoor, C_BaseEntity ); DECLARE_CLASS( C_BaseDoor, CFF_SH_BaseFFGoal ); // FF: --> hlstriker: Changed to derive from CFF_SH_BaseFFGoal. It was C_BaseEntity.
//DECLARE_CLASS( C_BaseDoor, C_BaseEntity );
DECLARE_CLIENTCLASS(); DECLARE_CLIENTCLASS();
C_BaseDoor( void ); C_BaseDoor( void );

View file

@ -18,7 +18,7 @@ $Configuration
{ {
$Compiler $Compiler
{ {
$AdditionalIncludeDirectories "$BASE;.\ff;.\ff\entities;$SRCDIR\game\shared\ff;$THIRDPARTYDIR\lua;$THIRDPARTYDIR" $AdditionalIncludeDirectories "$BASE;.\ff;.\ff\entities;$SRCDIR\game\shared\ff;$SRCDIR\game\shared\ff\other;$SRCDIR\game\shared\ff\entities;$THIRDPARTYDIR\lua;$THIRDPARTYDIR"
$PreprocessorDefinitions "$BASE;FF;FF_CLIENT_DLL;SOURCE_2013;GLOWS_ENABLE" $PreprocessorDefinitions "$BASE;FF;FF_CLIENT_DLL;SOURCE_2013;GLOWS_ENABLE"
} }
} }

View file

@ -15,7 +15,7 @@
#include "studio.h" #include "studio.h"
#include "datacache/idatacache.h" #include "datacache/idatacache.h"
#include "tier0/threadtools.h" #include "tier0/threadtools.h"
#include "ff_sv_base_ff_goal.h" // FF: --> hlstriker: Added #include "ff_sh_base_ff_goal.h" // FF: --> hlstriker: Added
struct animevent_t; struct animevent_t;
@ -27,10 +27,13 @@ FORWARD_DECLARE_HANDLE( memhandle_t );
#define BCF_NO_ANIMATION_SKIP ( 1 << 0 ) // Do not allow PVS animation skipping (mostly for attachments being critical to an entity) #define BCF_NO_ANIMATION_SKIP ( 1 << 0 ) // Do not allow PVS animation skipping (mostly for attachments being critical to an entity)
#define BCF_IS_IN_SPAWN ( 1 << 1 ) // Is currently inside of spawn, always evaluate animations #define BCF_IS_IN_SPAWN ( 1 << 1 ) // Is currently inside of spawn, always evaluate animations
class CBaseAnimating : public CFF_SV_BaseFFGoal // FF: --> hlstriker: Changed to derive from CFF_SV_BaseFFGoal. It was CBaseEntity.
class CBaseAnimating : public CFF_SH_BaseFFGoal // FF: --> hlstriker: Changed to derive from CFF_SH_BaseFFGoal. It was CBaseEntity.
//class CBaseAnimating : public CBaseEntity
{ {
public: public:
DECLARE_CLASS( CBaseAnimating, CFF_SV_BaseFFGoal ); // FF: --> hlstriker: Changed to derive from CFF_SV_BaseFFGoal. It was CBaseEntity. DECLARE_CLASS( CBaseAnimating, CFF_SH_BaseFFGoal ); // FF: --> hlstriker: Changed to derive from CFF_SH_BaseFFGoal. It was CBaseEntity.
//DECLARE_CLASS( CBaseAnimating, CBaseEntity );
CBaseAnimating(); CBaseAnimating();
~CBaseAnimating(); ~CBaseAnimating();

View file

@ -10,12 +10,14 @@
#pragma once #pragma once
#include "baseentity.h" #include "baseentity.h"
#include "ff_sv_base_ff_goal.h" // FF: --> hlstriker: Added #include "ff_sh_base_ff_goal.h" // FF: --> hlstriker: Added
class CBaseToggle : public CFF_SV_BaseFFGoal // FF: --> hlstriker: Changed to derive from CFF_SV_BaseFFGoal. It was CBaseEntity. class CBaseToggle : public CFF_SH_BaseFFGoal // FF: --> hlstriker: Changed to derive from CFF_SH_BaseFFGoal. It was CBaseEntity.
//class CBaseToggle : public CBaseEntity
{ {
DECLARE_CLASS( CBaseToggle, CFF_SV_BaseFFGoal ); // FF: --> hlstriker: Changed to derive from CFF_SV_BaseFFGoal. It was CBaseEntity. DECLARE_CLASS( CBaseToggle, CFF_SH_BaseFFGoal ); // FF: --> hlstriker: Changed to derive from CFF_SH_BaseFFGoal. It was CBaseEntity.
//DECLARE_CLASS( CBaseToggle, CBaseEntity );
public: public:
CBaseToggle(); CBaseToggle();

View file

@ -1,5 +1,4 @@
#include "cbase.h" #include "cbase.h"
#include "ff_sv_teamcheck_target.h"
#include "ff_sh_shareddefs.h" #include "ff_sh_shareddefs.h"
#include "ammodef.h" #include "ammodef.h"
@ -77,7 +76,7 @@ void CFF_SV_InfoFFWeaponSpawner::Precache( void )
int CFF_SV_InfoFFWeaponSpawner::UpdateTransmitState() int CFF_SV_InfoFFWeaponSpawner::UpdateTransmitState()
{ {
// We have to call this since EF_NODRAW will set it to FL_EDICT_DONTSEND. // We have to call this since EF_NODRAW will set it to FL_EDICT_DONTSEND.
return FL_EDICT_PVSCHECK; return SetTransmitState( FL_EDICT_PVSCHECK );
} }
void CFF_SV_InfoFFWeaponSpawner::Spawn() void CFF_SV_InfoFFWeaponSpawner::Spawn()

View file

@ -1,4 +1,41 @@
#include "cbase.h" #include "cbase.h"
#include "ff_sv_goal_manager.h"
#include "ff_sv_item_ff_goal.h"
LINK_ENTITY_TO_CLASS( item_ff_goal, CFF_SV_ItemFFGoal );
BEGIN_DATADESC( CFF_SV_ItemFFGoal )
END_DATADESC()
CFF_SV_ItemFFGoal::CFF_SV_ItemFFGoal()
{
BaseClass::InitGoal( FF_GOALTYPE_ITEM );
}
void CFF_SV_ItemFFGoal::Spawn()
{
// TODO: Check if needs to drop to floor.
if( false )
UTIL_DropToFloor( this, MASK_SOLID );
m_vecSpawnOrigin = GetAbsOrigin();
}
CBasePlayer* CFF_SV_ItemFFGoal::GetCarrier()
{
return m_hItemCarrier;
}
const Vector& CFF_SV_ItemFFGoal::GetSpawnOrigin()
{
return m_vecSpawnOrigin;
}
/*
#include "cbase.h"
#include "ff_sv_teamcheck_target.h" #include "ff_sv_teamcheck_target.h"
@ -212,3 +249,4 @@ void CFF_SV_ItemFFGoal::ThinkSetInactive()
{ {
SetInactive(); SetInactive();
} }
*/

View file

@ -874,9 +874,12 @@ void CFF_SV_Player::ChangeTeam( int iTeam )
if ( iTeam == FF_TEAM_SPECTATE ) if ( iTeam == FF_TEAM_SPECTATE )
{ {
RemoveAllItems( true ); RemoveAllItems( true );
State_Transition( STATE_OBSERVER_MODE ); State_Transition( STATE_OBSERVER_MODE );
} }
else
{
State_Transition( STATE_ACTIVE );
}
if ( bKill == true ) if ( bKill == true )
{ {

View file

@ -17,7 +17,7 @@ $Configuration
{ {
$Compiler $Compiler
{ {
$AdditionalIncludeDirectories "$BASE;.\ff;.\ff\other;.\ff\entities;$SRCDIR\game\shared\ff;$SRCDIR\game\shared\ff\other;$THIRDPARTYDIR\lua;$THIRDPARTYDIR" $AdditionalIncludeDirectories "$BASE;.\ff;.\ff\other;.\ff\entities;$SRCDIR\game\shared\ff;$SRCDIR\game\shared\ff\other;$SRCDIR\game\shared\ff\entities;$THIRDPARTYDIR\lua;$THIRDPARTYDIR"
$PreprocessorDefinitions "$BASE;FF;FF_DLL;GLOWS_ENABLE" $PreprocessorDefinitions "$BASE;FF;FF_DLL;GLOWS_ENABLE"
} }
} }
@ -42,18 +42,11 @@ $Project "Server (FF)"
} }
$Folder "Entities" $Folder "Entities"
{ {
$File "ff\entities\ff_sv_base_ff_goal.cpp"
$File "ff\entities\ff_sv_base_ff_goal.h"
$File "ff\entities\ff_sv_env_ff_message.cpp" $File "ff\entities\ff_sv_env_ff_message.cpp"
$File "ff\entities\ff_sv_env_ff_message.h" $File "ff\entities\ff_sv_env_ff_message.h"
$File "ff\entities\ff_sv_info_ff_team_manager.cpp" $File "ff\entities\ff_sv_info_ff_team_manager.cpp"
$File "ff\entities\ff_sv_info_ff_team_manager.h" $File "ff\entities\ff_sv_info_ff_team_manager.h"
$File "ff\entities\ff_sv_info_ff_teamcheck.cpp"
$File "ff\entities\ff_sv_info_ff_teamcheck.h"
$File "ff\entities\ff_sv_info_ff_weapon_spawner.cpp" $File "ff\entities\ff_sv_info_ff_weapon_spawner.cpp"
$File "ff\entities\ff_sv_item_ff_goal.cpp"
$File "ff\entities\ff_sv_teamcheck_target.cpp"
$File "ff\entities\ff_sv_teamcheck_target.h"
} }
$Folder "Other" $Folder "Other"
{ {

View file

@ -0,0 +1,735 @@
#include "cbase.h"
#include "ff_sh_base_ff_goal.h"
#include "ff_sh_item_ff_goal.h"
#include "ff_sh_shareddefs.h"
#ifdef GAME_DLL
#include "ff_sv_util.h"
#include "dt_utlvector_send.h"
#else
#include "dt_utlvector_recv.h"
#endif
#ifdef GAME_DLL
BEGIN_DATADESC( CFF_SH_BaseFFGoal )
// Think functions.
DEFINE_THINKFUNC( ActivateGoal ),
DEFINE_THINKFUNC( DeactivateGoal ),
// Goal inputs.
DEFINE_INPUTFUNC( FIELD_VOID, "Enable", Input_Enable ),
DEFINE_INPUTFUNC( FIELD_VOID, "Disable", Input_Disable ),
DEFINE_INPUTFUNC( FIELD_VOID, "Activate", Input_Activate ),
DEFINE_INPUTFUNC( FIELD_VOID, "Inactivate", Input_Inactivate ),
// Goal outputs.
DEFINE_OUTPUT( m_Output_OnEnabled, "OnEnabled" ),
DEFINE_OUTPUT( m_Output_OnDisabled, "OnDisabled" ),
DEFINE_OUTPUT( m_Output_OnActive, "OnActive" ),
DEFINE_OUTPUT( m_Output_OnInactive, "OnInactive" ),
// Goal keys.
DEFINE_KEYFIELD_NOT_SAVED( m_fActiveDelay, FIELD_FLOAT, "active_delay" ),
DEFINE_KEYFIELD_NOT_SAVED( m_fActiveTime, FIELD_FLOAT, "active_time" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszActivationSound, FIELD_SOUNDNAME, "activation_sound" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszResetSound, FIELD_SOUNDNAME, "reset_sound" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszFailedCriteriaMessage, FIELD_STRING, "msg_if_activator_fails_criteria" ),
// Criteria check keys.
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_TeamsAllowed, FIELD_STRING, "teams_allowed" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_ClassesAllowed, FIELD_STRING, "classes_allowed" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_ItemsCarriedByActivator, FIELD_STRING, "if_items_carried_by_ap" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_ItemsNotCarriedByActivator, FIELD_STRING, "if_items_not_carried_by_ap" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_ItemsCarriedByTeam, FIELD_STRING, "if_items_carried_by_team" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_ItemsNotCarriedByTeam, FIELD_STRING, "if_items_not_carried_by_team" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_ItemsCarriedByAny, FIELD_STRING, "if_items_carried_by_any" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_ItemsNotCarriedByAny, FIELD_STRING, "if_items_not_carried_by_any" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_ItemsCarriedByOne, FIELD_STRING, "if_items_carried_by_one" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_ItemsNotCarriedByOne, FIELD_STRING, "if_items_not_carried_by_one" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_ItemsAtSpawnPoint, FIELD_STRING, "if_items_at_spawn_point" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_ItemsNotAtSpawnPoint, FIELD_STRING, "if_items_not_at_spawn_point" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_GoalsAreActive, FIELD_STRING, "if_goals_are_active" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_GoalsAreInactive, FIELD_STRING, "if_goals_are_inactive" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_GoalsAreEnabled, FIELD_STRING, "if_goals_are_enabled" ),
DEFINE_KEYFIELD_NOT_SAVED( m_iszCriteria_GoalsAreDisabled, FIELD_STRING, "if_goals_are_disabled" ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST( CFF_SH_BaseFFGoal, DT_FF_BaseFFGoal )
SendPropBool( SENDINFO( m_bGoalEnabled ) ),
SendPropBool( SENDINFO( m_bGoalActivated ) ),
SendPropEHandle( SENDINFO( m_hGoalActivator ) ),
SendPropInt( SENDINFO( m_iCriteria_TeamsAllowed ) ),
SendPropInt( SENDINFO( m_iCriteria_ClassesAllowed ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_ItemsCarriedByActivator ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_ItemsNotCarriedByActivator ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_ItemsCarriedByTeam ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_ItemsNotCarriedByTeam ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_ItemsCarriedByAny ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_ItemsNotCarriedByAny ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_ItemsCarriedByOne ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_ItemsNotCarriedByOne ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_ItemsAtSpawnPoint ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_ItemsNotAtSpawnPoint ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_GoalsAreActive ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_GoalsAreInactive ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_GoalsAreEnabled ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
SendPropUtlVector( SENDINFO_UTLVECTOR( m_Criteria_GoalsAreDisabled ), MAX_GOALS_PER_CRITERIA, SendPropEHandle( NULL, 0 ) ),
END_SEND_TABLE()
#else
IMPLEMENT_CLIENTCLASS_DT( CFF_SH_BaseFFGoal, DT_FF_BaseFFGoal, CFF_SH_BaseFFGoal )
RecvPropBool( RECVINFO( m_bGoalEnabled ) ),
RecvPropBool( RECVINFO( m_bGoalActivated ) ),
RecvPropEHandle( RECVINFO( m_hGoalActivator ) ),
RecvPropInt( RECVINFO( m_iCriteria_TeamsAllowed ) ),
RecvPropInt( RECVINFO( m_iCriteria_ClassesAllowed ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_ItemsCarriedByActivator ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_ItemsNotCarriedByActivator ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_ItemsCarriedByTeam ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_ItemsNotCarriedByTeam ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_ItemsCarriedByAny ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_ItemsNotCarriedByAny ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_ItemsCarriedByOne ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_ItemsNotCarriedByOne ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_ItemsAtSpawnPoint ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_ItemsNotAtSpawnPoint ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_GoalsAreActive ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_GoalsAreInactive ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_GoalsAreEnabled ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
RecvPropUtlVector( RECVINFO_UTLVECTOR( m_Criteria_GoalsAreDisabled ), MAX_GOALS_PER_CRITERIA, RecvPropEHandle( NULL, 0, 0 ) ),
END_RECV_TABLE()
#endif
bool CFF_SH_BaseFFGoal::IsGoalEnabled()
{
return m_bGoalEnabled;
}
bool CFF_SH_BaseFFGoal::IsGoalActivated()
{
return m_bGoalActivated;
}
bool CFF_SH_BaseFFGoal::HandleCriteriaCheckResult( const CBaseEntity *pEnt, bool bIsActivator, bool bReturnValue )
{
#ifdef GAME_DLL
if( bIsActivator && !bReturnValue && m_iszFailedCriteriaMessage != NULL_STRING )
{
// Display criteria failed message to the activator.
CBasePlayer *pPlayer = dynamic_cast<CBasePlayer *>( Instance(pEnt->edict()) );
if( pPlayer )
{
int iPlayerIndex = ENTINDEX(pPlayer);
if( m_fNextFailedCriteriaMessage[iPlayerIndex] <= gpGlobals->curtime )
{
FF_UTIL_HudMessage( pPlayer, -1.0f, 0.8f, HUD_EFFECT_FADE_IN_OUT, m_clrFailedCriteriaColor, m_clrFailedCriteriaColor, 0.2f, 0.3f, 1.3f, 0.0f, 1, STRING(m_iszFailedCriteriaMessage) );
m_fNextFailedCriteriaMessage[iPlayerIndex] = gpGlobals->curtime + 1.8f;
}
}
}
#endif
return bReturnValue;
}
bool CFF_SH_BaseFFGoal::PassesCriteriaCheck( const CBaseEntity *pEnt, bool bIsActivator )
{
// Check to see if this player needs to be on a certain team to pass.
if( TeamCheck_IsUsed() )
{
if( !TeamCheck_IsTeamAllowed( pEnt->GetTeamNumber() ) )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
else
{
if( m_iCriteria_TeamsAllowed && !( m_iCriteria_TeamsAllowed & FF_TEAM_BITS[pEnt->GetTeamNumber()] ) )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
// --> START: Player specific checks.
const CBasePlayer *pPlayer = dynamic_cast<const CBasePlayer *>(pEnt);
if( pPlayer )
{
// TODO: Add this back when classes are added.
/*
// Check to see if this player needs to be a certain class to pass.
if( TeamCheck_IsUsed() )
{
if( !TeamCheck_IsClassAllowed( pActivator->GetClass() ) )
return PassesCriteriaCheckOutput( pEnt, bIsActivator, false);
}
else
{
if( m_iCriteria_ClassesAllowed && !( m_iCriteria_ClassesAllowed & FF_CLASS_BITS[pActivator->GetClass()] ) )
return PassesCriteriaCheckOutput( pEnt, bIsActivator, false);
}
*/
// Check to see if this player needs to be carrying specific items.
for( int i=0; i<m_Criteria_ItemsCarriedByActivator.Count(); i++ )
{
if( pPlayer != m_Criteria_ItemsCarriedByActivator[i]->GetCarrier() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
// Check to see if this player needs to NOT be carrying specific items.
for( int i=0; i<m_Criteria_ItemsNotCarriedByActivator.Count(); i++ )
{
if( pPlayer == m_Criteria_ItemsNotCarriedByActivator[i]->GetCarrier() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
// Check to see if this players team needs to be carrying specific items.
CBasePlayer *pCarrier;
for( int i=0; i<m_Criteria_ItemsCarriedByTeam.Count(); i++ )
{
pCarrier = m_Criteria_ItemsCarriedByTeam[i]->GetCarrier();
if( !pCarrier || pPlayer->GetTeamNumber() != pCarrier->GetTeamNumber() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
// Check to see if this players team needs to NOT be carrying specific items.
for( int i=0; i<m_Criteria_ItemsNotCarriedByTeam.Count(); i++ )
{
pCarrier = m_Criteria_ItemsNotCarriedByTeam[i]->GetCarrier();
if( pCarrier && pPlayer->GetTeamNumber() == pCarrier->GetTeamNumber() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
// Check to make sure certain items are being carried by someone.
for( int i=0; i<m_Criteria_ItemsCarriedByAny.Count(); i++ )
{
if( !m_Criteria_ItemsCarriedByAny[i]->GetCarrier() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
// Check to make sure certain items are NOT being carried by anyone.
for( int i=0; i<m_Criteria_ItemsNotCarriedByAny.Count(); i++ )
{
if( m_Criteria_ItemsNotCarriedByAny[i]->GetCarrier() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
// Check to make sure certain items are being carried by one single player.
if( m_Criteria_ItemsCarriedByOne.Count() > 0 )
{
pCarrier = m_Criteria_ItemsCarriedByOne[0]->GetCarrier();
for( int i=0; i<m_Criteria_ItemsCarriedByOne.Count(); i++ )
{
if( !pCarrier || pCarrier != m_Criteria_ItemsCarriedByOne[i]->GetCarrier() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
}
// Check to make sure certain items are NOT being carried by one single player.
if( m_Criteria_ItemsNotCarriedByOne.Count() > 0 )
{
int iMatches = 0;
pCarrier = m_Criteria_ItemsNotCarriedByOne[0]->GetCarrier();
for( int i=0; i<m_Criteria_ItemsNotCarriedByOne.Count(); i++ )
{
if( pCarrier && pCarrier == m_Criteria_ItemsNotCarriedByOne[i]->GetCarrier() )
iMatches++;
}
if( iMatches == m_Criteria_ItemsNotCarriedByOne.Count() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
// Check to make sure certain items are at their spawn point.
for( int i=0; i<m_Criteria_ItemsAtSpawnPoint.Count(); i++ )
{
if( m_Criteria_ItemsAtSpawnPoint[i]->GetAbsOrigin() != m_Criteria_ItemsAtSpawnPoint[i]->GetSpawnOrigin() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
// Check to make sure certain items are NOT at their spawn point.
for( int i=0; i<m_Criteria_ItemsNotAtSpawnPoint.Count(); i++ )
{
if( m_Criteria_ItemsNotAtSpawnPoint[i]->GetAbsOrigin() == m_Criteria_ItemsNotAtSpawnPoint[i]->GetSpawnOrigin() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
}
// <-- END: Player specific checks.
// Check to make sure certain goals are active.
for( int i=0; i<m_Criteria_GoalsAreActive.Count(); i++ )
{
if( !m_Criteria_GoalsAreActive[i]->IsGoalActivated() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
// Check to make sure certain goals are NOT active.
for( int i=0; i<m_Criteria_GoalsAreInactive.Count(); i++ )
{
if( m_Criteria_GoalsAreInactive[i]->IsGoalActivated() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
// Check to make sure certain goals are enabled.
for( int i=0; i<m_Criteria_GoalsAreEnabled.Count(); i++ )
{
if( !m_Criteria_GoalsAreEnabled[i]->IsGoalEnabled() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
// Check to make sure certain goals are NOT enabled.
for( int i=0; i<m_Criteria_GoalsAreDisabled.Count(); i++ )
{
if( m_Criteria_GoalsAreDisabled[i]->IsGoalEnabled() )
return HandleCriteriaCheckResult( pEnt, bIsActivator, false);
}
// The activator passed all criteria checks!
return HandleCriteriaCheckResult( pEnt, bIsActivator, true);
}
#ifdef GAME_DLL
void CFF_SH_BaseFFGoal::OnTouching( CBaseEntity *pOther )
{
// TODO: Fix the bug that allows any entity to touch each other.
// -->
if( m_spawnflags & GSF_ACTIVATED_BY_PLAYER_TOUCH )
{
if( dynamic_cast<CBasePlayer *>(pOther) )
TryActivateGoal( pOther );
}
}
void CFF_SH_BaseFFGoal::TryActivateGoal( CBaseEntity *pActivator )
{
if( !m_bGoalEnabled || m_bGoalActive )
return;
if( PassesCriteriaCheck( pActivator ) )
ActivateGoalStart( pActivator );
}
void CFF_SH_BaseFFGoal::ActivateGoalStart( CBaseEntity *pActivator )
{
m_hGoalActivator = pActivator;
m_bGoalActive = true;
if( m_fActiveDelay > 0.0f )
{
SetThink( &CFF_SH_BaseFFGoal::ActivateGoal );
SetNextThink( gpGlobals->curtime + m_fActiveDelay );
}
else
{
ActivateGoal();
}
}
void CFF_SH_BaseFFGoal::ActivateGoal()
{
m_bGoalActivated = true;
m_Output_OnActive.FireOutput( m_hGoalActivator, this ); // TODO: Do we need to check if m_hGoalActivator still exists? If not send the world ent?
if( m_iszActivationSound != NULL_STRING )
{
CRecipientFilter filter;
filter.AddRecipientsByPVS( GetAbsOrigin() );
filter.MakeReliable();
EmitSound_t params;
params.m_pSoundName = STRING(m_iszActivationSound);
params.m_SoundLevel = SNDLVL_NORM;
if( filter.GetRecipientCount() )
EmitSound( filter, ENTINDEX(this), params );
}
// Start the deactivate timer.
if( m_fActiveTime )
{
SetThink( &CFF_SH_BaseFFGoal::DeactivateGoal );
SetNextThink( gpGlobals->curtime + m_fActiveTime );
}
else
{
DeactivateGoal();
}
}
void CFF_SH_BaseFFGoal::DeactivateGoal()
{
m_bGoalActivated = false;
m_Output_OnInactive.FireOutput( m_hGoalActivator, this ); // TODO: Do we need to check if m_hGoalActivator still exists? If not send the world ent?
if( m_iszResetSound != NULL_STRING )
{
CRecipientFilter filter;
filter.AddRecipientsByPVS( GetAbsOrigin() );
filter.MakeReliable();
EmitSound_t params;
params.m_pSoundName = STRING(m_iszResetSound);
params.m_SoundLevel = SNDLVL_NORM;
if( filter.GetRecipientCount() )
EmitSound( filter, ENTINDEX(this), params );
}
if( m_bGoalEnabled && m_bGoalActive && ( m_spawnflags & GSF_LOOP_ACTIVATION_UNTIL_DISABLED ) )
{
ActivateGoalStart( m_hGoalActivator );
}
else
{
m_bGoalActive = false;
SetThink( NULL );
}
}
void CFF_SH_BaseFFGoal::Precache()
{
const char *szSound;
if( m_iszActivationSound != NULL_STRING )
{
szSound = STRING(m_iszActivationSound);
if(*szSound != '!')
PrecacheScriptSound(szSound);
}
if( m_iszResetSound != NULL_STRING )
{
szSound = STRING(m_iszResetSound);
if(*szSound != '!')
PrecacheScriptSound(szSound);
}
BaseClass::Precache();
}
void CFF_SH_BaseFFGoal::Spawn()
{
Precache();
ParseCriteriaKeyValues();
BaseClass::Activate();
}
void CFF_SH_BaseFFGoal::Activate()
{
ParseCriteriaKeyValues();
BaseClass::Activate();
if( m_spawnflags & GSF_START_ACTIVE )
{
CBaseEntity *pWorld = Instance(0);
ActivateGoalStart( pWorld );
}
}
void CFF_SH_BaseFFGoal::ParseCriteriaKeyValues()
{
// Put spawnflags that can change in their own variable.
m_bGoalEnabled = ( m_spawnflags & GSF_START_ENABLED ) ? true : false;
// Parse teams allowed.
CUtlVector<char *> string_vector;
Q_SplitString( STRING(m_iszCriteria_TeamsAllowed), ",", string_vector );
int iTemp;
for( int i=0; i<string_vector.Count(); i++ )
{
iTemp = Q_atoi(string_vector[i]);
if( iTemp == -1 )
{
m_iCriteria_TeamsAllowed = -1;
break;
}
iTemp++; // Increase the team by 1 since FF_TEAM_ONE starts at value 2.
if( iTemp < FF_TEAM_ONE || iTemp > FF_TEAM_LAST )
continue;
m_iCriteria_TeamsAllowed |= FF_TEAM_BITS[iTemp];
}
// Parse classes allowed.
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_ClassesAllowed), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
iTemp = Q_atoi(string_vector[i]);
if( iTemp == -1 )
{
m_iCriteria_ClassesAllowed = -1;
break;
}
if( iTemp <= FF_CLASS_UNASSIGNED || iTemp >= FF_CLASS_COUNT )
continue;
m_iCriteria_ClassesAllowed |= FF_CLASS_BITS[iTemp];
}
// Parse item/goal based criterias.
CBaseEntity *pEnt;
CFF_SH_BaseFFGoal *pGoal;
CFF_SH_ItemFFGoal *pItem;
// ItemsCarriedByActivator
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_ItemsCarriedByActivator), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pItem = dynamic_cast<CFF_SH_ItemFFGoal *>(pEnt);
if( pItem )
m_Criteria_ItemsCarriedByActivator.AddToTail( pItem );
}
}
// ItemsNotCarriedByActivator
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_ItemsNotCarriedByActivator), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pItem = dynamic_cast<CFF_SH_ItemFFGoal *>(pEnt);
if( pItem )
m_Criteria_ItemsNotCarriedByActivator.AddToTail( pItem );
}
}
// ItemsCarriedByTeam
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_ItemsCarriedByTeam), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pItem = dynamic_cast<CFF_SH_ItemFFGoal *>(pEnt);
if( pItem )
m_Criteria_ItemsCarriedByTeam.AddToTail( pItem );
}
}
// ItemsNotCarriedByTeam
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_ItemsNotCarriedByTeam), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pItem = dynamic_cast<CFF_SH_ItemFFGoal *>(pEnt);
if( pItem )
m_Criteria_ItemsNotCarriedByTeam.AddToTail( pItem );
}
}
// ItemsCarriedByAny
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_ItemsCarriedByAny), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pItem = dynamic_cast<CFF_SH_ItemFFGoal *>(pEnt);
if( pItem )
m_Criteria_ItemsCarriedByAny.AddToTail( pItem );
}
}
// ItemsNotCarriedByAny
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_ItemsNotCarriedByAny), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pItem = dynamic_cast<CFF_SH_ItemFFGoal *>(pEnt);
if( pItem )
m_Criteria_ItemsNotCarriedByAny.AddToTail( pItem );
}
}
// ItemsCarriedByOne
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_ItemsCarriedByOne), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pItem = dynamic_cast<CFF_SH_ItemFFGoal *>(pEnt);
if( pItem )
m_Criteria_ItemsCarriedByOne.AddToTail( pItem );
}
}
// ItemsNotCarriedByOne
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_ItemsNotCarriedByOne), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pItem = dynamic_cast<CFF_SH_ItemFFGoal *>(pEnt);
if( pItem )
m_Criteria_ItemsNotCarriedByOne.AddToTail( pItem );
}
}
// ItemsAtSpawnPoint
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_ItemsAtSpawnPoint), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pItem = dynamic_cast<CFF_SH_ItemFFGoal *>(pEnt);
if( pItem )
m_Criteria_ItemsAtSpawnPoint.AddToTail( pItem );
}
}
// ItemsNotAtSpawnPoint
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_ItemsNotAtSpawnPoint), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pItem = dynamic_cast<CFF_SH_ItemFFGoal *>(pEnt);
if( pItem )
m_Criteria_ItemsNotAtSpawnPoint.AddToTail( pItem );
}
}
// GoalsAreActive
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_GoalsAreActive), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pGoal = dynamic_cast<CFF_SH_BaseFFGoal *>(pEnt);
if( pGoal )
m_Criteria_GoalsAreActive.AddToTail( pGoal );
}
}
// GoalsAreInactive
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_GoalsAreInactive), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pGoal = dynamic_cast<CFF_SH_BaseFFGoal *>(pEnt);
if( pGoal )
m_Criteria_GoalsAreInactive.AddToTail( pGoal );
}
}
// GoalsAreEnabled
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_GoalsAreEnabled), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pGoal = dynamic_cast<CFF_SH_BaseFFGoal *>(pEnt);
if( pGoal )
m_Criteria_GoalsAreEnabled.AddToTail( pGoal );
}
}
// GoalsAreDisabled
string_vector.Purge();
Q_SplitString( STRING(m_iszCriteria_GoalsAreDisabled), ",", string_vector );
for( int i=0; i<string_vector.Count(); i++ )
{
pEnt = NULL;
while( (pEnt = gEntList.FindEntityByName( pEnt, string_vector[i] )) != NULL )
{
pGoal = dynamic_cast<CFF_SH_BaseFFGoal *>(pEnt);
if( pGoal )
m_Criteria_GoalsAreDisabled.AddToTail( pGoal );
}
}
}
void CFF_SH_BaseFFGoal::Input_Enable( inputdata_t &inputdata )
{
m_bGoalEnabled = true;
m_Output_OnEnabled.FireOutput( inputdata.pActivator, this );
}
void CFF_SH_BaseFFGoal::Input_Disable( inputdata_t &inputdata )
{
m_bGoalEnabled = false;
m_Output_OnDisabled.FireOutput( inputdata.pActivator, this );
}
void CFF_SH_BaseFFGoal::Input_Activate( inputdata_t &inputdata )
{
if( !m_bGoalEnabled || m_bGoalActive )
return;
CBaseEntity *pWorld = Instance(0);
ActivateGoalStart( pWorld );
}
void CFF_SH_BaseFFGoal::Input_Inactivate( inputdata_t &inputdata )
{
if( !m_bGoalEnabled || !m_bGoalActive )
return;
m_bGoalActive = false; // WARNING: We must set m_bGoalActive to false before calling DeactivateGoal() because it will start looping again if looping is set.
DeactivateGoal();
}
#endif

View file

@ -0,0 +1,142 @@
#pragma once
#ifndef FF_SH_BASE_FF_GOAL_H
#define FF_SH_BASE_FF_GOAL_H
#include "ff_sh_teamcheck_target.h"
#define MAX_GOALS_PER_CRITERIA 20
class CFF_SH_ItemFFGoal;
class CFF_SH_BaseFFGoal : public CFF_SH_TeamcheckTarget
{
public:
DECLARE_CLASS( CFF_SH_BaseFFGoal, CFF_SH_TeamcheckTarget );
#ifdef GAME_DLL
DECLARE_DATADESC();
DECLARE_SERVERCLASS();
#else
DECLARE_CLIENTCLASS();
#endif
CFF_SH_BaseFFGoal()
{
SetThink( NULL );
m_bGoalActivated = false;
#ifdef GAME_DLL
m_clrFailedCriteriaColor.r = 4;
m_clrFailedCriteriaColor.g = 235;
m_clrFailedCriteriaColor.b = 4;
m_clrFailedCriteriaColor.a = 255;
#endif
}
#ifdef GAME_DLL
virtual void Precache( void );
virtual void Spawn( void );
virtual void Activate( void );
void ParseCriteriaKeyValues( void );
virtual void OnTouching( CBaseEntity *pOther ); // NOTE: This function is called from its derived classes SetTouch() function (BaseClass::OnTouching()).
void TryActivateGoal( CBaseEntity *pActivator );
void ActivateGoalStart( CBaseEntity *pActivator );
void ActivateGoal( void );
void DeactivateGoal( void );
#endif
public:
enum GOAL_SPAWNFLAGS
{
GSF_START_ACTIVE = (1<<0),
GSF_START_ENABLED = (1<<1),
GSF_ACTIVATED_BY_PLAYER_TOUCH = (1<<2),
GSF_LOOP_ACTIVATION_UNTIL_DISABLED = (1<<3),
GSF_CHECK_PLAYER_CRITERIA_INDIVIDUALLY = (1<<4),
};
bool IsGoalEnabled( void );
bool IsGoalActivated( void );
protected:
bool PassesCriteriaCheck( const CBaseEntity *pEnt, bool bIsActivator=true );
private:
bool HandleCriteriaCheckResult( const CBaseEntity *pEnt, bool bIsActivator, bool bReturnValue );
// Goal varaibles.
CNetworkVar( bool, m_bGoalEnabled );
CNetworkVar( bool, m_bGoalActivated );
CNetworkHandle( CBaseEntity, m_hGoalActivator );
float m_fActiveDelay; // How long to wait before going in the active state.
float m_fActiveTime; // How long to stay in the active state.
// Criteria check variables.
CNetworkVar( int, m_iCriteria_TeamsAllowed );
CNetworkVar( int, m_iCriteria_ClassesAllowed );
CUtlVector<CHandle<CFF_SH_ItemFFGoal>> m_Criteria_ItemsCarriedByActivator;
CUtlVector<CHandle<CFF_SH_ItemFFGoal>> m_Criteria_ItemsNotCarriedByActivator;
CUtlVector<CHandle<CFF_SH_ItemFFGoal>> m_Criteria_ItemsCarriedByTeam;
CUtlVector<CHandle<CFF_SH_ItemFFGoal>> m_Criteria_ItemsNotCarriedByTeam;
CUtlVector<CHandle<CFF_SH_ItemFFGoal>> m_Criteria_ItemsCarriedByAny;
CUtlVector<CHandle<CFF_SH_ItemFFGoal>> m_Criteria_ItemsNotCarriedByAny;
CUtlVector<CHandle<CFF_SH_ItemFFGoal>> m_Criteria_ItemsCarriedByOne;
CUtlVector<CHandle<CFF_SH_ItemFFGoal>> m_Criteria_ItemsNotCarriedByOne;
CUtlVector<CHandle<CFF_SH_ItemFFGoal>> m_Criteria_ItemsAtSpawnPoint;
CUtlVector<CHandle<CFF_SH_ItemFFGoal>> m_Criteria_ItemsNotAtSpawnPoint;
CUtlVector<CHandle<CFF_SH_BaseFFGoal>> m_Criteria_GoalsAreActive;
CUtlVector<CHandle<CFF_SH_BaseFFGoal>> m_Criteria_GoalsAreInactive;
CUtlVector<CHandle<CFF_SH_BaseFFGoal>> m_Criteria_GoalsAreEnabled;
CUtlVector<CHandle<CFF_SH_BaseFFGoal>> m_Criteria_GoalsAreDisabled;
#ifdef GAME_DLL
private:
void Input_Enable( inputdata_t &inputdata );
void Input_Disable( inputdata_t &inputdata );
void Input_Activate( inputdata_t &inputdata );
void Input_Inactivate( inputdata_t &inputdata );
COutputEvent m_Output_OnEnabled;
COutputEvent m_Output_OnDisabled;
COutputEvent m_Output_OnActive;
COutputEvent m_Output_OnInactive;
string_t m_iszActivationSound;
string_t m_iszResetSound;
bool m_bGoalActive;
color32 m_clrFailedCriteriaColor;
float m_fNextFailedCriteriaMessage[MAX_PLAYERS+1];
string_t m_iszFailedCriteriaMessage;
// NOTE: The strings below are only used for parsing the data from the map keyfields.
string_t m_iszCriteria_TeamsAllowed;
string_t m_iszCriteria_ClassesAllowed;
string_t m_iszCriteria_ItemsCarriedByActivator;
string_t m_iszCriteria_ItemsNotCarriedByActivator;
string_t m_iszCriteria_ItemsCarriedByTeam;
string_t m_iszCriteria_ItemsNotCarriedByTeam;
string_t m_iszCriteria_ItemsCarriedByAny;
string_t m_iszCriteria_ItemsNotCarriedByAny;
string_t m_iszCriteria_ItemsCarriedByOne;
string_t m_iszCriteria_ItemsNotCarriedByOne;
string_t m_iszCriteria_ItemsAtSpawnPoint;
string_t m_iszCriteria_ItemsNotAtSpawnPoint;
string_t m_iszCriteria_GoalsAreActive;
string_t m_iszCriteria_GoalsAreInactive;
string_t m_iszCriteria_GoalsAreEnabled;
string_t m_iszCriteria_GoalsAreDisabled;
#endif
};
#endif // FF_SH_BASE_FF_GOAL_H

View file

@ -0,0 +1,50 @@
#include "cbase.h"
#include "ff_sh_func_ff_clip.h"
LINK_ENTITY_TO_CLASS( func_ff_clip, CFF_SH_FuncFFClip );
#ifdef GAME_DLL
BEGIN_DATADESC( CFF_SH_FuncFFClip )
// Goal touch functions.
DEFINE_FUNCTION( OnTouching ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST( CFF_SH_FuncFFClip, DT_FF_FuncFFClip )
END_SEND_TABLE()
#else
IMPLEMENT_CLIENTCLASS_DT( CFF_SH_FuncFFClip, DT_FF_FuncFFClip, CFF_SH_FuncFFClip )
END_RECV_TABLE()
#endif
void CFF_SH_FuncFFClip::Spawn()
{
BaseClass::Spawn();
SetSolid( SOLID_BSP );
SetSolidFlags( FSOLID_TRIGGER ); // Note: Do not add FSOLID_NOT_SOLID. CTraceFilterSimple::ShouldHitEntity() handles collisions for this entity.
#ifdef GAME_DLL
SetTouch( &CFF_SH_FuncFFClip::OnTouching );
#endif
}
bool CFF_SH_FuncFFClip::ShouldClipActivator( const CBaseEntity *pActivator )
{
if( !IsGoalEnabled() )
return false;
if( PassesCriteriaCheck( pActivator ) )
return false;
return true;
}
#ifdef GAME_DLL
void CFF_SH_FuncFFClip::OnTouching( CBaseEntity *pOther )
{
BaseClass::OnTouching( pOther );
}
#endif

View file

@ -0,0 +1,40 @@
#pragma once
#ifndef FF_SH_FUNC_FF_CLIP_H
#define FF_SH_FUNC_FF_CLIP_H
#include "ff_sh_trigger_ff_goal.h"
class CFF_SH_FuncFFClip : public CFF_SH_TriggerFFGoal
{
public:
DECLARE_CLASS( CFF_SH_FuncFFClip, CFF_SH_TriggerFFGoal );
#ifdef GAME_DLL
DECLARE_DATADESC();
DECLARE_SERVERCLASS();
#else
DECLARE_CLIENTCLASS();
#endif
CFF_SH_FuncFFClip() {}
virtual void Spawn();
bool ShouldClipActivator( const CBaseEntity *pActivator );
#ifdef GAME_DLL
virtual void OnTouching( CBaseEntity *pOther );
int UpdateTransmitState( void )
{
// The goal must always be transmitted because client side relys on knowing about each goal.
// We don't set this in the base_goal because so many other entities are derived from it.
return SetTransmitState( FL_EDICT_ALWAYS );
}
#endif
};
#endif // FF_SH_FUNC_FF_CLIP_H

View file

@ -0,0 +1,54 @@
#include "cbase.h"
#include "ff_sh_util.h"
#include "ff_sh_info_ff_teamcheck.h"
LINK_ENTITY_TO_CLASS( info_ff_teamcheck, CFF_SH_InfoFFTeamCheck );
#ifdef GAME_DLL
BEGIN_DATADESC( CFF_SH_InfoFFTeamCheck )
// Keyfields.
DEFINE_KEYFIELD_NOT_SAVED( m_iTeamsAllowed, FIELD_INTEGER, "teams_allowed" ),
// Inputs.
DEFINE_INPUTFUNC( FIELD_INTEGER, "SetTeamsAllowed", Input_SetTeamsAllowed ),
DEFINE_INPUTFUNC( FIELD_VOID, "SwapTeams", Input_SwapTeams ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST_NOBASE( CFF_SH_InfoFFTeamCheck, DT_FF_InfoFFTeamCheck )
SendPropInt( SENDINFO(m_iTeamsAllowed) ),
END_SEND_TABLE()
#else
IMPLEMENT_CLIENTCLASS_DT_NOBASE( CFF_SH_InfoFFTeamCheck, DT_FF_InfoFFTeamCheck, CFF_SH_InfoFFTeamCheck )
RecvPropInt( RECVINFO(m_iTeamsAllowed) ),
END_RECV_TABLE()
#endif
bool CFF_SH_InfoFFTeamCheck::IsTeamAllowed( int iTeamNum )
{
if( !m_iTeamsAllowed )
return true;
if( m_iTeamsAllowed & FF_UTIL_GetTeamBit(iTeamNum) )
return true;
return false;
}
#ifdef GAME_DLL
int CFF_SH_InfoFFTeamCheck::UpdateTransmitState()
{
return SetTransmitState( FL_EDICT_ALWAYS );
}
void CFF_SH_InfoFFTeamCheck::Input_SetTeamsAllowed( inputdata_t &inputdata )
{
m_iTeamsAllowed.Set( inputdata.value.Int() );
}
void CFF_SH_InfoFFTeamCheck::Input_SwapTeams( inputdata_t &inputdata )
{
m_iTeamsAllowed.Set( ~m_iTeamsAllowed.Get() );
}
#endif

View file

@ -0,0 +1,36 @@
#pragma once
#ifndef FF_SH_INFO_FF_TEAMCHECK_H
#define FF_SH_INFO_FF_TEAMCHECK_H
class CFF_SH_InfoFFTeamCheck : public CBaseEntity
{
public:
DECLARE_CLASS( CFF_SH_InfoFFTeamCheck, CBaseEntity );
#ifdef GAME_DLL
DECLARE_DATADESC();
DECLARE_SERVERCLASS();
#else
DECLARE_CLIENTCLASS();
#endif
CFF_SH_InfoFFTeamCheck()
{
}
CNetworkVar( int, m_iTeamsAllowed );
bool IsTeamAllowed( int iTeamNum );
#ifdef GAME_DLL
int UpdateTransmitState( void );
private:
void Input_SetTeamsAllowed( inputdata_t &inputdata );
void Input_SwapTeams( inputdata_t &inputdata );
#endif
};
#endif // FF_SH_INFO_FF_TEAMCHECK_H

View file

@ -0,0 +1,37 @@
#include "cbase.h"
#include "ff_sh_item_ff_goal.h"
LINK_ENTITY_TO_CLASS( item_ff_goal, CFF_SH_ItemFFGoal );
#ifdef GAME_DLL
IMPLEMENT_SERVERCLASS_ST( CFF_SH_ItemFFGoal, DT_FF_ItemFFGoal )
END_SEND_TABLE()
#else
IMPLEMENT_CLIENTCLASS_DT( CFF_SH_ItemFFGoal, DT_FF_ItemFFGoal, CFF_SH_ItemFFGoal )
END_RECV_TABLE()
#endif
#ifdef GAME_DLL
void CFF_SH_ItemFFGoal::Spawn()
{
BaseClass::Spawn();
// TODO: Check if needs to drop to floor. Note: This should be done in the info_ versions spawn
if( false )
UTIL_DropToFloor( this, MASK_SOLID );
m_vecSpawnOrigin = GetAbsOrigin();
}
#endif
CBasePlayer* CFF_SH_ItemFFGoal::GetCarrier()
{
return m_hItemCarrier;
}
const Vector& CFF_SH_ItemFFGoal::GetSpawnOrigin()
{
return m_vecSpawnOrigin;
}

View file

@ -0,0 +1,47 @@
#pragma once
#ifndef FF_SH_ITEM_FF_GOAL_H
#define FF_SH_ITEM_FF_GOAL_H
#ifdef GAME_DLL
#include "baseanimating.h"
#else
#include "c_baseanimating.h"
#endif
class CFF_SH_ItemFFGoal : public CBaseAnimating // TODO: Derive from info_ version. Note: info_ should still derive from CBaseAnimating.
{
public:
DECLARE_CLASS( CFF_SH_ItemFFGoal, CBaseAnimating ); // TODO: Derive from info_ version. Note: info_ should still derive from CBaseAnimating.
#ifdef GAME_DLL
DECLARE_SERVERCLASS();
#else
DECLARE_CLIENTCLASS();
#endif
CFF_SH_ItemFFGoal() {}
CBasePlayer* GetCarrier( void );
const Vector& GetSpawnOrigin( void );
#ifdef GAME_DLL
void Spawn( void );
int UpdateTransmitState( void )
{
// The goal must always be transmitted because client side relys on knowing about each goal.
// We don't set this in the base_goal because so many other entities are derived from it.
return SetTransmitState( FL_EDICT_ALWAYS );
}
#endif
private:
CHandle<CBasePlayer> m_hItemCarrier; // TODO: network this.
Vector m_vecSpawnOrigin; // TODO: network this.
};
#endif // FF_SH_ITEM_FF_GOAL_H

View file

@ -0,0 +1,48 @@
#include "cbase.h"
#include "ff_sh_teamcheck_target.h"
#ifdef GAME_DLL
BEGIN_DATADESC( CFF_SH_TeamcheckTarget )
// Keyfields.
DEFINE_KEYFIELD_NOT_SAVED( m_iszTeamTarget, FIELD_STRING, "teamcheck_target" ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST( CFF_SH_TeamcheckTarget, DT_FF_TeamcheckTarget )
SendPropEHandle( SENDINFO( m_hTeamTarget ) ),
END_SEND_TABLE()
#else
IMPLEMENT_CLIENTCLASS_DT( CFF_SH_TeamcheckTarget, DT_FF_TeamcheckTarget, CFF_SH_TeamcheckTarget )
RecvPropEHandle( RECVINFO( m_hTeamTarget ) ),
END_RECV_TABLE()
#endif
#ifdef GAME_DLL
void CFF_SH_TeamcheckTarget::Activate()
{
BaseClass::Activate();
if( m_iszTeamTarget != NULL_STRING )
m_hTeamTarget = dynamic_cast<CFF_SH_InfoFFTeamCheck *>( gEntList.FindEntityByName( NULL, m_iszTeamTarget ) );
}
#endif
bool CFF_SH_TeamcheckTarget::TeamCheck_IsUsed()
{
if( !m_hTeamTarget )
return false;
return true;
}
bool CFF_SH_TeamcheckTarget::TeamCheck_IsTeamAllowed( int iTeamNum )
{
if( !m_hTeamTarget )
return false;
if( m_hTeamTarget->IsTeamAllowed( iTeamNum ) )
return true;
return false;
}

View file

@ -0,0 +1,48 @@
#pragma once
#ifndef FF_SH_TEAMCHECK_TARGET_H
#define FF_SH_TEAMCHECK_TARGET_H
#include "ff_sh_info_ff_teamcheck.h"
#ifdef CLIENT_DLL
#define CFF_SV_EnvFFMessage C_BaseEntity
#else
#include "ff_sv_env_ff_message.h"
#endif
class CFF_SH_TeamcheckTarget : public CFF_SV_EnvFFMessage
{
public:
DECLARE_CLASS( CFF_SH_TeamcheckTarget, CFF_SV_EnvFFMessage );
#ifdef GAME_DLL
DECLARE_DATADESC();
DECLARE_SERVERCLASS();
#else
DECLARE_CLIENTCLASS();
#endif
CFF_SH_TeamcheckTarget()
{
}
#ifdef GAME_DLL
void Activate( void );
#endif
bool TeamCheck_IsUsed( void );
bool TeamCheck_IsTeamAllowed( int iTeamNum );
CNetworkHandle( CFF_SH_InfoFFTeamCheck, m_hTeamTarget );
private:
#ifdef GAME_DLL
string_t m_iszTeamTarget;
#endif
};
#endif // FF_SH_TEAMCHECK_TARGET_H

View file

@ -0,0 +1,40 @@
#include "cbase.h"
#include "ff_sh_trigger_ff_goal.h"
LINK_ENTITY_TO_CLASS( trigger_ff_goal, CFF_SH_TriggerFFGoal );
#ifdef GAME_DLL
BEGIN_DATADESC( CFF_SH_TriggerFFGoal )
// Goal touch functions.
DEFINE_FUNCTION( OnTouching ),
END_DATADESC()
IMPLEMENT_SERVERCLASS_ST( CFF_SH_TriggerFFGoal, DT_FF_TriggerFFGoal )
END_SEND_TABLE()
#else
IMPLEMENT_CLIENTCLASS_DT( CFF_SH_TriggerFFGoal, DT_FF_TriggerFFGoal, CFF_SH_TriggerFFGoal )
END_RECV_TABLE()
#endif
void CFF_SH_TriggerFFGoal::Spawn()
{
BaseClass::Spawn();
SetSolid( SOLID_BSP );
SetSolidFlags( FSOLID_NOT_SOLID | FSOLID_TRIGGER );
#ifdef GAME_DLL
SetTouch( &CFF_SH_TriggerFFGoal::OnTouching );
#endif
}
#ifdef GAME_DLL
void CFF_SH_TriggerFFGoal::OnTouching( CBaseEntity *pOther )
{
BaseClass::OnTouching( pOther );
}
#endif

View file

@ -0,0 +1,45 @@
#pragma once
#ifndef FF_SH_TRIGGER_FF_GOAL_H
#define FF_SH_TRIGGER_FF_GOAL_H
#include "ff_sh_base_ff_goal.h"
#ifdef GAME_DLL
#include "triggers.h"
#else
#define CTriggerMultiple CFF_SH_BaseFFGoal
#endif
class CFF_SH_TriggerFFGoal : public CTriggerMultiple
{
public:
DECLARE_CLASS( CFF_SH_TriggerFFGoal, CTriggerMultiple );
#ifdef GAME_DLL
DECLARE_DATADESC();
DECLARE_SERVERCLASS();
#else
DECLARE_CLIENTCLASS();
#endif
CFF_SH_TriggerFFGoal() {}
virtual void Spawn();
#ifdef GAME_DLL
virtual void OnTouching( CBaseEntity *pOther );
int UpdateTransmitState( void )
{
// The goal must always be transmitted because client side relys on knowing about each goal.
// We don't set this in the base_goal because so many other entities are derived from it.
return SetTransmitState( FL_EDICT_ALWAYS );
}
#endif
};
#endif // FF_SH_TRIGGER_FF_GOAL_H

View file

@ -22,6 +22,21 @@ enum FF_CLASS
FF_CLASS_COUNT FF_CLASS_COUNT
}; };
const int FF_CLASS_BITS[] =
{
0,
(1<<0),
(1<<1),
(1<<2),
(1<<3),
(1<<4),
(1<<5),
(1<<6),
(1<<7),
(1<<8),
(1<<9)
};
enum FF_TEAM enum FF_TEAM
{ {

View file

@ -42,6 +42,21 @@ $Project
$File "$SRCDIR\game\shared\ff\ff_sh_team_manager.h" $File "$SRCDIR\game\shared\ff\ff_sh_team_manager.h"
$File "$SRCDIR\game\shared\ff\ff_sh_team_manager.cpp" $File "$SRCDIR\game\shared\ff\ff_sh_team_manager.cpp"
} }
$Folder "Entities"
{
$File "$SRCDIR\game\shared\ff\entities\ff_sh_base_ff_goal.cpp"
$File "$SRCDIR\game\shared\ff\entities\ff_sh_base_ff_goal.h"
$File "$SRCDIR\game\shared\ff\entities\ff_sh_func_ff_clip.cpp"
$File "$SRCDIR\game\shared\ff\entities\ff_sh_func_ff_clip.h"
$File "$SRCDIR\game\shared\ff\entities\ff_sh_info_ff_teamcheck.cpp"
$File "$SRCDIR\game\shared\ff\entities\ff_sh_info_ff_teamcheck.h"
$File "$SRCDIR\game\shared\ff\entities\ff_sh_item_ff_goal.cpp"
$File "$SRCDIR\game\shared\ff\entities\ff_sh_item_ff_goal.h"
$File "$SRCDIR\game\shared\ff\entities\ff_sh_teamcheck_target.cpp"
$File "$SRCDIR\game\shared\ff\entities\ff_sh_teamcheck_target.h"
$File "$SRCDIR\game\shared\ff\entities\ff_sh_trigger_ff_goal.cpp"
$File "$SRCDIR\game\shared\ff\entities\ff_sh_trigger_ff_goal.h"
}
$Folder "Other" $Folder "Other"
{ {
$File "$SRCDIR\game\shared\ff\other\ff_sh_util.cpp" $File "$SRCDIR\game\shared\ff\other\ff_sh_util.cpp"

View file

@ -19,6 +19,7 @@
#include "particle_parse.h" #include "particle_parse.h"
#include "KeyValues.h" #include "KeyValues.h"
#include "time.h" #include "time.h"
#include "ff_sh_func_ff_clip.h" // FF: --> hlstriker: Added
#ifdef USES_ECON_ITEMS #ifdef USES_ECON_ITEMS
#include "econ_item_constants.h" #include "econ_item_constants.h"
@ -284,6 +285,26 @@ CTraceFilterSimple::CTraceFilterSimple( const IHandleEntity *passedict, int coll
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool CTraceFilterSimple::ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask ) bool CTraceFilterSimple::ShouldHitEntity( IHandleEntity *pHandleEntity, int contentsMask )
{ {
// FF: --> hlstriker: Added
CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity );
if ( !pEntity )
return false;
// Check to see if pEntity is a func_ff_clip. If so, check to see if the pass ent should hit it or not.
if( m_pPassEnt )
{
CFF_SH_FuncFFClip *pClip = dynamic_cast<CFF_SH_FuncFFClip *>(pEntity);
if( pClip )
{
const CBaseEntity *pActivator = EntityFromEntityHandle( m_pPassEnt );
if( pActivator && pClip->ShouldClipActivator( pActivator ) )
return true;
return false;
}
}
// FF: <--
if ( !StandardFilterRules( pHandleEntity, contentsMask ) ) if ( !StandardFilterRules( pHandleEntity, contentsMask ) )
return false; return false;
@ -295,10 +316,12 @@ bool CTraceFilterSimple::ShouldHitEntity( IHandleEntity *pHandleEntity, int cont
} }
} }
// Don't test if the game code tells us we should ignore this collision... // FF: --> hlstriker: Commented to move this check to the very top.
CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity ); //CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity );
if ( !pEntity ) //if ( !pEntity )
return false; // return false;
// FF: <--
if ( !pEntity->ShouldCollide( m_collisionGroup, contentsMask ) ) if ( !pEntity->ShouldCollide( m_collisionGroup, contentsMask ) )
return false; return false;
if ( pEntity && !g_pGameRules->ShouldCollide( m_collisionGroup, pEntity->GetCollisionGroup() ) ) if ( pEntity && !g_pGameRules->ShouldCollide( m_collisionGroup, pEntity->GetCollisionGroup() ) )