diff --git a/mp/src/game/client/c_baseanimating.h b/mp/src/game/client/c_baseanimating.h index 5f30d8f8..ba237d75 100644 --- a/mp/src/game/client/c_baseanimating.h +++ b/mp/src/game/client/c_baseanimating.h @@ -26,6 +26,7 @@ #include "ragdoll_shared.h" #include "tier0/threadtools.h" #include "datacache/idatacache.h" +#include "ff_sh_base_ff_goal.h" // FF: --> hlstriker: Added #define LIPSYNC_POSEPARAM_NAME "mouth" #define NUM_HITBOX_FIRES 10 @@ -88,10 +89,12 @@ typedef unsigned int ClientSideAnimationListHandle_t; #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: - 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_PREDICTABLE(); DECLARE_INTERPOLATION(); diff --git a/mp/src/game/client/c_basedoor.h b/mp/src/game/client/c_basedoor.h index fdf9d09a..213f12f7 100644 --- a/mp/src/game/client/c_basedoor.h +++ b/mp/src/game/client/c_basedoor.h @@ -11,15 +11,18 @@ #endif #include "c_baseentity.h" +#include "ff_sh_base_ff_goal.h" // FF: --> hlstriker: Added #if defined( CLIENT_DLL ) #define CBaseDoor C_BaseDoor #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: - 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(); C_BaseDoor( void ); diff --git a/mp/src/game/client/client_ff.vpc b/mp/src/game/client/client_ff.vpc index 1fe35826..27290d41 100644 --- a/mp/src/game/client/client_ff.vpc +++ b/mp/src/game/client/client_ff.vpc @@ -18,7 +18,7 @@ $Configuration { $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" } } diff --git a/mp/src/game/server/baseanimating.h b/mp/src/game/server/baseanimating.h index 4d89d557..936167c7 100644 --- a/mp/src/game/server/baseanimating.h +++ b/mp/src/game/server/baseanimating.h @@ -15,7 +15,7 @@ #include "studio.h" #include "datacache/idatacache.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; @@ -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_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: - 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(); diff --git a/mp/src/game/server/basetoggle.h b/mp/src/game/server/basetoggle.h index c6c1db98..a80342d9 100644 --- a/mp/src/game/server/basetoggle.h +++ b/mp/src/game/server/basetoggle.h @@ -10,12 +10,14 @@ #pragma once #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: CBaseToggle(); diff --git a/mp/src/game/server/ff/entities/ff_sv_info_ff_weapon_spawner.cpp b/mp/src/game/server/ff/entities/ff_sv_info_ff_weapon_spawner.cpp index 9fed82cc..f344017b 100644 --- a/mp/src/game/server/ff/entities/ff_sv_info_ff_weapon_spawner.cpp +++ b/mp/src/game/server/ff/entities/ff_sv_info_ff_weapon_spawner.cpp @@ -1,5 +1,4 @@ #include "cbase.h" -#include "ff_sv_teamcheck_target.h" #include "ff_sh_shareddefs.h" #include "ammodef.h" @@ -77,7 +76,7 @@ void CFF_SV_InfoFFWeaponSpawner::Precache( void ) int CFF_SV_InfoFFWeaponSpawner::UpdateTransmitState() { // 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() diff --git a/mp/src/game/server/ff/entities/ff_sv_item_ff_goal.cpp b/mp/src/game/server/ff/entities/ff_sv_item_ff_goal.cpp index 50d81e4b..7a78728a 100644 --- a/mp/src/game/server/ff/entities/ff_sv_item_ff_goal.cpp +++ b/mp/src/game/server/ff/entities/ff_sv_item_ff_goal.cpp @@ -1,4 +1,41 @@ #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" @@ -212,3 +249,4 @@ void CFF_SV_ItemFFGoal::ThinkSetInactive() { SetInactive(); } +*/ \ No newline at end of file diff --git a/mp/src/game/server/ff/ff_sv_player.cpp b/mp/src/game/server/ff/ff_sv_player.cpp index b500ff9a..a54fe6c9 100644 --- a/mp/src/game/server/ff/ff_sv_player.cpp +++ b/mp/src/game/server/ff/ff_sv_player.cpp @@ -874,9 +874,12 @@ void CFF_SV_Player::ChangeTeam( int iTeam ) if ( iTeam == FF_TEAM_SPECTATE ) { RemoveAllItems( true ); - State_Transition( STATE_OBSERVER_MODE ); } + else + { + State_Transition( STATE_ACTIVE ); + } if ( bKill == true ) { diff --git a/mp/src/game/server/server_ff.vpc b/mp/src/game/server/server_ff.vpc index 58d3ae89..983b5aca 100644 --- a/mp/src/game/server/server_ff.vpc +++ b/mp/src/game/server/server_ff.vpc @@ -17,7 +17,7 @@ $Configuration { $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" } } @@ -42,18 +42,11 @@ $Project "Server (FF)" } $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.h" $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_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_item_ff_goal.cpp" - $File "ff\entities\ff_sv_teamcheck_target.cpp" - $File "ff\entities\ff_sv_teamcheck_target.h" } $Folder "Other" { diff --git a/mp/src/game/shared/ff/entities/ff_sh_base_ff_goal.cpp b/mp/src/game/shared/ff/entities/ff_sh_base_ff_goal.cpp new file mode 100644 index 00000000..3df93ddf --- /dev/null +++ b/mp/src/game/shared/ff/entities/ff_sh_base_ff_goal.cpp @@ -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( 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(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; iGetCarrier() ) + return HandleCriteriaCheckResult( pEnt, bIsActivator, false); + } + + // Check to see if this player needs to NOT be carrying specific items. + for( int i=0; iGetCarrier() ) + return HandleCriteriaCheckResult( pEnt, bIsActivator, false); + } + + // Check to see if this players team needs to be carrying specific items. + CBasePlayer *pCarrier; + + for( int i=0; iGetCarrier(); + 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; iGetCarrier(); + 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; iGetCarrier() ) + return HandleCriteriaCheckResult( pEnt, bIsActivator, false); + } + + // Check to make sure certain items are NOT being carried by anyone. + for( int i=0; iGetCarrier() ) + 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; iGetCarrier() ) + 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; iGetCarrier() ) + 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; iGetAbsOrigin() != 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; iGetAbsOrigin() == 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; iIsGoalActivated() ) + return HandleCriteriaCheckResult( pEnt, bIsActivator, false); + } + + // Check to make sure certain goals are NOT active. + for( int i=0; iIsGoalActivated() ) + return HandleCriteriaCheckResult( pEnt, bIsActivator, false); + } + + // Check to make sure certain goals are enabled. + for( int i=0; iIsGoalEnabled() ) + return HandleCriteriaCheckResult( pEnt, bIsActivator, false); + } + + // Check to make sure certain goals are NOT enabled. + for( int i=0; iIsGoalEnabled() ) + 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(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 string_vector; + Q_SplitString( STRING(m_iszCriteria_TeamsAllowed), ",", string_vector ); + + int iTemp; + for( int i=0; i 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= 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(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(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(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(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(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(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(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(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(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(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(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(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(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(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 \ No newline at end of file diff --git a/mp/src/game/shared/ff/entities/ff_sh_base_ff_goal.h b/mp/src/game/shared/ff/entities/ff_sh_base_ff_goal.h new file mode 100644 index 00000000..664e5a66 --- /dev/null +++ b/mp/src/game/shared/ff/entities/ff_sh_base_ff_goal.h @@ -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> m_Criteria_ItemsCarriedByActivator; + CUtlVector> m_Criteria_ItemsNotCarriedByActivator; + CUtlVector> m_Criteria_ItemsCarriedByTeam; + CUtlVector> m_Criteria_ItemsNotCarriedByTeam; + CUtlVector> m_Criteria_ItemsCarriedByAny; + CUtlVector> m_Criteria_ItemsNotCarriedByAny; + CUtlVector> m_Criteria_ItemsCarriedByOne; + CUtlVector> m_Criteria_ItemsNotCarriedByOne; + CUtlVector> m_Criteria_ItemsAtSpawnPoint; + CUtlVector> m_Criteria_ItemsNotAtSpawnPoint; + + CUtlVector> m_Criteria_GoalsAreActive; + CUtlVector> m_Criteria_GoalsAreInactive; + CUtlVector> m_Criteria_GoalsAreEnabled; + CUtlVector> 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 diff --git a/mp/src/game/shared/ff/entities/ff_sh_func_ff_clip.cpp b/mp/src/game/shared/ff/entities/ff_sh_func_ff_clip.cpp new file mode 100644 index 00000000..9f136b09 --- /dev/null +++ b/mp/src/game/shared/ff/entities/ff_sh_func_ff_clip.cpp @@ -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 diff --git a/mp/src/game/shared/ff/entities/ff_sh_func_ff_clip.h b/mp/src/game/shared/ff/entities/ff_sh_func_ff_clip.h new file mode 100644 index 00000000..9d9c2a6b --- /dev/null +++ b/mp/src/game/shared/ff/entities/ff_sh_func_ff_clip.h @@ -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 diff --git a/mp/src/game/shared/ff/entities/ff_sh_info_ff_teamcheck.cpp b/mp/src/game/shared/ff/entities/ff_sh_info_ff_teamcheck.cpp new file mode 100644 index 00000000..b9ce1410 --- /dev/null +++ b/mp/src/game/shared/ff/entities/ff_sh_info_ff_teamcheck.cpp @@ -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 diff --git a/mp/src/game/shared/ff/entities/ff_sh_info_ff_teamcheck.h b/mp/src/game/shared/ff/entities/ff_sh_info_ff_teamcheck.h new file mode 100644 index 00000000..f9e1676f --- /dev/null +++ b/mp/src/game/shared/ff/entities/ff_sh_info_ff_teamcheck.h @@ -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 diff --git a/mp/src/game/shared/ff/entities/ff_sh_item_ff_goal.cpp b/mp/src/game/shared/ff/entities/ff_sh_item_ff_goal.cpp new file mode 100644 index 00000000..30f6cd40 --- /dev/null +++ b/mp/src/game/shared/ff/entities/ff_sh_item_ff_goal.cpp @@ -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; +} diff --git a/mp/src/game/shared/ff/entities/ff_sh_item_ff_goal.h b/mp/src/game/shared/ff/entities/ff_sh_item_ff_goal.h new file mode 100644 index 00000000..480454e1 --- /dev/null +++ b/mp/src/game/shared/ff/entities/ff_sh_item_ff_goal.h @@ -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 m_hItemCarrier; // TODO: network this. + Vector m_vecSpawnOrigin; // TODO: network this. +}; + + +#endif // FF_SH_ITEM_FF_GOAL_H diff --git a/mp/src/game/shared/ff/entities/ff_sh_teamcheck_target.cpp b/mp/src/game/shared/ff/entities/ff_sh_teamcheck_target.cpp new file mode 100644 index 00000000..6c067cd6 --- /dev/null +++ b/mp/src/game/shared/ff/entities/ff_sh_teamcheck_target.cpp @@ -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( 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; +} diff --git a/mp/src/game/shared/ff/entities/ff_sh_teamcheck_target.h b/mp/src/game/shared/ff/entities/ff_sh_teamcheck_target.h new file mode 100644 index 00000000..58feb64f --- /dev/null +++ b/mp/src/game/shared/ff/entities/ff_sh_teamcheck_target.h @@ -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 diff --git a/mp/src/game/shared/ff/entities/ff_sh_trigger_ff_goal.cpp b/mp/src/game/shared/ff/entities/ff_sh_trigger_ff_goal.cpp new file mode 100644 index 00000000..4e455d03 --- /dev/null +++ b/mp/src/game/shared/ff/entities/ff_sh_trigger_ff_goal.cpp @@ -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 diff --git a/mp/src/game/shared/ff/entities/ff_sh_trigger_ff_goal.h b/mp/src/game/shared/ff/entities/ff_sh_trigger_ff_goal.h new file mode 100644 index 00000000..876dc919 --- /dev/null +++ b/mp/src/game/shared/ff/entities/ff_sh_trigger_ff_goal.h @@ -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 diff --git a/mp/src/game/shared/ff/ff_sh_shareddefs.h b/mp/src/game/shared/ff/ff_sh_shareddefs.h index 202d7e27..ed348e93 100644 --- a/mp/src/game/shared/ff/ff_sh_shareddefs.h +++ b/mp/src/game/shared/ff/ff_sh_shareddefs.h @@ -22,6 +22,21 @@ enum FF_CLASS 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 { diff --git a/mp/src/game/shared/ff/ff_shared.vpc b/mp/src/game/shared/ff/ff_shared.vpc index 6ef19626..0a53fa2c 100644 --- a/mp/src/game/shared/ff/ff_shared.vpc +++ b/mp/src/game/shared/ff/ff_shared.vpc @@ -42,6 +42,21 @@ $Project $File "$SRCDIR\game\shared\ff\ff_sh_team_manager.h" $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" { $File "$SRCDIR\game\shared\ff\other\ff_sh_util.cpp" diff --git a/mp/src/game/shared/util_shared.cpp b/mp/src/game/shared/util_shared.cpp index 889ed9ab..c29f5cce 100644 --- a/mp/src/game/shared/util_shared.cpp +++ b/mp/src/game/shared/util_shared.cpp @@ -19,6 +19,7 @@ #include "particle_parse.h" #include "KeyValues.h" #include "time.h" +#include "ff_sh_func_ff_clip.h" // FF: --> hlstriker: Added #ifdef USES_ECON_ITEMS #include "econ_item_constants.h" @@ -284,6 +285,26 @@ CTraceFilterSimple::CTraceFilterSimple( const IHandleEntity *passedict, int coll //----------------------------------------------------------------------------- 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(pEntity); + if( pClip ) + { + const CBaseEntity *pActivator = EntityFromEntityHandle( m_pPassEnt ); + if( pActivator && pClip->ShouldClipActivator( pActivator ) ) + return true; + + return false; + } + } + // FF: <-- + if ( !StandardFilterRules( pHandleEntity, contentsMask ) ) 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... - CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity ); - if ( !pEntity ) - return false; + // FF: --> hlstriker: Commented to move this check to the very top. + //CBaseEntity *pEntity = EntityFromEntityHandle( pHandleEntity ); + //if ( !pEntity ) + // return false; + // FF: <-- + if ( !pEntity->ShouldCollide( m_collisionGroup, contentsMask ) ) return false; if ( pEntity && !g_pGameRules->ShouldCollide( m_collisionGroup, pEntity->GetCollisionGroup() ) )